Я немного запутался по поводу того, как декодировать SKSpriteNode.
У меня есть следующий класс SKSpriteNode:
class Person : SKSpriteNode
{
var gender : Gender
var age : Age
var positionX : CGFloat!
var positionY : CGFloat!
let frontTexture : SKTexture
let backTexture : SKTexture
required convenience init?(coder aDecoder: NSCoder)
{
print("INITIALIZED WITH DECODER????")
guard let myPerson = aDecoder.decodeObject(forKey: "person") as? Person
else { return nil }
self.init(coder: aDecoder)
}
func encodeWithCoder(coder: NSCoder)
{
coder.encode(self, forKey: "person")
}
init(gender: Gender, age: Age, positionX: CGFloat, positionY: CGFloat, sceneSize: CGSize)
{
self.gender = gender
self.age = age
self.backTexture = SKTexture(imageNamed: "person_back")
self.frontTexture = SKTexture(imageNamed: "person_front")
var currentTexture = self.frontTexture
super.init(texture: currentTexture, color: .clear, size: frontTexture.size())
// Position of the person in the scene
self.position = updatePosition(positionX: positionX, positionY: positionY, sceneSize: sceneSize)
}
В подклассе MultipeerConnection я использую это для отправки закодированных данных(данные, похоже, правильно заархивированы):
func sendData(dictionaryWithData dictionary: Dictionary<String, Any>, toPeer targetPeers: [MCPeerID])
{
let dataToSend = NSKeyedArchiver.archivedData(withRootObject: dictionary)
do
{
try session.send(dataToSend, toPeers: targetPeers, with: MCSessionSendDataMode.reliable)
}
catch
{
print("ERROR")
}
}
с данными, полученными следующим образом (толпа - это массив [Person]):
func makeMessageCrowd() -> Dictionary<String, Any>
{
var messageToSend = Dictionary<String, Any>()
messageToSend["move"] = "start"
messageToSend["action"] = appDelegate.persons
return messageToSend
}
Я использую следующее для получения данных:
func session(_ session: MCSession,
didReceive data: Data,
fromPeer peerID: MCPeerID)
{
let message = NSKeyedUnarchiver.unarchiveObject(with: data) as! Dictionary<String, Any>
if let moveType = message["move"] as? String
{
switch(moveType)
{
case "start":
appDelegate.persons = message["action"] as! [Person]
default:
print("default")
}
}
}
Прямо сейчас он начинает инициализацию объекта Person с помощью удобного инициализатора, а затем вылетает здесь:
let message = NSKeyedUnarchiver.unarchiveObject(with: data) as! Dictionary<String, Any>
, говоря, что он нашел нулевое значение.Однако данные, кажется, имеют 15000 байтов, поэтому они были переданы правильно.
Если вместо удобного инициализатора я использую это:
required init?(coder aDecoder: NSCoder)
{
//fatalError("NSCoding not supported")
self.gender = Gender.male
self.age = Age.young
self.frontTexture = SKTexture(imageNamed: "person_front")
self.backTexture = SKTexture(imageNamed: "person_back")
self.positionX = 0
self.positionY = 0
super.init(coder: aDecoder)
}
У меня нет сбоя, однакомассив [Person] на одноранговом устройстве создается с использованием значений по умолчанию, инициализированных как указано выше, а не как передано.
Это виновник, так как он возвращает nil:
guard let myPerson = aDecoder.decodeObject(forKey: "person") as? Person
else { return nil }
Как мнеправильно кодировать и декодировать пользовательский класс?
Большое спасибо!