2017-07-06 39 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