使用 aCoder 编码时出现 Swift PFFile 异常
Posted
技术标签:
【中文标题】使用 aCoder 编码时出现 Swift PFFile 异常【英文标题】:Swift PFFile Exception when encoding with aCoder 【发布时间】:2017-08-30 18:28:01 【问题描述】:我正在尝试对 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'
【问题讨论】:
【参考方案1】:您的PFFile
类似乎不支持NSCoding
协议。如果PFFile
是你自己的类,那么你可以通过添加NSCoding
支持来解决这个问题。如果PFFile
是您从没有源代码的第三方获得的类,那么您将不得不找到其他方法来存储稍后重构PFFile
所需的信息。
【讨论】:
感谢您的建议。【参考方案2】:解决方案是将对象转换为 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")
【讨论】:
以上是关于使用 aCoder 编码时出现 Swift PFFile 异常的主要内容,如果未能解决你的问题,请参考以下文章
使用 Alamofire 和 PromiseKit 使用 Swift 时出现 Void 错误(请求)
使用 performSegueWithIdentifier 时出现 Swift UIImageView 错误
在 XCode/Swift 上安装/使用 DCKit 时出现问题