Store dictionary with optional values [String: AnyObject?] in NSUserDefaults - swift

I need to store a dictionary that which can contain a nil as a value
Example
var someOptionalVar: String? = nil
var dict: [String: AnyObject?] = [
"someOptionalVar": self.someOptionalVar
]
defaults.setObject(dict, forKey: self.nsUserDefaultsKey)
But it gives me this error
Cannot convert value of type '[String: AnyObject?]' to expected
argument type 'AnyObject?'
I know I could leave the nil variables and then when I'm parsing the dictionary from NSUserDefaults I would set variables (corresponding to the missing properties) to nil, but this is not what I would like to do.
So how can I store nil values in NSUserDefaults ?

Use NSNull() instead of nil, and declare the dictionary to contain only non-optionals:
var someOptionalVar: String? = nil
var dict: [String: AnyObject] = [
"someOptionalVar": self.someOptionalVar ?? NSNull()
]
defaults.setObject(dict, forKey: self.nsUserDefaultsKey)

Related

Store dictionary in UserDefaults using #Published

I have this:
#Published var mealsAndTime: [String: Date] = UserDefaults.standard.dictionary(forKey: "mealsAndTime") {
didSet {
UserDefaults.standard.set(self.mealsAndTime, forKey: "mealsAndTime")
}
}
and it's telling me:
Cannot convert value of type '[String : Any]' to expected argument type '[String : Date]'
What's wrong here?
Thanks
Casting... UserDefaults does not know about internal values, so type is Any. You have to cast explicitly, as you know your types, but safely, just in case.
So solution is
#Published var mealsAndTime: [String: Date] =
UserDefaults.standard.dictionary(forKey: "mealsAndTime") as? [String: Date] ?? [:] {
didSet {
UserDefaults.standard.set(self.mealsAndTime, forKey: "mealsAndTime")
}
}

Swift 3: How to convert from [String: AnyObject] to [String: String]?

I want to convert a [String: Anyobject] dictionary to [String: String] dictionary?
How can I do this?
You cannot convert a dictionary directly from [String: AnyObject] to [String: String]: since AnyObject can hold different types of values in the same dict, each such value entry isn't necessarily convertable to String.
Instead, you need to go over each key-value pair and conditionally perform a value conversion to String, if possible. E.g.:
// (example) source dict
let dict: [String: AnyObject] = ["foo": "1" as AnyObject,
"bar": 2 as AnyObject,
"baz": "3" as AnyObject]
// target dict
var targetDict = [String: String]()
for (key, value) in dict {
if let value = value as? String { targetDict[key] = value }
} // targetDict: ["foo": "1", "baz": "3"]
Simply, you can do it this way:
if let castedDict = dictionary as? [String: String] {
print("Converted successfully: \(castedDict)")
} else {
print("Failed to cast the dictionary")
}

Nsuserdefaults remove value and key

I want to know how to remove both key and value in NSUserDefaults . removeobjectforkey only removes the value ?
removeObjectForKey(string)
Swift 3
to add value in NSUserDefault
integer
UserDefaults.standard.integer(forKey: "key")
a dictionary
UserDefaults.standard.set(Dictvariable, forKey: "key")
get value
from integer
key value = UserDefaults.standard.integer(forKey: "key")
get value from dictionary
let result = UserDefaults.standard.value(forKey: "key") as? [String: String] ?? [String: String]()
to remove(i not tried this u can try this take it from stackoverflow 99% its work)
UserDefaults.standard.removeObject(forKey: "yourKey")

Assign Value of NSNumber to AnyObject

I have a segment of code that gets info from an API, and I need to add it to a Dictionary. The code is below:
typealias JSONdic = [String: AnyObject]
var weatherData: AnyObject = StorageManager.getValue(StorageManager.StorageKeys.WeatherData)!
let json: AnyObject = ["Any": "Object"]
if let json = json as? JSONdic, history = json["history"] as? JSONdic, tempi = history["tempi"] as? Int, hum = history["hum"] as? String, precip = history["precipi"] as? String{
println("Temperature:\(tempi) Humidity:\(hum) Precipitation:\(precip)")
weatherData = [NSDate: AnyObject]()
let temp = tempi as NSNumber
weatherData[(The Current Date)] = temp
}
I want to first add "temp" to the weatherData Dictionary, but even after casting it to NSNumber, I am told that an NSNumber value cannot be assigned to the AnyObject?! type. Can anyone help me fix this?
Your weatherData variable is of type AnyObject. Despite the fact that you later assign it a value of type [NSDate: AnyObject], the variable itself is still considered by the compiler to be AnyObject. You then hit problems because you try to subscript it, assigning an NSNumber, which is obviously not possible on AnyObject.
Your declaration of weatherData should ensure it is the type you intend. If you are sure that your StorageManager will return you the appropriate dictionary type for the weather data key, you can force downcast it to the correct type:
var weatherData = StorageManager.getValue(StorageManager.StorageKeys.WeatherData) as! [NSDate: NSObject]

How to unwrap optional NSDictionary

I cannot unwrap an optional NSDictionary. I am using NSDictionary because that is what I am returned when loading a plist from a file path.
var dict: NSDictionary? = NSDictionary(contentsOfFile: getFontPath())
assert(dict != nil, "Top level dictionary from plist can't be nil")
var fontArray = dict!objectForKey("fonts") as [NSDictionary]
The compiler is not recognizing dict! as an unwrap - tells me I should separate sequences by a ;
What is the problem and solution?
You're missing the attribute accessor (ie, the dot) after the exclamation point:
var fontArray = dict!.objectForKey("fonts") as [NSDictionary]
^
Depending on what you're doing, it might make more sense to use if let, eg:
if let unwrappedDict = dict as? NSDictionary {
}