以 swift 元组作为值的 NSCoding swift 字典
NSCoding swift dictionary with swift tuple as values
我有一个 Swift 字典,其中键作为字符串,值作为 Swift 元组。我想将这本字典发送到其他设备,所以我需要在这本字典上实现 NSCoding。任何人都可以帮助我如何实现这一目标。以下是我的字典代码。
class STCTruthDict: NSObject, NSCoding, SequenceType {
typealias IpRelationshipTuple = (String, String?)
private var truthDict: [String : IpRelationshipTuple] = [ : ]
subscript(key: String) -> IpRelationshipTuple? {
get {
return self.truthDict[key]
}
set {
truthDict[key] = newValue
}
}
// MARK: - Initializers
override init() {
super.init()
}
required init(coder aDecoder: NSCoder) {
self.truthDict = aDecoder.decodeObjectForKey("truthDict") as! [String : IpRelationshipTuple]
let key = aDecoder.decodeObjectForKey("user_id") as? String
let ip = aDecoder.decodeObjectForKey("tupleIp") as? String
let groupId = aDecoder.decodeObjectForKey("tupleGroupId") as? String
}
func encodeWithCoder(aCoder: NSCoder) {
for (key, tuple) in self.truthDict {
aCoder.encodeObject(key, forKey: "user_id")
aCoder.encodeObject(tuple.Ip, forKey: "tupleIp")
aCoder.encodeObject(tuple.groupId, forKey: "tupleGroupId")
}
}
func generate() -> DictionaryGenerator <String, IpRelationshipTuple> {
return self.truthDict.generate()
}
}
您 运行 遇到的问题是元组是 structs
而不是 class
(对象)类型。当您尝试执行以下操作时,您会注意到此问题:
if let dictionary = aDecoder.decodeObjectForKey("truthDict") as? [String : RelationshipType] { ... }
不幸的是,在尝试处理 Swift 中的值类型时会出现这个问题。要绕过此限制,您可以使用通用 Box
class 将值类型框起来,如下所示:
class Box<T>
{
var value : T?
init(_ value: T?)
{
self.value = value
}
}
使用 Box
class,您可以使用它来编码和解码您的字典元组:
class TruthDictionary : NSObject, NSCoding, SequenceType
{
typealias RelationshipType = (ip: String, groupId: String?)
private var dictionary = [String : RelationshipType]()
subscript(key: String) -> RelationshipType?
{
get { return self.dictionary[key] }
set { self.dictionary[key] = newValue }
}
// MARK: - Initializers
override init()
{
super.init()
}
// MARK: - NSCoding
required init(coder aDecoder: NSCoder)
{
// Unbox each tuple from the decoded dictionary
if let boxedDictionary = aDecoder.decodeObjectForKey("truthDict") as? [String : Box<RelationshipType>]
{
for (key, boxedTuple) in boxedDictionary
{
self.dictionary[key] = boxedTuple.value
}
}
}
func encodeWithCoder(aCoder: NSCoder)
{
var boxedDictionary = [String: Box<RelationshipType>]()
// Box each tuple to the dictionary to be encoded
for (key, tuple) in self.dictionary
{
boxedDictionary[key] = Box(tuple)
}
aCoder.encodeObject(boxedDictionary, forKey: "truthDict")
}
// MARK: - SequenceType
func generate() -> DictionaryGenerator<String, RelationshipType>
{
return dictionary.generate()
}
}
我有一个 Swift 字典,其中键作为字符串,值作为 Swift 元组。我想将这本字典发送到其他设备,所以我需要在这本字典上实现 NSCoding。任何人都可以帮助我如何实现这一目标。以下是我的字典代码。
class STCTruthDict: NSObject, NSCoding, SequenceType {
typealias IpRelationshipTuple = (String, String?)
private var truthDict: [String : IpRelationshipTuple] = [ : ]
subscript(key: String) -> IpRelationshipTuple? {
get {
return self.truthDict[key]
}
set {
truthDict[key] = newValue
}
}
// MARK: - Initializers
override init() {
super.init()
}
required init(coder aDecoder: NSCoder) {
self.truthDict = aDecoder.decodeObjectForKey("truthDict") as! [String : IpRelationshipTuple]
let key = aDecoder.decodeObjectForKey("user_id") as? String
let ip = aDecoder.decodeObjectForKey("tupleIp") as? String
let groupId = aDecoder.decodeObjectForKey("tupleGroupId") as? String
}
func encodeWithCoder(aCoder: NSCoder) {
for (key, tuple) in self.truthDict {
aCoder.encodeObject(key, forKey: "user_id")
aCoder.encodeObject(tuple.Ip, forKey: "tupleIp")
aCoder.encodeObject(tuple.groupId, forKey: "tupleGroupId")
}
}
func generate() -> DictionaryGenerator <String, IpRelationshipTuple> {
return self.truthDict.generate()
}
}
您 运行 遇到的问题是元组是 structs
而不是 class
(对象)类型。当您尝试执行以下操作时,您会注意到此问题:
if let dictionary = aDecoder.decodeObjectForKey("truthDict") as? [String : RelationshipType] { ... }
不幸的是,在尝试处理 Swift 中的值类型时会出现这个问题。要绕过此限制,您可以使用通用 Box
class 将值类型框起来,如下所示:
class Box<T>
{
var value : T?
init(_ value: T?)
{
self.value = value
}
}
使用 Box
class,您可以使用它来编码和解码您的字典元组:
class TruthDictionary : NSObject, NSCoding, SequenceType
{
typealias RelationshipType = (ip: String, groupId: String?)
private var dictionary = [String : RelationshipType]()
subscript(key: String) -> RelationshipType?
{
get { return self.dictionary[key] }
set { self.dictionary[key] = newValue }
}
// MARK: - Initializers
override init()
{
super.init()
}
// MARK: - NSCoding
required init(coder aDecoder: NSCoder)
{
// Unbox each tuple from the decoded dictionary
if let boxedDictionary = aDecoder.decodeObjectForKey("truthDict") as? [String : Box<RelationshipType>]
{
for (key, boxedTuple) in boxedDictionary
{
self.dictionary[key] = boxedTuple.value
}
}
}
func encodeWithCoder(aCoder: NSCoder)
{
var boxedDictionary = [String: Box<RelationshipType>]()
// Box each tuple to the dictionary to be encoded
for (key, tuple) in self.dictionary
{
boxedDictionary[key] = Box(tuple)
}
aCoder.encodeObject(boxedDictionary, forKey: "truthDict")
}
// MARK: - SequenceType
func generate() -> DictionaryGenerator<String, RelationshipType>
{
return dictionary.generate()
}
}