Search code examples
jsonswiftnsmutablearrayimmutablearray

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


I did some search but still cannot figure out how to solve the error. Basically I am reading booklist from Json file and then update it. The reading part is fine but error ("Cannot assign to immutable expression of type ' AnyObject?!'") happens when trying to update.

var url = NSBundle.mainBundle().URLForResource("Book", withExtension: "json")

var data = NSData(contentsOfURL: url!)

var booklist = try! NSJSONSerialization.JSONObjectWithData(data!, options: []) as! NSMutableArray


for boo in booklist {
            if (boo["name"]  as! String) == "BookB" {
                print (boo["isRead"]) //see Console Output
                boo["isRead"] = "true"  //this gets error "Cannot assign to immutable expression of type ' AnyObject?!'"
            }

The Json file Book.json is as below:

[
{"name":"BookA","auth":"AAA","isRead":"false",},
{"name":"BookB","auth":"BBB","isRead":"false",},
{"name":"BookC","auth":"CCC","isRead":"false",},
]

The booklist has expected values, see Console output:

(
        {
        name = BookA;
        auth = AAA;
        isRead = false;
    },
        {
        name = BookB;
        auth = BBB;
        isRead = false; 
    },
       {
        name = BookC;
        auth = CCC;
        isRead = false;
    }
)

and for print (boo["isRead"]), the console result is Optional(false), which is correct.

Booklist is already a NSMutableArray, and I also tried to change as

var booklist = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSMutableArray

but it does not help.

Also referred to Swift: Cannot assign to immutable expression of type 'AnyObject?!', changing to below also get the same error:

var mutableObjects = booklist
for var boo in mutableObjects {
            if (boo["name"]  as! String) == "BookB" {
                print (boo["isRead"]) //see Console Output
                boo["isRead"] = "true"  //this gets error "Cannot assign to immutable expression of type ' AnyObject?!'"
            }

Could anyone advise how to update the isRead in booklist for BookB in this case. Or even better how to update the Book.json file.


Solution

  • In your case you hit this error twice:

    1. in the for loop, which you correctly edited
    2. because the compiler doesn't know the type of boo (it's just an element of an NSMutableArray)

    To fix this you could write:

    for var boo in mutableObjects {
        if var theBoo = boo as? NSMutableDictionary {
            if (theBoo["name"]  as! String) == "BookB" {
                print (theBoo["isRead"]) //see Console Output
                theBoo["isRead"] = "true"  //this gets error "Cannot assign to immutable expression of type ' AnyObject?!'"
            }
        }
    }
    

    Or, you give the compiler a hint about the type of boo with:

        guard let theBoos = mutableObjects as? [Dictionary<String, AnyObject>] else {
            return
        }
    
        for var theBoo in theBoos {
            if (theBoo["name"]  as! String) == "BookB" {
                print (theBoo["isRead"]) //see Console Output
                theBoo["isRead"] = "true"  //this gets error "Cannot assign to immutable expression of type ' AnyObject?!'"
            }
        }