问题
Just trying to be extra careful here...
If I have an app that saved a value in UserDefaults like this in Objective-C:
NSString *newString = textField.text;
[[NSUserDefaults standardUserDefaults] setObject: newString forKey:@"textKey"];
Would this be the proper way of checking whether this value exists when I release an update to the app that is now coded in Swift:
if (UserDefaults.standard.object(forKey: "textKey") as? String) != nil {
print("There is a string")
} else {
print("No string exists")
}
I try to use .string(forKey:) and .bool(forKey:) since they've been introduced, but is it safest since this was saved as an object to pull it out as an object and then test it with "as? String"?
Trickier version of the same question:
An NSMutableArray of NSDictionary objects was saved as an object in UserDefaults
if let oldData = UserDefaults.standard.object(forKey: "theData") as? [NSMutableDictionary] {
}
Will NSDictionary and NSMutableDictionary be interchangeable here?
Thanks!
回答1:
[NS]UserDefaults
is backed by a plist and a dictionary. The Objective-C string was saved to the plist as a <string>Some Text</string>
.
That same plist loaded in Swift gives a string for that key.
So you should have no issue using UserDefaults.string
to read the value stored with Objective-C. Of course you still need to verify the value actually exists.
if let str = UserDefaults.standard.string(forKey: "textKey") {
print("Found \(str)")
} else {
print("No string for key")
}
Even if the original value isn't a string, using UserDefault.string
is safe. It will simply return nil
for non-string values.
With regard to NSDictionary
and NSMutableDictionary
, note that UserDefaults
only retrieves immutable NSDictionary
. You can't read an NSMutableDictionary
(or array) from UserDefaults
.
Note you can safely use a Swift dictionary to read the original NSDictionary
. No need to use Objective-C classes.
回答2:
Yes your solution is safe, if the value you saved in the Objective C code is indeed a String
type than, when you retrieve that value from NSUserDefaults
, it will be a String and will correctly be coerced to a String by the ?
operator of your Swift code.
回答3:
The recommended way (in Swift and Objective-C) is to register each key value pair to provide a default value. This default value is considered until the value is changed the first time.
let userDefaults = UserDefaults.standard
let defaultValues : [String : Any] = ["textKey" : "", "dictionaryKey" : [:]]
userDefaults.register(defaults: defaultValues)
Now you can safely write
if UserDefaults.standard.string(forKey: "textKey")!.isEmpty {
print("No string exists")
} else {
print("There is a string")
}
Of course the developer is responsible for overwriting a value with the same type.
NSMutableDictionary
is not related to Swift Dictionary
. To get a mutable object just use the var
keyword.
var dictionary = UserDefaults.standard.object(forKey: "dictionaryKey") as! [String:Any]
来源:https://stackoverflow.com/questions/44171504/userdefaults-between-objective-c-and-swift