I’ve a bizarre bug in my iOS-app. Initially: the bug solely seems utilizing Testflight, not when compiling the app by xCode and operating it on a tool.
I’ve a easy onboarding TabView
with three tabs. The primary one has a button the place the person can enable notifications:
@EnvironmentObject var delegate: AppDelegate
//some Code
Button("enable notifications") {
delegate.registerForPushNotifications()
}
If I take advantage of this button, the bug doesn’t seem. Not in xCode nor in Testflight. But when the person does not use the button, I ask for permission for notifications when the primary tab disapears:
.onDisappear {
if web page.id == 0 { //web page.id is the present tab
delegate.registerForPushNotifications()
}
}
And now it get’s bizarre: after I do not enable notifications utilizing this onDisappear
-function, the entire app freezes and turns into unresponsive. I can not swipe anymore to vary the tabs. After I carry the app within the background it takes some time and it crashes on account of a watchdog termination with the error code 0x8badf00d
– ate dangerous meals. This implies the app took to lengthy to terminate (sure, as a result of it received unresponsive).
To summarize:
- xCode utilizing button: enable/deny notifications → OK
- xCode utilizing onDisappear: enable/deny → OK
- Testflight utilizing button: enable/deny → OK
- Testflight utilizing onDisappear: enable → OK | deny → unresponsive
My guess is that contained in the registerForPushNotifications()
perform the mainthread will get blocked. So right here comes the code for that:
//some code with struct xxx: App {
@UIApplicationDelegateAdaptor personal var delegate: AppDelegate
//some code with OnboardingView().environmentObject(delegate) }
class AppDelegate: NSObject, ObservableObject, UIApplicationDelegate {
//some code
func registerForPushNotifications() {
UNUserNotificationCenter.present().delegate = self
UNUserNotificationCenter.present().requestAuthorization(choices: [.alert, .sound, .badge]) {
(granted, error) in
if let error = error {
print("D'oh: (error.localizedDescription)")
} else {
guard granted else {
//permission denied
return
}
//permission granted
DispatchQueue.essential.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
}
}
However the DispatchQueue.essential.async
is not referred to as when the person denies notifications, proper? Has it one thing to do with manufacturing and sandbox environments? However why does it work when the button is pressed?
I am grateful for each reply, as this drawback shouldn’t be simple to debug as a result of I’ve to add a brand new construct to Testflight everytime. If it is wanted I can ship an invite-link for the beta inside Testflight. The bug occurs proper after the primary onboarding display screen.