How to add nil value to Swift Dictionary?
SwiftDictionaryNullOptionalSwift Problem Overview
I have made a request to my server in my app. And posted data something like this.Server side is waiting for all parameters even they are nil. But i couldn't add nil values to dictionary.
var postDict = Dictionary<String,AnyObject>
postDict[pass]=123
postDict[name]="ali"
postDict[surname]=nil // dictionary still has only pass and name variables.
Is there a way to add nil value to dictionary ?
Swift Solutions
Solution 1 - Swift
> How to add nil
value to Swift Dictionary?
Basically the same way you add any other value to a dictionary. You first need a dictionary which has a value type that can hold your value. The type AnyObject
cannot have a value nil
. So a dictionary of type [String : AnyObject]
cannot have a value nil
.
If you had a dictionary with a value type that was an optional type, like [String : AnyObject?]
, then it can hold nil
values. For example,
let x : [String : AnyObject?] = ["foo" : nil]
If you want to use the subscript syntax to assign an element, it is a little tricky. Note that a subscript of type [K:V]
has type V?
. The optional is for, when you get it out, indicating whether there is an entry for that key or not, and if so, the value; and when you put it in, it allows you to either set a value or remove the entry (by assigning nil
).
That means for our dictionary of type [String : AnyObject?]
, the subscript has type AnyObject??
. Again, when you put a value into the subscript, the "outer" optional allows you to set a value or remove the entry. If we simply wrote
x["foo"] = nil
the compiler infers that to be nil
of type AnyObject??
, the outer optional, which would mean remove the entry for key "foo"
.
In order to set the value for key "foo"
to the AnyObject?
value nil
, we need to pass in a non-nil
outer optional, containing an inner optional (of type AnyObject?
) of value nil
. In order to do this, we can do
let v : AnyObject? = nil
x["foo"] = v
or
x["foo"] = nil as AnyObject?
Anything that indicates that we have a nil
of AnyObject?
, and not AnyObject??
.
Solution 2 - Swift
You can use the updateValue
method:
postDict.updateValue(nil, forKey: surname)
Solution 3 - Swift
As documented in here, setting nil
for a key in dictionary means removing the element itself.
If you want null
when converting to JSON
for example, you can use NSNull()
var postDict = Dictionary<String,AnyObject>()
postDict["pass"]=123
postDict["name"]="ali"
postDict["surname"]=NSNull()
let jsonData = NSJSONSerialization.dataWithJSONObject(postDict, options: NSJSONWritingOptions.allZeros, error: nil)!
let jsonString = NSString(data: jsonData, encoding: NSUTF8StringEncoding)!
// -> {"pass":123,"surname":null,"name":"ali"}
Solution 4 - Swift
You can use the Optional
type
var postDict = ["pass": 123, "name": "ali", "surname": Optional()]
Solution 5 - Swift
postDict[surname] = Optional<AnyObject>(nil)
Solution 6 - Swift
To add a nil
value to a dictionary in Swift, your dictionary's values must be of the Optional
type.
Consider a Person
class:
class Person {
let name: String
weak var spouse: Person?
init(name: String, spouse: Person?) {
self.name = name
self.spouse = spouse
}
}
Instances of the Person
type can have a name
and an optional spouse
. Create two instances, and add the first to a dictionary:
let p1 = Person(name: "John", spouse: nil)
let p2 = Person(name: "Doe", spouse: p1)
p1.spouse = p2
var people = [p1.name: p1.spouse]
This dictionary (called people
) maps names to spouses, and is of type [String: Person?]
. You now have a dictionary with a value of Optional
type: Person?
.
To update the value of the key p1.name
to be nil
, use the updateValue(_: forKey:)
method on the Dictionary
type.
people.updateValue(nil, forKey: p1.name)
people[p1.name]
The value for the key p1.name
is now nil
. Using updateValue(_: forKey:)
is a bit more straightforward in this case because it doesn't involve making a throwaway instance, setting it to nil
, and assigning that instance to a key in a dictionary.
NB: See rintaro's answer for inserting null
into a post's dictionary.
Solution 7 - Swift
var dict = [Int:Int?]()
dict[0] = (Int?).none // <--- sets to value nil
dict[0] = nil // <-- removes
dict[0] = .none // <-- same as previous, but more expressive
switch dict[0] {
case .none:
Swift.print("Value does not exist")
case .some(let value):
if let value = value {
Swift.print("Value exists and is", value)
} else {
Swift.print("Value exists and is nil")
}
}
Solution 8 - Swift
> Below dictionary will hold one key with nil value
var dict = [String:Any?]()
dict["someKey"] = nil as Any?
Solution 9 - Swift
postDict[surname]=nil
When you use subscript to set nil. It deletes the key if exists. In this case key surname will be removed from dictionary if exists.
To set value as nil, there are certain ways.
postDict.updateValue(nil, forKey: surname)
or
let anyObjectNil : AnyObject? = nil
postDict[surname] = anyObjectNil
or
postDict[surname] = nil as AnyObject?