Кодирование и декодирование SKSpriteNode - PullRequest
0 голосов
/ 22 октября 2018

Я немного запутался по поводу того, как декодировать 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 }

Как мнеправильно кодировать и декодировать пользовательский класс?

Большое спасибо!

...