2017-10-10 4 views
0

Imaginez ce code:classe entière à Swift Realm en 1 temps ne fonctionnera pas

class StoredVersions: Object{ 
    @objc dynamic var minimumAppVersion = 0.0 
    @objc dynamic var sets = 0.0 
} 
class LoadViewController: UIViewController { 
    let realm = try! Realm() 
override func viewDidLoad() { 
    super.viewDidLoad() 
    let db = Firestore.firestore() 
    var newestVersions = StoredVersions() 
    if let resultsStoredVersion = self.realm.objects(StoredVersions.self).first{ 
     print("found stored versions: \(resultsStoredVersion)") 
     self.storedVersions = resultsStoredVersion 
    }else{ 
     try! self.realm.write { 
      print("no stored versions") 
      self.realm.add(self.storedVersions) 
     } 
    } 

    db.collection("data").document("version").getDocument(completion: { (data, someError) in 
      if let versions = data.flatMap({StoredVersions(value: $0.data()) }) { 
       try! self.realm.write { 
        self.storedVersions = versions 
       } 
      } 
     }) 
} 

storedVersions est mis à jour, mais lorsque je redémarre l'application, storedVersions est de retour à son état initial. Je vois l'impression "versions stockées trouvées".

Si j'écris juste 1 variable à la fois, cela fonctionne. Cela ressemble à ceci:

try! self.realm.write { 
     self.storedVersions.sets = versions.sets 
    } 

Comment puis-je mettre à jour une classe entière sans devoir mettre dans les variables un à la fois?

+0

Pouvez-vous partager un peu plus de contexte, s'il vous plaît? Par exemple, la définition de classe de la classe avec la propriété 'storedVersions', l'entrée que vous fournissez (c'est-à-dire,' data'), et ce que vous attendez du résultat. – bdash

+0

Salut @bdash, j'ai édité ma question pour ajouter un peu plus de contexte, je peux ajouter plus si vous voulez. L'entrée que je fournis et mon résultat attendu est l'impression "devrait être" (une impression de "versions"). Mes "storedVersions" devraient contenir les mêmes valeurs que "versions". –

+0

Pouvez-vous partager la déclaration de classe qui contient le code en cours d'exécution? – bdash

Répondre

1

Lorsque vous faites ceci:

if let versions = data.flatMap({StoredVersions(value: $0.data()) }) { 
    try! self.realm.write { 
     self.storedVersions = versions 
    } 
} 

Vous créez une nouvelle, non géré objet StoredVersions. Vous devez appeler le realm.add(_:) pour l'ajouter au Royaume, sinon l'objet n'existe que dans la mémoire.

Si vous voulez mise à jour l'objet StoredVersions existant plutôt que de créer un nouveau, vous devriez plutôt utiliser Realm.add(_:update:), en spécifiant true pour l'argument de mise à jour. Notez que cela nécessite que votre type possède une propriété de clé primaire déclarée afin que Realm sache quel objet existant mettre à jour.

+0

Merci ça marche. Mais je pense qu'il est très étrange que la mise à jour de la variable 1 fonctionne comme je le souhaite, mais lorsque la mise à jour d'une classe entière nécessite plus de tracas avec des clés et des mises à jour. –

+1

Lorsque vous modifiez les propriétés de 'self.storedVersions', vous modifiez les propriétés d'un objet déjà géré par Realm (vous venez de le récupérer du royaume, après tout). C'est complètement différent de la création d'un nouvel objet, _unmanaged_. – bdash

+0

Ha! Maintenant, je comprends enfin! Merci pour votre temps. –