Доступ к словарю в Swift

Рассмотрим следующий код, который получает массив словарей из 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]

Теперь у меня возникают проблемы с доступом к отдельным книжным словарям:

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 

Каков правильный способ найти название книги?

Ответ 1

Вы можете использовать новые синтаксические сахара для массивов и словарей из бета-версии 3.

let path = NSBundle.mainBundle().pathForResource("books", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path)
let books = dict.objectForKey("Books")! as [[String:AnyObject]]

Вы можете получить доступ к bookData как есть, автоматический вывод типа должен работать...

let rnd = Int(arc4random_uniform((UInt32(books.count))))
let bookData = books[rnd]

Поместите явный тип для каждого элемента в книжном словаре, так как мы определили его как AnyObject.

let title = bookData["title"]! as String
let numPages = bookData["pages"]! as Int

Позднее редактирование

  • При использовании оператора nil coalescing ?? вы можете проверить значения nil и предоставить альтернативное значение следующим образом:

    let title = (bookData["title"] as? String) ?? "untitled"
    let numPages = (bookData["pages"] as? Int) ?? -1
    

Ответ 2

Swift:

Если используется Dictionary:

if let bookData = bookData{
   if let keyUnwrapped = bookData["title"]{
      title = keyUnwrapped.string
   }
}