Исключение Swift PFFile при кодировании с помощью aCoder

Я пытаюсь закодировать PFFile и постоянно сохранять его, но он возвращает исключение:

Класс:

import UIKit

import Parse

class Usuario: PFObject, PFSubclassing, NSCoding {

    //MARK: Propriedades
    //O NSManaged é para o PFObject
    @NSManaged var nome: String?
    @NSManaged var foto: PFFile?
    @NSManaged var dataNascimento: Date?
    @NSManaged var numeroTelefone: String?
    @NSManaged var pais: PaisCodigo?
    @NSManaged var telefoneE164: String?

    static func parseClassName() -> String {
        return "Usuario"
    }


    //Isto é para NSObject e NSCoding
    override init() {

        super.init()
    }

    required init(coder aDecoder: NSCoder) {

        super.init()

        self.nome = aDecoder.decodeObject(forKey: "nome") as? String
        self.foto = aDecoder.decodeObject(forKey: "foto") as? PFFile
        self.dataNascimento = aDecoder.decodeObject(forKey: "dataNascimento") as? Date
        self.numeroTelefone = aDecoder.decodeObject(forKey: "numeroTelefone") as? String
        self.pais = aDecoder.decodeObject(forKey: "pais") as? PaisCodigo
        self.telefoneE164 = aDecoder.decodeObject(forKey: "telefoneE164") as? String
    }

    func encode(with aCoder: NSCoder) {

        if let nomeUsuario = nome {
            aCoder.encode(nomeUsuario, forKey: "nome")
        }

        if let fotoUsuario = foto {
            //The problems happens here
            aCoder.encode(fotoUsuario, forKey: "foto")
        }

        if let dataNascimentoUsuario = dataNascimento {
            aCoder.encode(dataNascimentoUsuario, forKey: "dataNascimento")
        }

        if let numeroTelefoneUsuario = numeroTelefone {
            aCoder.encode(numeroTelefoneUsuario, forKey: "numeroTelefone")
        }

        if let paisUsuario = pais {
            aCoder.encode(paisUsuario, forKey: "pais")
        }

        if let telefoneE164Usuario = telefoneE164 {
            aCoder.encode(telefoneE164Usuario, forKey: "telefoneE164")
        }
    }
}

Я пытаюсь сохранить данные с помощью этого метода:

Объект contatos представляет собой массив Usuario (класс выше)

func fazerCacheContatos() {

        let userDefaults = UserDefaults.standard

        let contatosIDoPartyCodificados: Data = NSKeyedArchiver.archivedData(withRootObject: contatos)

        userDefaults.set(contatosCodificados, forKey: "cacheContatos")

        userDefaults.synchronize()
    }

Когда я запускаю приложение, я получаю это исключение:

-[PFFile encodeWithCoder:]: unrecognized selector sent to instance 0x170e513d0

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[PFFile encodeWithCoder:]: unrecognized selector sent to instance 0x170e513d0'


person GuiDupas    schedule 30.08.2017    source источник


Ответы (2)


Похоже, ваш класс PFFile не поддерживает протокол NSCoding. Если PFFile — ваш собственный класс, то вы можете решить эту проблему, добавив к нему поддержку NSCoding. Если PFFile — это класс, который вы получаете от третьей стороны, для которого у вас нет исходного кода, вам придется найти какой-то другой способ хранения информации, необходимой для восстановления PFFile позже.

person Charles Srstka    schedule 30.08.2017
comment
Спасибо за предложение. - person GuiDupas; 30.08.2017

Решение заключалось в преобразовании объекта в UIImage для кодирования и в PFFile после декодирования, как показано ниже:

import UIKit

import Parse

class Usuario: PFObject, PFSubclassing, NSCoding {

    //MARK: Propriedades
    //O NSManaged é para o PFObject
    @NSManaged var nome: String?
    @NSManaged var foto: PFFile?
    @NSManaged var dataNascimento: Date?
    @NSManaged var numeroTelefone: String?
    @NSManaged var pais: PaisCodigo?
    @NSManaged var telefoneE164: String?

    static func parseClassName() -> String {
        return "Usuario"
    }


    //Isto é para NSObject e NSCoding
    override init() {

        super.init()
    }

    required init(coder aDecoder: NSCoder) {

        super.init()

        self.nome = aDecoder.decodeObject(forKey: "nome") as? String

        let image = aDecoder.decodeObject(forKey: "foto") as? UIImage
        if let fotoImage = image {
            self.foto = PFFile(data: UIImagePNGRepresentation(fotoImage)!)
        }

        self.dataNascimento = aDecoder.decodeObject(forKey: "dataNascimento") as? Date
        self.numeroTelefone = aDecoder.decodeObject(forKey: "numeroTelefone") as? String
        self.pais = aDecoder.decodeObject(forKey: "pais") as? PaisCodigo
        self.telefoneE164 = aDecoder.decodeObject(forKey: "telefoneE164") as? String
    }

    func encode(with aCoder: NSCoder) {

        if let nomeUsuario = nome {
            aCoder.encode(nomeUsuario, forKey: "nome")
        }

        if let fotoUsuario = foto {
            do {
                let dataImage = try fotoUsuario.getData()

                let image = UIImage(data: dataImage)!

                aCoder.encode(image, forKey: "foto")
            } catch {
                //Erro
            }
        }

        if let dataNascimentoUsuario = dataNascimento {
            aCoder.encode(dataNascimentoUsuario, forKey: "dataNascimento")
        }

        if let numeroTelefoneUsuario = numeroTelefone {
            aCoder.encode(numeroTelefoneUsuario, forKey: "numeroTelefone")
        }

        if let paisUsuario = pais {
            aCoder.encode(paisUsuario, forKey: "pais")
        }

        if let telefoneE164Usuario = telefoneE164 {
            aCoder.encode(telefoneE164Usuario, forKey: "telefoneE164")
        }
    }
}
person GuiDupas    schedule 30.08.2017