Xcode 9 (iOS 11) zeigt mir einen Fehler / eine Warnung bei der Registrierung für die Push-Benachrichtigung (Remote) an.
Hier ist eine Fehlermeldung
Und hier ist Code, ich habe versucht:
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
if error == nil{
UIApplication.shared.registerForRemoteNotifications()
}
}
Fehler- / Warnzeile:
UIApplication.shared.registerForRemoteNotifications ()
Wie kann ich das beheben?
UIApplication.shared.registerForRemoteNotifications()
in den Hauptthread einschließen. :) Lassen Sie Google, wie man es im Haupt-Thread nennt ...UIApplication.shared.registerForRemoteNotifications()
hat nichts mit der Benutzeroberfläche zu tun (Sie werden nicht aufgefordert, Benutzer zu benachrichtigen, wenn Sie ein Token für stille Benachrichtigungen erhalten). Die Zeile, die der Fehler anzeigt, ist also verwirrend. Die Registrierung für die Abzeichen, Warnungen und Sounds hängt jedoch mit der Benutzeroberfläche zusammen und es ist viel besser, dies vom Hauptthread aus zu tun. Insgesamtcenter.requestAuthorization(options:...
muss also der gesamte Block von vom Hauptthread aus ausgeführt werden. Es macht SinnAntworten:
In swift4
Sie können dieses Problem mit lösen
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
Hoffe das wird helfen ...
quelle
DispatchQueue.main.async(execute: UIApplication.shared.registerForRemoteNotifications())
Cannot invoke 'async' with an argument list of type '(execute: Void)'
anhand Ihres Beispiels einen Fehler erhalten.DispatchQueue.main.async(execute: UIApplication.shared.registerForRemoteNotifications)
.execute
erwartet eine Funktion / Schließung des Typs() -> Void
soregisterForRemoteNotifications
funktioniertdispatch_async(dispatch_get_main_queue(), ^{ //Do stuff });
Für Ziel C funktioniert der folgende Code
dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] registerForRemoteNotifications]; });
quelle
TL; DR:
Alle UI-Manipulationen sollten im Haupt-Thread durchgeführt werden, um Probleme zu vermeiden. Andernfalls führt der Main Thread Checker (neu eingeführte Debugging-Funktion in XCode 9) zur Laufzeit zu Problemen. Wickeln Sie Ihren Code also wie unten beschrieben in den Haupt-Thread-Block ein, um Störungen und Laufzeitwarnungen zu vermeiden.
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
In Xcode-Releases vor ver. In 9 werden die Warnungen in Bezug auf den Haupt-Thread im Konsolenbereich in Textform gedruckt. Auf jeden Fall können Sie den Haupt-Thread-Checker in den Diagnoseeinstellungen im Bearbeitungsschema optional deaktivieren ( kein empfohlener Ansatz ) .
Erläuterung:
Apple hat in XCode 9 eine neue Debugging-Option eingeführt, mit der Probleme bei Runtime for UIKit und anderen APIs, die Benutzeroberflächenelemente bearbeiten, überprüft werden können. Wenn zur Laufzeit Änderungen an den UI-Elementen von der UIKit-API ohne einen Hauptthreadblock vorgenommen werden, ist es sehr wahrscheinlich, dass UI-Störungen und Abstürze auftreten. Der Haupt-Thread-Checker ist standardmäßig aktiviert, um diese Probleme zur Laufzeit zu erkennen. Sie können die Haupt-Thread-Prüfung im Fenster " Schema bearbeiten" wie unten beschrieben deaktivieren , obwohl dies nicht unbedingt empfohlen wird:
Wenn Sie ältere SDKs oder Frameworks haben, wird beim Aktualisieren auf Xcode 9 möglicherweise diese Warnung angezeigt, da einige der UIKit-Methodenaufrufe nicht in den Hauptthread eingeschlossen worden wären. Das Aktualisieren auf die neueste Version würde das Problem beheben (wenn der Entwickler davon Kenntnis hat und es behoben hat).
Zitat aus den Beta-Versionshinweisen zu XCode 9:
quelle
Die Fehlermeldung ist ziemlich klar: Versand
registerForRemoteNotifications
an den Haupt-Thread.Ich würde den
granted
Parameter verwenden und daserror
entsprechend behandelncenter.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in if granted { DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } else { print(error!) // handle the error } }
quelle
Dies ist auch in Swift 4.0 der richtige Weg
UNUserNotificationCenter.current().delegate = self UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge], completionHandler: {(granted,error) in if granted{ DispatchQueue.main.async { application.registerForRemoteNotifications() } } })
quelle
Hoffe das wird helfen
DispatchQueue.main.async(execute: { UIApplication.shared.registerForRemoteNotifications() })
quelle
Das hat bei mir funktioniert. Mit freundlicher Genehmigung von @ Mason11987 im oben akzeptierten Kommentar.
DispatchQueue.main.async() { code }
quelle