2016-06-04 7 views
0


Ich bin neu zu swift, und ich versuche ein Spiel zu bauen, das einen Top 5 Spieler Namen und Punktzahl enthält, wenn ich nur die Spieler zu einem Array hinzufügen und neu starten das Spiel es „löscht“ die Spieler, so versuche ich, NSUserDefaults zu verwenden (i nur 5 Saiten und 5 ganze Zahlen speichern müssen), ist es nicht funktionieren, egal was, der Code:Verwenden von NSUserDefaults, um ein Array von Objekten zu speichern

class scoreController: UITableViewController { 

    var playersArray:[Player] = [Player]() 

    var nameFromGame = "" //name from game vc 
    var timeFromGame = 0 //time from game vc 

    let tmpPlayer = Player(playerName: "", scoreTime: 0) 
    let playerDefaults = NSUserDefaults.standardUserDefaults() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let player1 = Player(playerName: "Bil", scoreTime: 50) 
     let player2 = Player(playerName: "Bob", scoreTime: 100) 


     playersArray.append(player1) 
     playersArray.append(player2) 

     tmpPlayer.playerName = nameFromGame 
     tmpPlayer.scoreTime = timeFromGame 
     playersArray.append(tmpPlayer) 

     playerDefaults.setObject(playersArray[11], forKey: "players") 

      print(playersArray) 
     } 
    } 

I Ich versuche nur, das für jetzt zu speichern und es stürzt ab, weiß jemand warum? Und wie kann ich das in meiner App speichern, damit die Daten gespeichert werden?

danke!

Antwort

1

Players Klasse NSCoding entsprechen muss, und Sie werden eine archivierten Daten Ihrer Spieler-Array und unarchive es speichern müssen, wenn die Daten zu extrahieren aus.

Klasse:

class Player: NSObject, NSCoding { 
    var playerName: String 
    var scoreTime: Int 

    init(playerName: String, scoreTime: Int) { 
     self.playerName = playerName 
     self.scoreTime = scoreTime 
    } 

    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeInteger(scoreTime, forKey: "score_time") 
     aCoder.encodeObject(playerName, forKey: "player_name") 
    } 

    required convenience init?(coder decoder: NSCoder) { 
     guard let playerName = decoder.decodeObjectForKey("player_name") as? String else { 
      return nil 
     } 
     self.init(playerName: playerName, scoreTime: decoder.decodeIntegerForKey("score_time")) 
    } 
} 

NSUserDefaults & Archivierung/Aufheben der Archivierung:

let player1 = Player(playerName: "Bil", scoreTime: 50) 
    let player2 = Player(playerName: "Bob", scoreTime: 100) 

    let playersArray = [player1, player2] 
    let playersData = NSKeyedArchiver.archivedDataWithRootObject(playersArray) 

    let defaults = NSUserDefaults.standardUserDefaults() 
    defaults.setObject(playersData, forKey: "players") 
    defaults.synchronize() 

    if let playersArrayData = defaults.objectForKey("players") as? NSData { 
     let unarchivedPlayers = NSKeyedUnarchiver.unarchiveObjectWithData(playersArrayData) as! [Player] 
     print(unarchivedPlayers) 
    } 

hoffe, das hilft, denken Sie bitte daran Antwort und up-Abstimmung zu wählen, wenn diese Frage löst. i

0

Sie Notwendigkeit nennen könnte

playerDefaults.synchronize() 

die Daten in den Standardeinstellungen zu speichern.

BEARBEITEN
Wie facumenzella sagt, Ihr anderes Problem speichert benutzerdefinierte Klassenobjekte in den Standardeinstellungen. Um das zu lösen, müssen Sie Methoden in der benutzerdefinierten Player-Klasse implementieren, die angeben, wie in Daten konvertiert werden soll. Dann sollten Sie das Objekt serialisieren, bevor Sie es in den Standardeinstellungen speichern.

+0

versucht, dass es sagt: erwartete Erklärung – Coder123

+0

Nein, die Sie nicht brauchen, das Verfahren in regelmäßigen Abständen durch das Betriebssystem aufgerufen wird. – vadian

+0

Wenn er jedoch wird die Standardwerte bald nach dem Setzen sie den Zugriff, sollte er nach dem Wechsel synchronisieren. Außerdem gibt es immer die Chance, dass der App zum Absturz bringen könnte oder durch den Benutzer gestoppt werden, wobei in diesem Fall einer Zeit-Synchronisation nicht auftreten kann. – milesper

2

Ihre Spieler Objekte sind wahrscheinlich das Problem hier. Sie müssen zwei Methoden in Ihrer Player-Klasse implementieren (ich bin kein geschickter Meister, aber es ist wahrscheinlich das die gleichen Fehler):

- (void)encodeWithCoder:(NSCoder *)encoder; 
- (id)initWithCoder:(NSCoder *)decoder; 

, die für Sie arbeiten soll. Hoffe es hilft !!

PD: überprüfen Sie diese Antwort How to store custom objects in NSUserDefaults

+0

Ich denke, die sind objektiv c Methoden .. wissen Sie, die schnellen welche? Hier – Coder123

+1

... https: //developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSCoding_Protocol/#//apple_ref/occ/intfm/NSCoding/encodeWithCoder: Hoffe, es hilft !! – facumenzella

Verwandte Themen