Consider the following code which gets an array of dictionaries from a plist:
let path = NSBundle.mainBundle().pathForResource("books", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path)
let books:Array = dict.objectForKey("Books") as Array<Dictionary<String, AnyObject>> //I hate how ugly and specific this is. There has got to be a better way??? Why can't I just say let books:Array = dict.objectForKey("Books")?
let rnd = Int(arc4random_uniform((UInt32(books.count))))
let bookData:Dictionary = books[rnd]
Now, I'm having trouble accessing individual book dictionaries:
let title:String = bookData.objectForKey("title") //[String: AnyObject] does not have a member named 'objectForKey'
let title:String = bookData["title"] // (String, AnyObject) is not convertible to String
What is the proper way to find the title of the book?
Swift 4 dictionaries use unique identifier known as a key to store a value which later can be referenced and looked up through the same key. Unlike items in an array, items in a dictionary do not have a specified order. You can use a dictionary when you need to look up values based on their identifiers.
Dictionaries in Swift and Objctive-C are unordered collections. They do not have any native order. If you want your data to be stored in a specific order, use an array of some other objects.
You could use the new syntactic sugars for Arrays and Dictionaries from Beta 3.
let path = NSBundle.mainBundle().pathForResource("books", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path)
let books = dict.objectForKey("Books")! as [[String:AnyObject]]
You can access bookData
as is, automatic type inference should work...
let rnd = Int(arc4random_uniform((UInt32(books.count))))
let bookData = books[rnd]
Put an explicit type for each item in the book dictionary, since we have defined it as AnyObject
.
let title = bookData["title"]! as String
let numPages = bookData["pages"]! as Int
Late edit
With the nil coalescing operator ??
you can check for nil values and provide an alternate value like so:
let title = (bookData["title"] as? String) ?? "untitled"
let numPages = (bookData["pages"] as? Int) ?? -1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With