2015-04-12 96 views
1

我想從plist文件迭代嵌套的字典。問題在於分解內容時類型不匹配。我總是得到錯誤,NSObject,NSDict和其他NSstuff不能轉換爲字符串變量,包括當我使用「(價值)」,字符串(),作爲..如何分解一個plist字典sub set tuple?(array)into separate variables ?迭代.plist字典。類型不匹配

func LoadPlistContacts() { 
    let path = NSBundle.mainBundle().pathForResource("ContactList", ofType: "plist") 
    var AppContactsList = NSDictionary(contentsOfFile: path!) 
    ListKeys = sorted(AppContactsList!.allKeys as! [String]) 

    for key in ListKeys { 
     var (AppPersonName, AppPersonSurname, AppPersonCompany, AppPersonPhone) = AppContactsList[key] 
     } 

    } 

更新: 我已經改變了與字典,而不是數組的plist中和更新的代碼,但類型不匹配仍然存在。 As Airspeed Velocity and nhgrif在評論中指出,例子確實與更新的plist有關。如果具有註釋錯誤的行不能解決它,我應該嵌套循環嗎?謝謝。

enter image description here

var ListKeys: [String]! 
var ListContacts: [String: String]! 

func LoadPlistContacts() { 

    if let path = NSBundle.mainBundle().pathForResource("ContactList", ofType: "plist") { 
     var AppContactsList = NSDictionary(contentsOfFile: path) 
     ListKeys = sorted(AppContactsList!.allKeys as! [String]) 
     ListContacts = sorted(AppContactsList!.allValues as [String:String]) { $0.0 < $1.0 } 
     // I get an error [AnyObject] is not convertible to '[String:String]' 

     for contact in ListContacts { 

      let name = contact["Forename"] ?? "" 
      let surname = contact["Surname"] ?? "" 
      let address = contact["Company"] ?? "" 
      let phone = contact["Phone"] ?? "" 
     } 

    } 
    else { 
     fatalError("Could not open Contacts plist") 
    } 
} 

順便說一句,空速速度,愛你的博客!

回答

4

Swift不允許你像這樣將數組解析爲元組 - 主要是因爲它不能保證工作(數組可能沒有正確數目的條目)。

您可能會發現更容易,而不是陣列,擁有的plist內的另一個字典:

A plist of dictionaries inside arrays inside dictionaries

然後使用像這樣的條目:

if let path = NSBundle.mainBundle().pathForResource("ContactList", ofType: "plist"), 
    contacts = NSDictionary(contentsOfFile: path) as? [String:[[String:String]]] 
{ 
    let sortedContacts = sorted(contacts) { lhs,rhs in lhs.0 < rhs.0 } 

    // destructuring works here because contacts is known 
    // at compile time to be an array of (key,value) pairs 
    for (section, contactArray) in sortedContacts { 
     for contact in contactArray { 
      let name = contact["Forename"] 
      let surname = contact["Surname"] 
      let address = contact["Company"] 
      let phone = contact["Phone"] 
      println(name,surname,address,phone) 
     } 
    } 
} 
else { 
    fatalError("Could not open Contacts plist") 
} 

注,當你將這些輸入出來,他們將是可選的。這確實是這種做法的另一個好處 - 它意味着你可以在plist中漏下的條目,然後要麼默認他們:

// default to blank string for phone number 
let phone = contact["Phone"] ?? "" 

或命令他們:

for (section, contactArray) in contacts { 
     for contact in contactArray { 
     if let name = contact["Forename"], 
       surname = contact["Surname"], 
       address = contact["Company"], 
       phone = contact["Phone"] 
     { 
      println(name,surname,address,phone) 
     } 
     else { 
      fatalError("Missing entry for \(section)") 
     } 
     } 
    } 

注意,它更最好使用if let,而不是用!強制展開事物,即使您正在從構建時配置的plist那樣工作,因此理論上不應該包含無效條目 - 因爲這樣可以明確地錯誤處理,這將有助於調試,如果你不小心把錯誤的數據放在plist中。

+0

我正在研究一個答案,但你很好涵蓋了所有要點。只是要評論說,提問者的plist結構並不符合你的說法。它看起來更像這樣:http://i.imgur.com/W03yayM.png – nhgrif

+0

啊,真的,好點。代碼應該很容易適應,否則將是一個更加混亂的例子。 –

+0

排序封閉測試中的.0訪問器是什麼?爲什麼它是必需的? –