Reputation: 13073
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?
Upvotes: 11
Views: 28690
Reputation: 6417
Swift:
If using Dictionary
:
if let bookData = bookData{
if let keyUnwrapped = bookData["title"]{
title = keyUnwrapped.string
}
}
Upvotes: 2
Reputation: 2459
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
Upvotes: 24