technerd
technerd

Reputation: 14504

'-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object' cause crash

I am assigning UserInfo Dictionary from NSUserDefault as NSMutableDictionary. Now my dicInfo is mutable dictionary, but object it contains are immutable. So, when i am trying to replace those value it cause crash. I am attaching image which describe crash report. If any solution, to how to convert inner object of mutable dictionary to mutable.

Thanks enter image description here

Upvotes: 2

Views: 1929

Answers (4)

vadian
vadian

Reputation: 285039

Neither use NSMutableDictionary nor mutableCopy() in Swift to get a mutable dictionary from UserDefaults.

Never do that.

Normally far be it from me to criticize other answers but NSMutableDictionary and mutableCopy() are indeed inappropriate API in Swift.


  • To get a dictionary from UserDefaults use dedicated method dictionary(forKey:. The default dictionary type is [String:Any]
  • To make an object mutable simply use the var keyword

    var userbasicInfo : [String:Any]
    if let dictionary = UserDefaults.standard.dictionary(forKey: UserDefaultKey.kUserBasicInfo) {
        userbasicInfo = dictionary
    } else {
        userbasicInfo = [String:Any]()
    }
    userbasicInfo[kPin] = 5678
    print(userbasicInfo)
    UserDefaults.standard.set(userbasicInfo, forKey:UserDefaultKey.kUserBasicInfo)
    

Upvotes: 0

vinodonkar
vinodonkar

Reputation: 59

You can also create Mutable Dictionary as follows: It will fix the crash.

let dicInfo = NSMutableDictionary.init(dictionary: userSharedDefaults?.objectForKey(UserDefaultKey.kUserBasicInfo) as! NSDictionary)

Upvotes: 0

Nilesh K
Nilesh K

Reputation: 11

var dicInfo = (userSharedDefault.object(forKey: "kUserbasicInfo") as! NSDictionary).mutableCopy() as! NSMutableDictionary

Upvotes: 1

nhgrif
nhgrif

Reputation: 62052

The NSDictionary class conforms to the NSMutableCopying protocol. As such, we can call the mutableCopy method on an NSDictionary to get an NSMutableDictionary copy of the object.

let dicInfo = userSharedDefaults?.objectForKey(UserDefaultKey.kUserBasicInfo) as? NSDictionary

let mutableDictionary = dicInfo?.mutableCopy

In Swift, we may need to cast this as the correct type:

let mutableDictionary = dicInfo?.mutableCopy as? NSMutableDictionary

Upvotes: 9

Related Questions