Search code examples
xcodeswiftparse-platformpfquerypfobject

PFQuery.getObjectWithId(objectId: String) --- 'AnyObject?' is not convertible to 'String' error --- Parse sdk 1.7.1 and Xcode 6.3


I just updated Xcode to 6.3 and my parse sdk to 1.7.1. I knew from the apple docs that I was going to spend some time fixing some of my swift code on my iOS app. Xcode is happy with all my fixes except for one func that gets a parse class by id. I've dredged parse, apple, stackoverflow, and google for a fix, but I've been banging my head against this last fix for hours and desperately need some help from one of you super smart guys. I apologize in advance if this turns out to be a stupid question. I've been programming for a really long time, but I'm a noob to iOS.

Below is a simple example of what I'm trying to do, which worked before I updated Xcode and parse sdk. Now Xcode gives me errors for each of the lines where I am trying to get the variables out from the PFObject. Errors for each line is like this: "'AnyObject?' is not convertible to 'String'" and "Cannot assign to immutable value of type 'String". Any insight would be greatly appreciated.

func getFakeObject(objectId: String) -> FakeObject {

    var fakeObject: FakeObject = FakeObject()
    var query = PFQuery(className:"FakeObject")
    var loadedFakeObject = query.getObjectWithId(objectId)
    if loadedFakeObject != nil {

            fakeObject.objectId = objectId
            fakeObject.isActive = loadedFakeObject["isActive"] as! Bool
            fakeObject.desc = loadedFakeObject["desc"] as! String
            fakeObject.purchasePrice = loadedFakeObject["purchasePrice"] as! Double
            fakeObject.purchaseDate = loadedFakeObject["purchaseDate"] as! NSDate
            fakeObject.labels = loadedFakeObject["labels"] as [String]

    }
    return fakeObject
}

Solution

  • Swift 1.2 is a lot stricter about syntax and tries to prevent you from unknowingly doing dangerous things.

    Where you write:

    var loadedFakeObject = query.getObjectWithId(objectId)
    if loadedFakeObject != nil {
    

    Try instead:

    if let loadedFakeObject = query.getObjectWithId(objectId) {
    

    In the first case, you are getting an optional (there might be no such object), and then checking it its nil, but then still using the optional. Because it’s optional, you need to write loadedFakeObject!["isActive"] as! Bool. But there’s really no need because instead you can use if let to both check and unwrap the optional, meaning within the if statement, it won’t be optional any more.

    You might also want to consider switching to as? instead of as! in various places, but this is probably less the cause of your problem, more of a runtime safety thing.