Swift 使用 aCoder 编码时出现 PFFile 异常
Swift PFFile Exception when encoding with aCoder
我正在尝试对 PFFile 进行编码并永久保存它,但它 returns 一个异常:
class:
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数组(上面的class)
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'
您的 PFFile
class 似乎不支持 NSCoding
协议。如果 PFFile
是你自己的 class,那么你可以通过添加 NSCoding
支持来解决这个问题。如果 PFFile
是 class 你从没有源代码的第三方那里得到的,那么你将不得不找到一些其他方法来存储重构 PFFile
稍后。
解决方案是将对象转换为 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")
}
}
}
我正在尝试对 PFFile 进行编码并永久保存它,但它 returns 一个异常:
class:
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数组(上面的class)
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'
您的 PFFile
class 似乎不支持 NSCoding
协议。如果 PFFile
是你自己的 class,那么你可以通过添加 NSCoding
支持来解决这个问题。如果 PFFile
是 class 你从没有源代码的第三方那里得到的,那么你将不得不找到一些其他方法来存储重构 PFFile
稍后。
解决方案是将对象转换为 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")
}
}
}