stevengbu
stevengbu

Reputation: 243

Ambiguous use of 'mutableCopy()' Swift3

I tried to update Swift 3 and I got the following error :

Ambiguous use of 'mutableCopy()'

Before update to swift 3. It runs well.

Swift 2.3

NSUserDefaults.standardUserDefaults().objectForKey("listsavednews")?.mutableCopy() as! NSMutableArray

Swift 3.0

(UserDefaults.standard.object(forKey: "listsavednews")? as AnyObject).mutableCopy() as! NSMutableArray

I found that mutableCopy in Swift3 return Any that doesnt have method mutableCopy() so that it needs to cast to AnyObject.

Any helps thanks.

I dont know why I can't comment.

Thanks all, I'll be using :

UserDefaults.standard.mutableArrayValue(forKey: "listsavednews")

Upvotes: 2

Views: 1455

Answers (1)

rmaddy
rmaddy

Reputation: 318774

mutableCopy is an Objective-C method from NSObject. There's little reason to use it in Swift 3.

Since you are dealing with UserDefaults and mutableCopy, you must be dealing with either an array or dictionary. Or it could be a string.

The proper way to do this in Swift 3 is to use the proper UserDefaults method to get an array or dictionary. And assign the result to a var. That combination will give you a mutable array or mutable dictionary.

var someArray = UserDefaults.standard.array(forKey: "somekey")

or:

var someDictionary = UserDefaults.standard.dictionary(forKey: "somekey")

In the two above cases, you end up with an optional since there might not be any data for the given key. And you also get a non-specific array or dictionary which isn't ideal. It would be better to cast the result to the appropriate type.

Let's say you have an array of strings and you want an empty array if there is nothing currently in user defaults. You can then do:

var someArray = UserDefaults.standard.array(forKey: "somekey" as? [String]) ?? []

Adjust as necessary if the array contains something other than String.

If you actually have a dictionary, the code would be similar.

var someDictionary = UserDefaults.standard.dictionary(forKey: "somekey") as? [String:String] ?? [:]

If your original object is just a string, then you could do:

var someString = UserDefaults.standard.string(forKey: "somekey") ?? ""

Upvotes: 3

Related Questions