Swift 将多个对象传递给NSUserDefault中的WatchKit

Swift 将多个对象传递给NSUserDefault中的WatchKit,swift,nsuserdefaults,watchkit,Swift,Nsuserdefaults,Watchkit,在这里的一些优秀教程和用户的帮助下,我成功地在我的应用程序中实现了SwiftyJSON,并获得了一个基本的WatchKit应用程序。我要通过的最后一个障碍是将我的整个解析JSON数据集传递给WatchKit,以便允许我从TableView中的一个单元格中进行选择,并获取关于一个条件的更具体细节 我正在分析Minion.swift文件中的JSON数据,就像这样 import UIKit class Minion { var name: String? var age: Stri

在这里的一些优秀教程和用户的帮助下,我成功地在我的应用程序中实现了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喜欢这样

我截断了大部分代码,因为我认为它与WatchKit无关。在WatchKit扩展中,我有我的InterfaceController.swift,就像这样

当我运行iOS应用程序时,它向我抛出错误“Property list invalid for format:200(Property list不能包含'CFType'类型的对象”),因为我将整个JSON数据集作为“minions”传递。如果我将NSUserDefaults键设置为“minions[0].name”,它将传递单个字符串,但传递整个数据集以便WatchKit表允许我选择一行似乎是在逃避我


与往常一样,我非常感谢。

您的
仆从
类需要实现
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
    }
}
在ViewController类中:

  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]
}

谢谢@ztan!我想这正是我想要的。只是想澄清一下,你介绍的第一个代码块将放在我的“Minions.swift”文件中,对吗?我遇到了一些类型不符合NSCoding的错误,但我会进一步调查。是的,第一个块是为您的
Minion.swift
文件创建的。谢谢@ztan!我想我很接近,你的指导堪称典范。很抱歉一直打扰您,但我希望您能建议如何处理您提供给我的最后一段代码。我会把它放在手表套件扩展的InterfaceController.swift中吗?在WatchKit InterfaceController中,我似乎很难找到将minions变量设置为NSData对象集的正确位置/措辞。再次感谢@AlanLewis,如果您想显示手表中的数据,最后一块代码应该放在WatchKit扩展名的
InterfaceController.swift
文件中。您可以将该代码放在
覆盖func willActivate()
方法中。因此,当您的手表界面将向用户显示时,您可以检索
NSUserDefaults
数据。谢谢@ztan。我仍然在实现
if let data=ud.objectForKey(“minions”)as时遇到错误?NSData{
在我的项目中,Xcode报告斜体(使用未解析的标识符'ud'')\u斜体。由于我在我的项目中没有在任何其他地方引用“ud”,我尝试将
if let data=defaults?.objectForKey(“仆从”)作为NSData{
,这似乎消除了该错误,但随后告诉我我的“仆从”被推断为具有可能意外的类型“AnyObject”。
  NSKeyedArchiver.setClassName("Minion", forClass: Minion.self)
  defaults?.setObject(NSKeyedArchiver.archivedDataWithRootObject(minions), forKey: "minions")
if let data = defaults?.objectForKey("minions") as? NSData {
    NSKeyedUnarchiver.setClass(Minion.self, forClassName: "Minion")
    let minions = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! [Minion]
}