Swift2 使用Swift中的WatchConnectivity/encoding传输自定义对象数组

Swift2 使用Swift中的WatchConnectivity/encoding传输自定义对象数组,swift2,encode,nskeyedarchiver,nscoder,watchconnectivity,Swift2,Encode,Nskeyedarchiver,Nscoder,Watchconnectivity,我正在尝试将自定义对象数组从iOS传输到watchkitextension 要理解,为了做到这一点,需要对数据进行编码。我觉得解码时出错了 我们开始: 自定义对象: final class Person: NSObject { var PersonName:String = "" var PersonAge:Int = 0 var joined:NSDate = NSDate() init(PersonName: Stri

我正在尝试将自定义对象数组从iOS传输到watchkitextension

要理解,为了做到这一点,需要对数据进行编码。我觉得解码时出错了

我们开始:

自定义对象:

    final class Person: NSObject {
        var PersonName:String = ""
        var PersonAge:Int = 0
        var joined:NSDate = NSDate()

        init(PersonName: String, PersonAge:Int, joined:NSDate){
            self.PersonName = PersonName
            self.PersonAge = PersonAge
            self.joined = joined
            super.init()
        }
    }

   extension Person: NSCoding {
        private struct CodingKeys {
            static let PersonName = "PersonName"
            static let PersonAge = "PersonAge"
            static let joined = "joined"
        }

        convenience init(coder aDecoder: NSCoder) {
            let PersonName = aDecoder.decodeObjectForKey(CodingKeys.PersonName) as! String
            let PersonAge = aDecoder.decodeIntForKey(CodingKeys.PersonAge) as! Int
            let joined = aDecoder.decodeDoubleForKey(CodingKeys.joined) as! NSDate

            self.init(PersonName: PersonName, PersonAge: PersonAge, joined: joined)
        }

        func encodeWithCoder(encoder: NSCoder) {
            encoder.encodeObject(PersonName, forKey: CodingKeys.PersonName)
            encoder.encodeObject(PersonAge, forKey: CodingKeys.PersonAge)
            encoder.encodeObject(joined, forKey: CodingKeys.joined)
        }
    }
包含数组的类:

@objc(Group)
final class Group: NSObject {

    static let sharedInstance = Group()

    var Persons:[Person] = []

    required override init() {
        super.init()
    }

    init (Persons:[Person]){
        self.Persons = Persons
        super.init()
    }

}

extension Group: NSCoding {
    private struct CodingKeys {
        static let Persons = "Persons"
    }

    convenience init(coder aDecoder: NSCoder) {

        let Persons = aDecoder.decodeObjectForKey(CodingKeys.Persons) as! [Person]
        self.init(Persons: Persons)

        self.Persons = aDecoder.decodeObjectForKey(CodingKeys.Persons) as! [Person]
    }

    func encodeWithCoder(encoder: NSCoder) {
        encoder.encodeObject(Persons, forKey: CodingKeys.Persons)
    }
}
创建示例对象,附加到数组,然后编码:

let aPerson:Person? = Person(PersonName: "Martin", PersonAge: 50, joined: NSDate())

Group.sharedInstance.Persons.append(aPerson!) 
let encodedData = NSKeyedArchiver.archivedDataWithRootObject(Group.sharedInstance)
这里我得到了错误“执行被中断-原因信号SIGABRT”


尝试将这些部分更改为:

convenience init(coder aDecoder: NSCoder) {
    let PersonName = aDecoder.decodeObjectForKey(CodingKeys.PersonName) as! String
    let PersonAge = aDecoder.decodeIntForKey(CodingKeys.PersonAge) as! Int
    let joined = aDecoder.decodeObjectForKey(CodingKeys.joined) as! NSDate

    self.init(PersonName: PersonName, PersonAge: PersonAge, joined: joined)
}

func encodeWithCoder(encoder: NSCoder) {
    encoder.encodeObject(PersonName, forKey: CodingKeys.PersonName)
    encoder.encodeInt(PersonAge, forKey: CodingKeys.PersonAge)
    encoder.encodeObject(joined, forKey: CodingKeys.joined)
}

以便序列化与反序列化以及Person类所需的类型相匹配。尽管如此,WWDC关于WatchConnectivity的谈话特别建议不要使用NSKeyedArchiver,因为它不是一种非常节省空间的序列化方法。

感谢您强调这种不匹配。不幸的是,这仍然是一个问题。如果不是NSKeyedArchiver,您使用什么?(我尝试了直接从watchkitextension解析JSON,它在模拟器上运行得很好,但在物理设备上超时,因此我现在恢复从电话解析,然后在手机上传递数据)NSPropertyListSerialization是WatchConnectivity工程师推荐的方法之一。只需确保只使用属性列表类型(看起来就是这样)。基本上,您会在Person类中添加一个
-(NSDictionary*)dictRepresentation
和一个
-(id)initWithDictionaryRepresentation:(NSDictionary*)dictionaryRepresentation
。如果您仍然遇到问题,您的代码中肯定有其他地方的bug。由于进程正在崩溃,您应该获得生成的崩溃报告,该报告将准确地告诉您问题所在。对不起,詹森,我还是Swift的新手。如何/在何处使用NSPropertySerialization实现这一点?
convenience init(coder aDecoder: NSCoder) {
    let PersonName = aDecoder.decodeObjectForKey(CodingKeys.PersonName) as! String
    let PersonAge = aDecoder.decodeIntForKey(CodingKeys.PersonAge) as! Int
    let joined = aDecoder.decodeObjectForKey(CodingKeys.joined) as! NSDate

    self.init(PersonName: PersonName, PersonAge: PersonAge, joined: joined)
}

func encodeWithCoder(encoder: NSCoder) {
    encoder.encodeObject(PersonName, forKey: CodingKeys.PersonName)
    encoder.encodeInt(PersonAge, forKey: CodingKeys.PersonAge)
    encoder.encodeObject(joined, forKey: CodingKeys.joined)
}