2017-06-30 6 views
1

J'essaie d'enregistrer une liste d'une classe personnalisée aux valeurs par défaut de l'utilisateur et je continue de recevoir l'erreur "sélecteur non reconnu envoyé à l'instance" lors de l'enregistrement. Je n'ai aucun problème lors de l'obtention du tableau à partir des valeurs par défaut de l'utilisateur.Swift 3 NSCoder sélecteur non reconnu envoyé à l'instance

Ceci est le code que j'utilise pour enregistrer les valeurs par défaut de l'utilisateur.

let userDefaults = UserDefaults.standard 
     userDefaults.set(NSKeyedArchiver.archivedData(withRootObject: visitors), forKey: "signedInUsers") 
     userDefaults.synchronize() 

visiteurs est un tableau d'objets Visitor.

Voici ma classe Visiteur.

class Visitor: NSObject { 
    var name: String = "" 
    var contactEmail: String = "" 
    var company: String = "" 
    var picture: UIImage = UIImage() 
    var signature: UIImage = UIImage() 
    var timeIn: String = "" 
    var timeOut: String = "" 
    var signedOut: Bool = false 
    var otherQuestionsWithAnswers: [String] = [] 

    // MARK: NSCoding 

    override init() { 
     super.init() 
    } 

    init(name: String, contactEmail: String, company: String, picture: UIImage, signature: UIImage,timeIn: String,timeOut: String,signedOut: Bool,otherQuestionsWithAnswers: [String]) { 
     self.name = name 
     self.contactEmail = contactEmail 
     self.company = company 
     self.picture = picture 
     self.signature = signature 
     self.timeIn = timeIn 
     self.timeOut = timeOut 
     self.signedOut = signedOut 
     self.otherQuestionsWithAnswers = otherQuestionsWithAnswers 
    } 

    required convenience init?(coder decoder: NSCoder) { 
     guard let name = decoder.decodeObject(forKey: "name") as? String, 
      let contactEmail = decoder.decodeObject(forKey: "contactEmail") as? String, 
      let company = decoder.decodeObject(forKey: "company") as? String, 
      let timeOut = decoder.decodeObject(forKey: "timeOut") as? String, 
      let timeIn = decoder.decodeObject(forKey: "timeIn") as? String, 
      let picture = decoder.decodeObject(forKey: "picture") as? UIImage, 
      let signature = decoder.decodeObject(forKey: "signature") as? UIImage, 
      let otherQuestionsWithAnswers = decoder.decodeObject(forKey: "otherQuestionsWithAnswers") as? [String], 
      let signedOut = decoder.decodeObject(forKey: "signedOut") as? Bool 
      else { return nil } 

     self.init(
      name: name, 
      contactEmail: contactEmail, 
      company: company, 
      picture: picture, 
      signature: signature, 
      timeIn: timeIn, 
      timeOut: timeOut, 
      signedOut: signedOut, 
      otherQuestionsWithAnswers: otherQuestionsWithAnswers 
     ) 
    } 

    func encodeWithCoder(coder: NSCoder) { 
     coder.encode(name, forKey: "name") 
     coder.encode(contactEmail, forKey: "contactEmail") 
     coder.encode(company, forKey: "company") 
     coder.encode(picture, forKey: "picture") 
     coder.encode(signature, forKey: "signature") 
     coder.encode(timeIn, forKey: "timeIn") 
     coder.encode(timeOut, forKey: "timeOut") 
     coder.encode(signedOut, forKey: "signedOut") 
     coder.encode(otherQuestionsWithAnswers, forKey: "otherQuestionsWithAnswers") 
    } 
} 

Merci aide est appréciée.

EDIT:

Modification de la classe à ce fixe elle.

import Foundation 
import UIKit 

// a question that the user has to answer 
class Visitor: NSObject, NSCoding { 
    var name: String = "" 
    var contactEmail: String = "" 
    var company: String = "" 
    var picture: UIImage = UIImage() 
    var signature: UIImage = UIImage() 
    var timeIn: String = "" 
    var timeOut: String = "" 
    var signedOut: Bool = false 
    var otherQuestionsWithAnswers: [String] = [] 

    // MARK: NSCoding 

    override init() { 
     super.init() 
    } 

