Swift: Cannot assign to immutable expression of type 'AnyObject?!'

PhilHarmonie picture PhilHarmonie · Aug 19, 2015 · Viewed 23.2k times · Source

I searched, but I didn't find a familiar answer, so...

I am about to program a class to handle parse methods like updating, adding, fetching and deleting.

func updateParse(className:String, whereKey:String, equalTo:String, updateData:Dictionary<String, String>) {

    let query = PFQuery(className: className)

    query.whereKey(whereKey, equalTo: equalTo)
    query.findObjectsInBackgroundWithBlock {(objects, error) -> Void in
        if error == nil {
            //this will always have one single object
            for user in objects! {
                //user.count would be always 1
                for (key, value) in updateData {

                    user[key] = value //Cannot assign to immutable expression of type 'AnyObject?!'

                }

                user.saveInBackground()
            } 

        } else {
            print("Fehler beim Update der Klasse \(className) where \(whereKey) = \(equalTo)")
        }
    }

}

As I am about to learn swift at the moment, I would love to get an answer with a little declaration, so that I would learn a little bit more.

btw: I later call this method like this:

parseAdd.updateParse("UserProfile", whereKey: "username", equalTo: "Phil", updateData: ["vorname":self.vornameTextField!.text!,"nachname":self.nachnameTextField!.text!,"telefonnummer":self.telefonnummerTextField!.text!])

Answer

ZpaceZombor picture ZpaceZombor · Jan 4, 2017

In swift a lot of types are defined as structs, which are immutable by default.

I had the same error doing this :

protocol MyProtocol {
    var anInt: Int {get set}
}

class A {

}

class B: A, MyProtocol {
    var anInt: Int = 0
}

and in another class :

class X {

   var myA: A

   ... 
   (self.myA as! MyProtocol).anInt = 1  //compile error here
   //because MyProtocol can be a struct
   //so it is inferred immutable
   //since the protocol declaration is 
   protocol MyProtocol {...
   //and not 
   protocol MyProtocol: class {...
   ...
}

so be sure to have

protocol MyProtocol: class {

when doing such casting