2016-07-15 15 views
3

So habe ich ein Array von benutzerdefinierten Objekten. Wenn ich versuche, das Array in NSUserDefaults zu speichern, muss ich sie archivieren. Hier ist, was ich tue das Array meiner benutzerdefinierten Objekte zu archivieren:Swift - Speichern von Benutzerdaten mit NSKeyedArchiver, erhalten Fehler bei der Konvertierung zu NSArray

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    //3 

    var allMessages = defaults.objectForKey(UserDefaultsMesssageKey) as! [AddMessageViewController.harassText] 
    var aMessage = AddMessageViewController.harassText(phoneNumber: 0, message: "1", frequency: 1, active: 1) 
    allMessages.append(aMessage) 
    saveMessage(allMessages) 


    return (allMessages.count) 
} 

func archiveMessage(message:[AddMessageViewController.harassText]) -> NSData { 
    let archivedObject = NSKeyedArchiver.archivedDataWithRootObject(message as NSArray) 
    return archivedObject 
} 
func saveMessage(messages: [AddMessageViewController.harassText]) { 
    let archivedObject = archiveMessage(messages) 
    defaults.setObject(archivedObject, forKey: UserDefaultsMesssageKey) 
    defaults.synchronize() 
} 
func retrieveData()-> [AddMessageViewController.harassText]? { 
    if let unarchiveObject = NSUserDefaults.standardUserDefaults().objectForKey(UserDefaultsMesssageKey) as? NSData { 
     return NSKeyedUnarchiver.unarchiveObjectWithData(unarchiveObject) as? [AddMessageViewController.harassText] 
    } 
    return nil 
} 

Die Strömung ist:

  1. Auf saveMessage Aufruf, die benutzerdefinierte Array übergeben werden in archiviert werden. So sieht das Array für GDB aus. Sie können sehen, dass es sich um ein Array handelt, in dem 1 Klassenobjekt enthalten ist.

    ([Harass_Your_Kate.AddMessageViewController.harassText]) $R0 = 1 value { [0] = 0x00007fa5ab409600 { ObjectiveC.NSObject = { isa = Harass_Your_Kate.AddMessageViewController.harassText } phoneNumber = 0 message = "1" frequency = 1 active = 1 } }

  2. Das Array in archiveMessage geben wird. Der Code schlägt sofort bei der NSKeyedArchiver-Methode fehl. Die Fehlermeldung lautet wie folgt:

    [_TtCC16Harass_Your_Kate24AddMessageViewController10harassText encodeWithCoder:]: unrecognized selector sent to instance 0x7fa5ab409600 
    

    2016-07-15 16: 31: 26,019 Harras Ihre Kate [5858: 7.847.495] * - [NSKeyedArchiver dealloc]: Warnung: NSKeyedArchiver freigegeben ohne gehabt zu haben -finishEncoding genannt darauf. 2016.07.15 16: 31: 26,023 Harras Ihre Kate [5858: 7.847.495] * app aufgrund nicht abgefangene Ausnahme 'NSInvalidArgumentException', Grund beenden: ‚- [_ TtCC16Harass_Your_Kate24AddMessageViewController10harassText encodeWithCoder:]: Unbekannter Selektor an Instanz gesendet 0x7fa5ab409600

Ich schätze all die Hilfe, danke im Voraus!

EDIT: Hier ist die Definition meines Objekt:

class Text : NSObject { 
    var phoneNumber = 0    //Text address to send to 
    var message: String = ""  //Message to be sent 
    var frequency = 24    //Number of hours between messages (usually a multiple of 24 - 24 = daily) 
    var active = 0     // 0 if cancelled, 1 if active 

    init(phoneNumber: Int, message: String, frequency: Int, active: Int){ 
     self.phoneNumber = phoneNumber 
     self.message = message 
     self.frequency = frequency 
     self.active = active 
    } 
} 
+2

Wir müssen die NSCoding-Methoden für Ihr benutzerdefiniertes Objekt sehen. ('initWithCoder' und' encodeWithCoder'). –

+0

Ich habe keines dieser Dinge. – Ryan

+1

Das ist dann das Problem. Zeigen Sie uns dann die Definition Ihrer benutzerdefinierten Klasse. (Bearbeiten Sie Ihre Frage, um den Code hinzuzufügen, nicht in einem Kommentar.) –

Antwort

3

NSKeyedArchiver Objekte serialisiert durch die Nutzung von Methoden unter Sie durch konform mit dem NSCoding Protokoll zur Verfügung stellen müssen. Es kann nicht automatisch abgeleitet werden, wie die benutzerdefinierten Klassen gespeichert werden. Sie haben zu implementieren, dass Sie sich wie folgt zusammen:

class Text : NSObject, NSCoding { 
    var phoneNumber = 0    //Text address to send to 
    var message: String = ""  //Message to be sent 
    var frequency = 24    //Number of hours between messages (usually a multiple of 24 - 24 = daily) 
    var active = 0     // 0 if cancelled, 1 if active 

    init(phoneNumber: Int, message: String, frequency: Int, active: Int){ 
     self.phoneNumber = phoneNumber 
     self.message = message 
     self.frequency = frequency 
     self.active = active 
    } 

    required init?(coder aDecoder: NSCoder) { 
     phoneNumber = aDecoder.decodeInteger(forKey: "phoneNumber") 
     message = aDecoder.decodeObject(forKey: "message") as! String 
     frequency = aDecoder.decodeInteger(forKey: "frequency") 
     active = aDecoder.decodeInteger(forKey: "active") 
    } 

    func encode(with aCoder: NSCoder) { 
     aCoder.encode(phoneNumber, forKey: "phoneNumber") 
     aCoder.encode(message, forKey: "message") 
     aCoder.encode(frequency, forKey: "frequency") 
     aCoder.encode(active, forKey: "active") 
    } 
} 

Wie Sie die initializer liest aus dem Codierer sehen und schafft und die Instanz, während die encode Verfahren an den Codierer relevanten Informationen speichert. In einer einfachen Klasse wie dieser mögen ihre Implementierungen offensichtlich erscheinen, aber in einem komplexeren benutzerdefinierten Typ müssen nicht-triviale Codierungsentscheidungen getroffen werden.

+0

Vielen Dank! Das funktioniert großartig. Ich implementiere es auch mit CoreData, die viel einfacher zum Speichern von benutzerdefinierten Informationen scheint – Ryan