Search code examples
iosarraysswiftrealm

Add arrays to Realm with swift 3


I'm new in Realm and I tried to add an Array as I did with strings and I ended up with some errors. So after a little search I found out a 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 = ""
}

This is working very good, now I want to add another array inside this class. If someone knows any other ways to add arrays with realm please share it.

Thanks in advance


Solution

  • As a general rule it's way more efficient to use the one-to-many relationships provided by Realm instead of trying to emulate them by using arrays (Realm's collections are lazy, the objects contained are instantiated only when needed as opposed to plain Swift arrays).

    In your case, if I understand correctly what you're trying to do, you want to add [RealmString] Swift arrays to the _backingNickNames list.

    Why not use the append(objectsIn:) method of Realm's List class (see here), like this:

    // 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])
    

    If you want to do the opposite (convert from a List to an Array) just do :

    let dogsArray = Array(jim.dogs)
    

    • • • • • • • •

    Back to your own posted solution, you could easily refactor the model to accommodate this. Each Sensor object could have several Topic and several Message objects attached.

    Just ditch the message and topic computed properties and rename topicV and messageV to topics and messages respectively. Also rename RealmString to Topic and RealmString1 to Message.

    Now, you could easily iterate through the, say, topics attached to a sensor like this :

    for topic in sensor1.topics { ... }
    

    Or if you want to attach a message to a sensor you could do something like this (don't forget to properly add the newly created object to the DB first):

    let message1 = Message()
    message1.stringValue = "Some text"
    
    sensor2.messages.append(message1)
    

    So, no need to use intermediary Swift Arrays.