2016-03-30 18 views
3

Ich habe gerade eine App im App Store veröffentlicht und einer meiner Kunden ließ mich wissen, dass ich den Datentyp, den ich zuvor als Integer mit dem NSKeyedArchiver gespeichert hatte, ändern sollte Doppelt.So konvertieren NSKeyedArchiver Objekte über neue Versionen

Einfach genug, um das Datenmodell der App zu ändern, aber wenn ich die App auf meinem Testgerät neu lade, will der NSKeyedUnarchiver offensichtlich keine Integer als Double dekodieren und löst eine NSInvalidUnarchiveOperation Exception aus.

Ich frage mich, wie andere iOS Devs mit dieser Situation umgehen würde. Ich würde es hassen, alle zuvor gespeicherten Daten meiner Benutzer zu löschen, aber das ist die einzige Lösung, die ich sehe.

Mein Code ist unten veröffentlicht. Ich habe ein paar Lösungen kommentierte heraus, dass ich ohne Erfolg versucht

required convenience init?(coder aDecoder: NSCoder){ 

     func decodeDoubles(coder aDecoder: NSCoder) throws-> (Double, Double){ 
      print("Getting in here") 
      /* These are stored as Integers in previous version */ 
      let myEarned = aDecoder.decodeDoubleForKey(PropertyKey.earnedKey) 
      let myTotal = aDecoder.decodeDoubleForKey(PropertyKey.totalKey) 

      /* App Crashes here - exception not caught */ 
      print("After decode attempt") 
      return (myEarned, myTotal) 
     } 

     let myID = aDecoder.decodeIntegerForKey(PropertyKey.idKey) 
     let myName = aDecoder.decodeObjectForKey(PropertyKey.nameKey) as! String 
     let myWeight = aDecoder.decodeIntegerForKey(PropertyKey.weightKey) 
      /* Throws exception */ 
      //let myEarned = aDecoder.decodeDoubleForKey(PropertyKey.earnedKey) 
      //let myTotal = try! aDecoder.decodeDoubleForKey(PropertyKey.totalKey) 


     var myEarned: Double = 0 
     var myTotal: Double = 0 

     do { 
      (myEarned, myTotal) = try decodeDoubles(coder: aDecoder) 
     } catch { 
      print("Exception caught - \(error)") 
      myEarned = Double(aDecoder.decodeIntegerForKey(PropertyKey.earnedKey)) 
      myTotal = Double(aDecoder.decodeIntegerForKey(PropertyKey.totalKey)) 
    } 

     self.init(id: myID, name: myName, weight: myWeight, earned: myEarned, total: myTotal) 
    } 

Antwort

3

Sie könnten eine Funktion vornehmen müssen Art, um das Archiv zu aktualisieren, wie die App geladen wird, im Schlüssel als Integer lesen und schreiben es Zurück als Doppel, dann kann der Rest Ihrer App es normalerweise als Doppel lesen und schreiben. Sie benötigen einen neuen Schlüssel, um zu kennzeichnen, dass Sie das Upgrade durchgeführt haben, damit Sie es nicht erneut tun, und tun Sie es nicht für neue Benutzer.

+0

So würde ich es machen. –

+0

Das ist eine großartige Idee! Ich dachte darüber nach, wusste aber nicht genau, wo ich die Flagge speichern könnte, um zu vermeiden, dass ich das gleiche Problem habe, wenn ich versuche, eine Integer als Doppel zu dekodieren. Ich denke, dass ich versuche, einen Wert zu NSUserDefaults zu speichern oder dem NSKeyedArchiver einen Markierungswert hinzuzufügen. Irgendwelche Vorschläge? – Louie4

+0

das Speichern der Flagge zu NSUserDefaults ist wahrscheinlich einfacher. auch nur versuchen/fangen in der Funktion, so dass, wenn es nicht in der Ganzzahl lesen kann, wird es einen neuen Benutzer annehmen und markieren Sie die Flagge, so dass es nicht versuchen wird, es erneut zu tun (oder der Wert ist irgendwie nicht vorhanden und muss nicht sowieso aktualisiert werden) – Fonix