ios – Notifications Essential Thread Crash


I am attempting to arrange native notifications and preserve getting the next error in my console when i faucet the notification:

Assertion failure in -[_TtC7SwiftUIP33_ACC2C5639A7D76F611E170E831FCA49118SwiftUIApplication _performBlockAfterCATransactionCommitSynchronizes:], UIApplication.m:3421 Terminating app as a result of uncaught exception ‘NSInternalInconsistencyException’, purpose: ‘Name should be made on predominant thread’ *** First throw name stack: (0x18c89a8c8 0x1898117c4 0x18a798e80 0x19343e5b8 0x193454778 0x193454b24 0x104467aac 0x104469f55 0x10446ac21 0x10446b4c9 0x10446acfd 0x10446b62d 0x10446b369 0x10446b771 0x18ad432a9) libc++abi: terminating as a result of uncaught exception of kind NSException

closing class NotificationManager: NSObject, UNUserNotificationCenterDelegate {
    @MainActor static let shared = NotificationManager()

    @MainActor func configure() {
        UNUserNotificationCenter.present().delegate = self
    }

    func userNotificationCenter(_ heart: UNUserNotificationCenter,
        willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
        [.banner, .list, .sound]
    }

    func userNotificationCenter(_ heart: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse) async {
        guard
            let hyperlink = response.notification.request.content material.userInfo["deeplink"] as? String,
            let url = URL(string: hyperlink)
        else { return }

        // Publish notification as an alternative of straight opening URL
        // This ensures all dealing with occurs in the correct context
        DispatchQueue.predominant.async {
            NotificationCenter.default.put up(
                identify: .handleDeepLink,
                object: url
            )
        }
    }
}

enum Notifications {
    @MainActor
    static func schedule(id: String = UUID().uuidString,
                         title: String,
                         physique: String,
                         hour: Int,
                         minute: Int,
                         days: Set) async throws
    {
        guard !days.isEmpty else { return }

        let heart = UNUserNotificationCenter.present()

        for day in days {
            let content material = UNMutableNotificationContent()
            content material.title = title
            content material.physique  = physique
            content material.sound = .default
            content material.userInfo = ["deeplink" : "sparky://codeoftheday/(Code.allCodes.randomElement()?.ruleNumber ?? "2-028")"]

            var date = DateComponents()
            date.hour = hour
            date.minute = minute
            date.weekday = day.rawValue

            let set off = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)

            // make a secure id per weekday so you possibly can reschedule/replace
            let perDayID = "(id).(day.rawValue)"
            let request = UNNotificationRequest(identifier: perDayID, content material: content material, set off: set off)
            strive await heart.add(request)
        }
    }
}

extension Notification.Identify {
    static let handleDeepLink = Notification.Identify("handleDeepLink")
    static let appDidReceiveURL = Notification.Identify("appDidReceiveURL")
    static let showCodeOfTheDay = Notification.Identify("showCodeOfTheDay")
    static let widgetToolSelected = Notification.Identify("widgetToolSelected")
}


@predominant
struct MyApp: App {
    var physique: some Scene {
        WindowGroup {
                NavigationStack {
                    ContentView()
                }
                .job {
                    NotificationManager.shared.configure()

                    do {
                        let granted = strive await UNUserNotificationCenter.present().requestAuthorization(choices: [.alert, .badge, .sound])
                        if granted {
                            print("Notifications Granted")
                        }
                    } catch {
                        print(error.localizedDescription)
                    }
                }
                .onOpenURL { url in
                    handleDeepLink(url)
                }
                .onReceive(NotificationCenter.default.writer(for: .handleDeepLink)) { notification in
                    guard let url = notification.object as? URL else { return }
                    handleDeepLink(url)
                }
            }
        }
    }

    @MainActor
    personal func handleDeepLink(_ url: URL) {
        print("Dealing with deep hyperlink: (url)")

        guard url.scheme == "sparky" else {
            print("Invalid URL scheme: (url.scheme ?? "nil")")
            return
        }

        guard let host = url.host else {
            print("No host in URL")
            return
        }

        // Convert the hyphenated URL format again to a device identify
        let toolName: String
        if host == "nema-configurations" {
            toolName = "configurations"
        } else {
            toolName = host
                .replacingOccurrences(of: "-", with: " ")
                .localizedCapitalized
        }

        if toolName.lowercased() == "calculator" {
            if !self.navManager.showingCalculator {
                self.navManager.showingCalculator = true
            }
        } else if toolName.lowercased() == "notes" {
            if !self.navManager.showingNotes {
                UserDefaults.commonplace.set(0, forKey: "jobsNotesTab")
                self.navManager.showingNotes = true
            }
        } else if toolName.lowercased() == "jobs" {
            if !self.navManager.showingNotes {
                UserDefaults.commonplace.set(1, forKey: "jobsNotesTab")
                self.navManager.showingNotes = true
            }
        } else if toolName.lowercased() == "set up assistant" {
            if !self.navManager.showInstallAssistant {
                self.navManager.showInstallAssistant = true
            }
        } else if toolName.lowercased() == "codeoftheday", let ruleNumber = url.pathComponents.final {
            let code = Code.allCodes.first { $0.ruleNumber == ruleNumber }

            self.navManager.popToRoot()
            self.navManager.codeOfTheDay = code

        } else if let device = self.toolStore.findTool(byName: toolName) {
            self.navManager.popToRoot()
            self.navManager.navigate(to: device.route)
            self.selectedToolRoute = device.route
        } else {
            print("Couldn't discover device for identify: (toolName)")
        }
    }
}

I’ve tried a number of issues corresponding to utilizing an AppDelegate as an alternative however nothing appears to be working.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles