在 NSUserDefaults 中将多个对象传递给 WatchKit

Passing Multiple Objects To WatchKit In A NSUserDefaults

在一些很棒的教程和用户的帮助下,我成功地在我的应用程序中实现了 SwiftyJSON 并获得了一个基本的 WatchKit 应用程序。我要通过的最后一个障碍是将我的整个解析 JSON 数据集传递给 WatchKit,以允许我从 TableView 中的单元格中进行选择,并根据一条标准提取更具体的细节。

我正在解析 Minion.swift 文件中的 JSON 数据,就像这样;

import UIKit

class Minion {

    var name: String?
    var age: String?
    var height: String?
    var weight: String?


    class func fetchMinionData() -> [Minion] {
        let dataURL = NSURL(string: "http://myurl/json/")

        var dataError: NSError?

        let data = NSData(contentsOfURL: dataURL!, options: NSDataReadingOptions.DataReadingMappedIfSafe, error: &dataError)


        let minionJSON = JSONValue(data)
        var minions = [Minion]()

       for minionDictionary in minionJSON {
           minions.append(Minion(minionDetails: minionDictionary))
        }

        return minions 
    }

    init(minionDetails: JSONValue) {
        name = minionDetails["san"].string
        age = minionDetails["age"].string
        height = minionDetails["height"].string
        weight = minionDetails["free"].string
    }
}

对于我的 iOS 应用程序,这可以很好地填充我的 UITableView 和后续的详细信息视图。我的 ViewController.Swift 是这样的;

import UIKit

class ViewController: UITableViewController {

    let minions: [Minion]

    required init(coder aDecoder: NSCoder!) {
        minions = Minion.fetchMinionData()
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        let defaults = NSUserDefaults(suiteName: "group.com.mygroup.data")
        let key = "dashboardData"
        defaults?.setObject(minions, forKey: key)
        defaults?.synchronize()
    }

// MARK: Table view data source
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

}

我已经 运行整理了大部分代码,因为我认为它与 WatchKit 无关。在 WatchKit 扩展中,我有我的 InterfaceController.swift 像这样;

import WatchKit

class InterfaceController: WKInterfaceController {

    @IBOutlet weak var minionTable: WKInterfaceTable!

    let defaults = NSUserDefaults(suiteName: "group.com.mygroup.data")

    var dashboardData: String? {
        defaults?.synchronize()
        return defaults?.stringForKey("dashboardData")
    }

    let minions = ???

当我 运行 iOS 应用程序时,它向我抛出错误 "Property list invalid for format: 200 (property lists cannot contain objects of type 'CFType')" 因为我将整个 JSON 数据集作为 "minions." 传递如果我将我的 NSUserDefaults 键设置为 "minions[0].name" 它将传递单个字符串,但传递整组数据以便 WatchKit table 可以让我选择一行似乎在逃避我。

提前,一如既往,我非常感谢。

您的 Minion class 需要实施 NSCoding。然后在您的视图控制器中,您需要将 Minion 对象传输到 NSData 对象。

 class Minion: NSObject, NSCoding  {
    .....
    init(coder aDecoder: NSCoder!) {
      aCoder.encodeObject(name, forKey: "name")
      aCoder.encodeObject(age, forKey: "age")
      aCoder.encodeObject(height, forKey: "height")
      aCoder.encodeObject(weight, forKey: "weight")
    }

    func encodeWithCoder(aCoder: NSCoder) {
       name = aDecoder.decodeObjectForKey("name") as String
       age = aDecoder.decodeObjectForKey("age") as String
       height = aDecoder.decodeObjectForKey("height") as String
       weight = aDecoder.decodeObjectForKey("weight") as String
    }
}

在你的ViewControllerclass中:

  NSKeyedArchiver.setClassName("Minion", forClass: Minion.self)
  defaults?.setObject(NSKeyedArchiver.archivedDataWithRootObject(minions), forKey: "minions")

如果要从 NSUserDefaults 检索数据:

if let data = defaults?.objectForKey("minions") as? NSData {
    NSKeyedUnarchiver.setClass(Minion.self, forClassName: "Minion")
    let minions = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! [Minion]
}