2017-07-06 36 views
0

我正在努力解决一个问题。我想发送一个结构到连接的设备。Swift 3,Multipeer,发送结构为数据

这里是我使用复制到游乐场

在代码的代码我加了一些扩展到数据类用于编码/解码。我创建了[String:Player]字典,并使用NSKeyedArchiver创建要发送的数据记录。

我不会在这里发送,但在我的程序中我做。在操场上,代码/解码工作正常。当我在我的程序中执行时,从数据中提取播放器时解码失败。它失败:EXC_BAD_ACCESS

如果我使用String而不是Player结构,它在didReceive数据函数中正确解码。仅在使用Struct时失败。

任何人有一些建议吗?

//: Playground - noun: a place where people can play 
import UIKit 

// Player structure 
struct Player { 
    var initials : String 
    var name : String 
} 

// 
// Data extension 
// 
extension Data { 

    // struct 
    init<T>(from value: T) { 
     var value = value 
     self.init(bytes: &value, count: MemoryLayout<T>.size) 
    } 

    // extract Struct 
    func extract<T>(from: T.Type) -> T { 
     return self.withUnsafeBytes { $0.pointee } // FAILS HERE: EXC_BAD_ACCESS 
    } 
} 

// Make a data record for sending 
let sply = Player(initials: "PN", name: "Player Name") 
let spda = Data(from: sply) 
let sdic : [String:Data] = ["Player" : spda] 
let sdta : Data = NSKeyedArchiver.archivedData(withRootObject: sdic) 

// Do the sending 
// ... send... 

//Decode 
// The following code that is used on the receiving device in 
// the "didReceive data" function. 
let rdic = NSKeyedUnarchiver.unarchiveObject(with: sdta) as! [String : Data] 
let rdta = rdic["Player"]! 
let rply = rdta.extract(from: Player.self) 
print(rply.name)  // Prints: "Player Name" 

回答

1

对我来说有效的是自定义类,它继承自NSObject并符合NSCoding。

class Player: NSObject, NSCoding { 
    var initials: String! 
    var name: String! 

    required convenience init(coder decoder: NSCoder) { 
     self.init() 
     self.initials = decoder.decodeObject(forKey: "initials") as! String 
     self.name = decoder.decodeObject(forKey: "name") as! String 
    } 

    convenience init(initials: String, name: String) { 
     self.init() 
     self.initials = initials 
     self.name = name 
    } 

    func encode(with aCoder: NSCoder) { 
     if let initials = initials { aCoder.encode(initials, forKey: "initials") } 
     if let name = name { aCoder.encode(name, forKey: "name") } 
    } 
} 

使数据传送:

let data = NSKeyedArchiver.archivedData(withRootObject: Player(initials: "PN", name: "Player Name")) 

获取数据传回播放器:

guard let player: Player = NSKeyedUnarchiver.unarchiveObject(with: data) as! Player? else { return } 
+0

非常感谢!这项工作就是我想要的,没有错误! – teho

+0

我在这里找到了更好的解决方案:https://stackoverflow.com/a/41538762/2957546 – teho