    init(name: String, contactEmail: String, company: String, picture: UIImage, signature: UIImage,timeIn: String,timeOut: String,signedOut: Bool,otherQuestionsWithAnswers: [String]) { 
     self.name = name 
     self.contactEmail = contactEmail 
     self.company = company 
     self.picture = picture 
     self.signature = signature 
     self.timeIn = timeIn 
     self.timeOut = timeOut 
     self.signedOut = signedOut 
     self.otherQuestionsWithAnswers = otherQuestionsWithAnswers 
    } 

    required init(coder decoder: NSCoder) { 
     name = decoder.decodeObject(forKey: "name") as! String 
     contactEmail = decoder.decodeObject(forKey: "contactEmail") as! String 
     company = decoder.decodeObject(forKey: "company") as! String 
     timeOut = decoder.decodeObject(forKey: "timeOut") as! String 
     timeIn = decoder.decodeObject(forKey: "timeIn") as! String 
     if let pictureTest = decoder.decodeObject(forKey: "picture") as? UIImage { 
      picture = pictureTest 
     } else { 
      picture = UIImage() 
     } 
     if let sigTest = decoder.decodeObject(forKey: "picture") as? UIImage { 
      signature = sigTest 
     } else { 
      signature = UIImage() 
     } 
     otherQuestionsWithAnswers = decoder.decodeObject(forKey: "otherQuestionsWithAnswers") as! [String] 
     signedOut = decoder.decodeBool(forKey: "signedOut") 
    } 

    public func encode(with aCoder: NSCoder) { 
     aCoder.encode(name, forKey: "name") 
     aCoder.encode(contactEmail, forKey: "contactEmail") 
     aCoder.encode(company, forKey: "company") 
     aCoder.encode(picture, forKey: "picture") 
     aCoder.encode(signature, forKey: "signature") 
     aCoder.encode(timeIn, forKey: "timeIn") 
     aCoder.encode(timeOut, forKey: "timeOut") 
     aCoder.encode(signedOut, forKey: "signedOut") 
     aCoder.encode(otherQuestionsWithAnswers, forKey: "otherQuestionsWithAnswers") 
    } 
} 
+3

Quel est le sélecteur spécifique qui n'est pas reconnu? Veuillez inclure le message d'erreur complet que vous voyez. –

+0

bonne question. même problème ici. joli code. hâte de voir une réponse à cette grande question. –

+0

comme @ItaiFerber dit quel sélecteur n'est pas reconnu? –

Répondre

0

La fonction que vous utilisez pour Cypher est incorrect, doit être func encode(with aCoder: NSCoder){} au lieu de func encodeWithCoder(coder: NSCoder) {} donc changer cela et fonctionne comme prévu

public func encode(with aCoder: NSCoder) { 
    aCoder.encode(name, forKey: "name") 
    aCoder.encode(contactEmail, forKey: "contactEmail") 
    aCoder.encode(company, forKey: "company") 
    aCoder.encode(picture, forKey: "picture") 
    aCoder.encode(signature, forKey: "signature") 
    aCoder.encode(timeIn, forKey: "timeIn") 
    aCoder.encode(timeOut, forKey: "timeOut") 
    aCoder.encode(signedOut, forKey: "signedOut") 
    aCoder.encode(otherQuestionsWithAnswers, forKey: "otherQuestionsWithAnswers") 
} 

Hope this helps

+0

Hmm ... Ne semble toujours pas être travail. Merci pour la réponse –

+0

@VincentLandolfi avez-vous nettoyé votre projet et réessayer? –

+0

Aucune erreur maintenant, mais la variable ne sauvegarde toujours pas –

0

Votre classe visiteur doit d'abord hériter à partir de NSObject suivi de NSCoding. Sans le NSCoding, vous ne pouvez pas encoder et décoder les classes personnalisées. C'est une erreur récente que j'ai faite dans mon projet, et la signature de votre fonction d'encodage est incorrecte. Je suis sûr que cela va régler ce problème. Voici le code corrigé:

Swift 3 Version: -

class Visitor: NSObject, NSCoding { 
    var name: String = "" 
    var contactEmail: String = "" 
    var company: String = "" 
    var picture: UIImage = UIImage() 
    var signature: UIImage = UIImage() 
    var timeIn: String = "" 
    var timeOut: String = "" 
    var signedOut: Bool = false 
    var otherQuestionsWithAnswers: [String] = [] 

func encode(with aCoder: NSCoder) { 
//... encode here 
} 
+0

Toujours ne semble pas fonctionner. Merci pour la réponse. –

+0

pouvez-vous mettre en place un point de rupture à cette déclaration de garde et voir si elle revient nulle? –

+0

Essayé, ne ressemble à rien est nul –