2016-03-28 6 views
1

Dies ist mein Code in swift 2.2, und ich habe inApp stürzt ab, weil der launchOptions am Start sein null

didfinishLaunchingWithOptions 

als

if let locationValue : AnyObject? = launchOptions![UIApplicationLaunchOptionsLocationKey] as? [NSObject : AnyObject] { 
    if (locationValue != nil) { 
     let app : UIApplication = UIApplication.sharedApplication() 
     var bgTask : UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid 
     bgTask = app.beginBackgroundTaskWithExpirationHandler({() -> Void in 
      app.endBackgroundTask(bgTask) 
     }) 
     self.startLocationUpdates() 
     }} 

Fehler (EXC_BAD_INSTRUCTION) geschrieben tritt auf dieser Linie

if let locationValue : AnyObject? = launchOptions![UIApplicationLaunchOptionsLocationKey] as? [NSObject : AnyObject] { 

Kann mir jemand helfen, wie man mit dem Nil-Fall hier umgeht? Ich habe versucht, wenn ..let Aussage auch .. danke im Voraus.

Antwort

5

Überall, wo Sie ein Ausrufezeichen für Optionals verwenden, ist ein Ort, an dem Ihre App möglicherweise abstürzen kann. In den meisten Fällen können Sie das Problem beheben, indem Sie das Ausrufezeichen durch Fragezeichen ersetzen.

Die Signatur von didFinishLaunchingWithOptions ist dies:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 

Das entsprechende Argument hier ist launchOptions, dessen Typ [NSObject: AnyObject]?, ein optionales Wörterbuch. Bevor wir Methoden aufrufen können (einschließlich des Zugriffs auf Elemente über den Subscript-Operator), müssen wir sie auspacken.

In Ihrem Fall die einfachste Lösung ist:

if let locationValue = launchOptions?[UIApplicationLaunchOptionsLocationKey] { 
    // use the location value 
} 

Per the official Apple documentation:

  • UIApplicationLaunchOptionsLocationKey

Das Vorhandensein dieses Schlüssels gibt an, dass der App gestartet wurde in Antwort auf ein eingehendes Standort-Ereignis. Der Wert dieses Schlüssels ist ein NSNumber-Objekt, das einen booleschen Wert enthält. Sie sollten die Anwesenheit dieses Schlüssels als ein Signal verwenden, um ein CLLocationManager-Objekt zu erstellen und Standortdienste erneut zu starten. Standortdaten werden nur an den Standortverwaltungsdelegaten übermittelt, und dieser Schlüssel wird nicht verwendet.

In dem obigen Codeausschnitt wird locationValue vom Typ seiner AnyObject (nicht optional) aufgrund der Art des Wörterbuchs. Aber nach der Dokumentation wissen wir, dass es sich um eine NSNumber handelt, die eine Bool darstellt (die in Swift kann frei mit dem nützlichen Typ überbrückt werden).

Und wahrscheinlich kümmern wir uns nur um den Fall, wenn der Wert wahr ist, oder?

Als solche können wir die Code-Schnipsel an folgenden umschreiben:

if let locationValue = launchOptions?[UIApplicationLaunchOptionsLocationKey] as? Bool where locationValue { 
    // the app was launched in response to a location event 
    // do your location stuff 
} 

Obwohl streng genommen pro der Dokumentation:

Das Vorhandensein dieses Schlüssels gibt an, dass der App gestartet wurde als Reaktion auf ein eintreffendes Standortereignis.

Zwischen dieser Formulierung und der Tatsache, dass der tatsächliche Wert nur ein true/false Wert ist, hatte ich wette fast, dass die Tatsache, dass der Schlüssel allein existiert genügend Informationen true der Wert zu übernehmen. Wenn die App nicht für Standortereignisse gestartet wird, ist der Schlüssel wahrscheinlich nicht vorhanden. Und wenn es ist, ist der Wert wahrscheinlich immer true.

Und wenn Sie auf dieser Annahme setzen möchten, können Sie einfach die _ für den Variablennamen verwenden, da wir es nicht verwenden:

if let _ = launchOptions?[UIApplicationLaunchOptionsLocationKey] { 
    // etc... 
} 
+0

Gute Erklärung. Sie können auch 'if launchOptions' [UIApplicationLaunchOptionsLocationKey]! = Nil' – TruMan1