Add bad_query support for iOS 26–27.0b4
Integrate forcequitOS/bad_query for sandbox-escaped PosterBoard writes, on-device container UUID detection (no PC/Nugget required), descriptor wipe for Reset Collections, and Mond-style WebKit respring that works under LiveContainer. Rebrand fork to com.mak5er.Pocket-Poster; credit Mak5er.
This commit is contained in:
1 parent
fb07aa4558
commit
18a67ec171
21 files changed
+1223
-102
No files matched your search
@@ -18,42 +18,70 @@ fileprivate let cancelString = NSLocalizedString("Cancel", comment: "")
|
||||
|
||||
extension UIApplication {
|
||||
|
||||
func dismissAlert(animated: Bool) {
|
||||
func dismissAlert(animated: Bool, completion: (() -> Void)? = nil) {
|
||||
DispatchQueue.main.async {
|
||||
lastDismissTitle = currentUIAlertController?.title
|
||||
currentUIAlertController?.dismiss(animated: animated)
|
||||
if let alert = currentUIAlertController {
|
||||
// Always clear pointer first so a follow-up present() won't chain on a dying VC
|
||||
currentUIAlertController = nil
|
||||
alert.dismiss(animated: animated) {
|
||||
completion?()
|
||||
}
|
||||
} else {
|
||||
// Also dismiss any orphaned presented alert
|
||||
if let top = Self.topViewController(), top is UIAlertController {
|
||||
top.dismiss(animated: animated) {
|
||||
completion?()
|
||||
}
|
||||
} else {
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func alert(title: String = errorString, body: String, animated: Bool = true, withButton: Bool = true) {
|
||||
DispatchQueue.main.async {
|
||||
var body = body
|
||||
|
||||
if title == errorString {
|
||||
// append debug info
|
||||
let device = UIDevice.current
|
||||
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
|
||||
let appBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? ""
|
||||
let systemVersion = device.systemVersion
|
||||
body += "\n\(device.systemName) \(systemVersion), v\(appVersion) build \(appBuild)"
|
||||
// Dismiss any existing alert first so we never stack a buttonless spinner under a new sheet
|
||||
dismissAlert(animated: false) {
|
||||
DispatchQueue.main.async {
|
||||
var body = body
|
||||
|
||||
if title == errorString {
|
||||
// append debug info
|
||||
let device = UIDevice.current
|
||||
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
|
||||
let appBuild = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? ""
|
||||
let systemVersion = device.systemVersion
|
||||
body += "\n\(device.systemName) \(systemVersion), v\(appVersion) build \(appBuild)"
|
||||
}
|
||||
|
||||
let controller = UIAlertController(title: title, message: body, preferredStyle: .alert)
|
||||
// Always allow dismiss for non-progress alerts; progress uses withButton: false intentionally
|
||||
if withButton {
|
||||
controller.addAction(.init(title: okString, style: .cancel))
|
||||
}
|
||||
currentUIAlertController = controller
|
||||
self.present(alert: controller)
|
||||
}
|
||||
|
||||
currentUIAlertController = UIAlertController(title: title, message: body, preferredStyle: .alert)
|
||||
if withButton { currentUIAlertController?.addAction(.init(title: okString, style: .cancel)) }
|
||||
self.present(alert: currentUIAlertController!)
|
||||
}
|
||||
}
|
||||
|
||||
func confirmAlert(title: String = errorString, body: String, confirmTitle: String = okString, onOK: @escaping () -> (), noCancel: Bool) {
|
||||
DispatchQueue.main.async {
|
||||
currentUIAlertController = UIAlertController(title: title, message: body, preferredStyle: .alert)
|
||||
if !noCancel {
|
||||
currentUIAlertController?.addAction(.init(title: cancelString, style: .cancel))
|
||||
dismissAlert(animated: false) {
|
||||
DispatchQueue.main.async {
|
||||
let controller = UIAlertController(title: title, message: body, preferredStyle: .alert)
|
||||
if !noCancel {
|
||||
controller.addAction(.init(title: cancelString, style: .cancel))
|
||||
}
|
||||
controller.addAction(.init(title: confirmTitle, style: noCancel ? .cancel : .default, handler: { _ in
|
||||
onOK()
|
||||
}))
|
||||
currentUIAlertController = controller
|
||||
self.present(alert: controller)
|
||||
}
|
||||
currentUIAlertController?.addAction(.init(title: confirmTitle, style: noCancel ? .cancel : .default, handler: { _ in
|
||||
onOK()
|
||||
}))
|
||||
self.present(alert: currentUIAlertController!)
|
||||
}
|
||||
}
|
||||
|
||||
func change(title: String = errorString, body: String) {
|
||||
DispatchQueue.main.async {
|
||||
currentUIAlertController?.title = title
|
||||
@@ -61,14 +89,30 @@ extension UIApplication {
|
||||
}
|
||||
}
|
||||
|
||||
func present(alert: UIAlertController) {
|
||||
if let window = UIApplication.shared.connectedScenes.map({ $0 as? UIWindowScene }).compactMap({ $0 }).first?.windows.first, var topController = window.rootViewController {
|
||||
while let presentedViewController = topController.presentedViewController, presentedViewController.title != lastDismissTitle {
|
||||
topController = presentedViewController
|
||||
}
|
||||
|
||||
topController.present(alert, animated: true)
|
||||
// topController should now be your topmost view controller
|
||||
/// Top-most VC in the key window (skips being-dismissed alerts when possible).
|
||||
static func topViewController() -> UIViewController? {
|
||||
let scenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
|
||||
let window = scenes
|
||||
.flatMap { $0.windows }
|
||||
.first { $0.isKeyWindow } ?? scenes.first?.windows.first
|
||||
guard var top = window?.rootViewController else { return nil }
|
||||
while let presented = top.presentedViewController {
|
||||
// Prefer not to stop on a controller that is mid-dismiss
|
||||
if presented.isBeingDismissed { break }
|
||||
top = presented
|
||||
}
|
||||
return top
|
||||
}
|
||||
|
||||
func present(alert: UIAlertController) {
|
||||
guard let topController = Self.topViewController() else { return }
|
||||
// If top is already an alert being shown, replace it
|
||||
if let existing = topController as? UIAlertController {
|
||||
existing.dismiss(animated: false) {
|
||||
Self.topViewController()?.present(alert, animated: true)
|
||||
}
|
||||
return
|
||||
}
|
||||
topController.present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user