web-dev-qa-db-fra.com

Ajouter des tableaux au Royaume avec Swift 3

Je suis nouveau dans Realm et j'ai essayé d'ajouter un tableau comme je l'ai fait avec des chaînes et j'ai fini par avoir quelques erreurs. Après quelques recherches, j'ai trouvé une solution:

class Sensors : Object {


    dynamic var name = ""
    dynamic var message = ""

    var topic: [String] {
        get {
            return _backingNickNames.map { $0.stringValue }
        }
        set {
            _backingNickNames.removeAll()
            _backingNickNames.append(objectsIn: newValue.map({ RealmString(value: [$0]) }))
        }
    }
    let _backingNickNames = List<RealmString>()

    override static func ignoredProperties() -> [String] {
        return ["topic"]
    }




}

class RealmString: Object {
    dynamic var stringValue = ""
}

Cela fonctionne très bien, maintenant je veux ajouter un autre tableau à l'intérieur de cette classe . Si quelqu'un connaît d'autres moyens d'ajouter des tableaux avec un royaume, merci de le partager.

Merci d'avance

7
mike vorisis

En règle générale, il est beaucoup plus efficace d'utiliser les relations un-à-plusieurs fournies par Realm au lieu d'essayer de les émuler en utilisant des tableaux (les collections de Realm sont paresseuses, les objets qu'il contient ne sont instanciés que lorsque cela est nécessaire, par opposition aux tableaux plain Swift) .

Dans votre cas, si je comprends bien ce que vous essayez de faire, vous souhaitez ajouter des tableaux [RealmString] Swift à la liste _backingNickNames

Pourquoi ne pas utiliser la méthode append(objectsIn:) de la classe List de Realm (voir ici ), comme ceci:

// Dog model
class Dog: Object {
    dynamic var name = ""
    dynamic var owner: Person?
}

// Person model
class Person: Object {
    dynamic var name = ""
    dynamic var birthdate = NSDate(timeIntervalSince1970: 1)

    let dogs = List<Dog>()
}

let jim = Person()

let dog1 = Dog()
let dog2 = Dog()

// here is where the magic happens
jim.dogs.append(objectsIn: [dog1, dog2])

Si vous voulez faire le contraire (convertir une liste en un tableau), faites simplement: 

let dogsArray = Array(jim.dogs)

• • • • • • • • 

De retour à votre propre solution postée , vous pourrez facilement refactoriser le modèle pour l'adapter à cela. Chaque objet Sensor peut avoir plusieurs objets Topic et plusieurs objets Message attachés.

Supprimez simplement les propriétés calculées message et topic et renommez topicV et messageV en topics et messages respectivement. Renommez également RealmString en Topic et RealmString1 en Message.

Maintenant, vous pouvez facilement parcourir les sujets liés, par exemple, à un capteur, comme ceci:

for topic in sensor1.topics { ... }

Ou, si vous souhaitez attacher un message à un capteur, vous pouvez procéder comme suit (n'oubliez pas de commencer par ajouter correctement l'objet nouvellement créé dans la base de données): 

let message1 = Message()
message1.stringValue = "Some text"

sensor2.messages.append(message1)

Donc, pas besoin d'utiliser des tableaux Swift intermédiaires.

14
Bogdan Farca

Après avoir testé, j'ai réussi à ajouter un autre tableau comme celui-ci:

class Sensors : Object {


    dynamic var type = ""
    dynamic var name = ""
    dynamic var badge = 0

    var topic: [String] {
        get {
            return topicV.map { $0.stringValue }
        }
        set {
            topicV.removeAll()
            topicV.append(objectsIn: newValue.map({ RealmString(value: [$0]) }))
        }
    }

    var message: [String] {
        get {
            return messageV.map { $0.stringValue1 }
        }
        set {
            messageV.removeAll()
            messageV.append(objectsIn: newValue.map({ RealmString1(value: [$0]) }))
        }
    }





    let topicV = List<RealmString>()
    let messageV = List<RealmString1>()

    override static func ignoredProperties() -> [String] {
        return ["topic", "message"]
    }




}

class RealmString: Object {
    dynamic var stringValue = ""
}

class RealmString1: Object {
    dynamic var stringValue1 = ""
}
2
mike vorisis

Ce que Bogdanf a dit et la manière dont vous l'avez mis en œuvre sont corrects.

Outre les types de valeur de base, Realm ne peut stocker que les références à des objets Realm Object singuliers, ainsi que des tableaux de Objects utilisant le type List. En tant que tel, si vous souhaitez enregistrer un tableau de types, il est nécessaire d'encapsuler tous les types de base que vous souhaitez enregistrer (comme un String ici) dans un royaume commode Object.

Comme l'a dit bogdanf, il n'est pas recommandé de convertir Realm Lists aux baies Swift standard, car vous perdez les avantages des fonctionnalités de chargement paresseux de Realm (qui peuvent entraîner des problèmes de performances et de mémoire), mais vous pouvez au moins atténuer les problèmes de mémoire. enfermant le code copiant les données hors du royaume dans un bloc @autoreleasepool.

class MyObject: Object {
    dynamic var childObject: MyObject?
    let objectList = List<MyObject>()
}

En résumé, il est donc recommandé de travailler directement avec les objets de domaine List chaque fois que cela est possible et d’utiliser @autoreleasepool chaque fois que vous souhaitez réellement parcourir tous les objets enfants d’un royaume. :)

0
TiM