DannieCoderBoi
DannieCoderBoi

Reputation: 728

fatal error: Can't unwrap Optional.None When using Swift with Parse

I've followed this connect your swift application to Parse.com tutorial: http://ios-blog.co.uk/tutorials/connect-your-swift-application-to-parse-com/ and it worked great. This tutorial only shows you how to place data on the Parse.com service. So I did some research into how to retrieve data.

In the First tutorial it says to add data to Parse like so:

    Parse.setApplicationId("your_application_key", clientKey: "your_client_key")

    var object = PFObject(className: "testDataClass")
    object.addObject("iOSBlog", forKey: "websiteUrl")
    object.addObject("Five", forKey: "websiteRating")
    object.save()

In the second tutorial, wrote by the Parse team (http://blog.parse.com/2014/06/06/building-apps-with-parse-and-swift/) It says to write it like this:

var gameScore = PFObject(className: "GameScore")
gameScore.setObject(1337, forKey: "score")
gameScore.setObject("Sean Plott", forKey: "playerName")
gameScore.saveInBackgroundWithBlock { 
    (success: Bool!, error: NSError!) -> Void in
    if success {
        NSLog("Object created with id: \(gameScore.objectId)")
    } else {
        NSLog("%@", error)
    }
}

and then to retrieve it, use this code:

 var query = PFQuery(className: "GameScore")
 query.getObjectInBackgroundWithId(gameScore.objectId) {
 (scoreAgain: PFObject!, error: NSError!) -> Void in
     if !error {
        NSLog("%@", scoreAgain.objectForKey("playerName") as NSString)
     } else {
        NSLog("%@", error)
    }
}

However, When I use the Official Parse code I get the following error:

fatal error: Can't unwrap Optional.None
(lldb) 

and All these things happen in almost every pane of Xcode:

xcodeDebug

Can someone tell me what is wrong and how to fix it? I am relatively new to Xcode and Swift so I would really appreciate a layman terms answer.

EDIT Here is the appDelegate.swift function

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {

    // Connect to Parse using the keys provided

    Parse.setApplicationId("xxx", clientKey: "xxx")

    // Store Data to Parse

    var gameScore = PFObject(className: "GameScore")
    gameScore.setObject(1337, forKey: "score")
    gameScore.setObject("Sean Plott", forKey: "playerName")
    gameScore.saveInBackgroundWithBlock {
        (success: Bool!, error: NSError!) -> Void in
        if success {
            NSLog("Object created with id: \(gameScore.objectId)")
        } else {
            NSLog("%@", error)
        }
    }

    var query = PFQuery(className: "GameScore")
    query.getObjectInBackgroundWithId(gameScore.objectId) {
        (scoreAgain: PFObject!, error: NSError!) -> Void in
        if !error {
            NSLog("%@", scoreAgain.objectForKey("playerName") as NSString)
        } else {
            NSLog("%@", error)
        }
    }



    // Override point for customization after application launch.
    return true
}

Much appreciated.

Added new code for user to see:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {

    // Connect to Parse using the keys provided

    Parse.setApplicationId("xxxx", clientKey: "xxxx")

    // Store Data to Parse

    var gameScore = PFObject(className: "GameScore")
    gameScore.setObject(1337, forKey: "score")
    gameScore.setObject("Sean Plott", forKey: "playerName")
    gameScore.saveInBackgroundWithBlock {
        (success: Bool!, error: NSError!) -> Void in
        if (success ?? false) {
            NSLog("Object created with id: \(gameScore.objectId)")
        } else {
            NSLog("%@", error)
        }
    }

    var query = PFQuery(className: "GameScore")
    query.getObjectInBackgroundWithId(gameScore.objectId) {
        (scoreAgain: PFObject!, error: NSError!) -> Void in
        if error == nil {
            NSLog("%@", scoreAgain.objectForKey("playerName") as NSString)
        } else {
            NSLog("%@", error)
        }
    }



    // Override point for customization after application launch.
    return true
}

Upvotes: 1

Views: 425

Answers (1)

vacawama
vacawama

Reputation: 154711

This Parse example was written in June when Swift was in Beta. Swift has continued to evolve, so some of the things they are doing are no longer legal in Swift.

Firstly, you can no longer check if an optional variable error is nil with if !error. Instead you must explicitly check against nil like this: if error == nil.

Secondly, success is declared as an implicitly unwrapped optional. It is no longer valid to check if it is true with if success. You could do if success == true but this will crash if success is nil. Instead, you could do if (success ?? false). This uses the nil coalescing operator to safely unwrap the optional Bool if it has a value or it uses false if the Bool is nil. Either way, the if will only succeed if the Bool is true.

Upvotes: 1

Related Questions