'Optional list of NSData in Realm - Swift

I need to save a list of images as NSData in Realm. I tried using Realm optional but realmOptional<NSdata> can't be used because realmOptional does not conform to type NSDate.
Is there a way to do it?

Edit: Basically all I want is to be able to store a list of NSData but optional something like:

@objc dynamic var photos: List<NSData>?


Solution 1:[1]

The List cannot be optional, but the Objects in the list can be optional, you have to declare it like:

@Persisted var value: List<Type?>

Here is the link with the Supported data types https://www.mongodb.com/docs/realm/sdk/swift/data-types/supported-property-types/

Solution 2:[2]

according to https://realm.io/docs/swift/latest/#property-cheatsheet you can not define optional lists in realm

Solution 3:[3]

Solution for optional List types when using Decodable

In my case I needed an optional List because I'm decoding json into Realm objects, and it's possible that the property might not exist in the json data. The typical workaround is to manually decode and use decodeIfPresent(). This isn't ideal because it requires boilerplate code in the model:

class Driver: Object, Decodable {
    var vehicles = List<Vehicle>()
    var name: String = ""
    // etc

    public required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.vehicles = try container.decodeIfPresent(List<Vehicle>.self, forKey: .vehicles) ?? List<Vehicle>()
        self.name = try container.decode(String.self, forKey: .name)
        // etc
    }
}

However, we can avoid the boilerplate by extending KeyedDecodingContainer with an overload for List types. This will force all lists to be decoded using decodeIfPresent():

  • Realm v5:

    class Driver: Object, Decodable {
        var vehicles = List<Vehicle>()
        var name: String = ""
        //etc
    }
    
    class Vehicle: Object, Decodable {
        var drivers = List<Driver>()
        var make: String = ""
        // etc
    }
    
    extension KeyedDecodingContainer {
        // This will be called when any List<> is decoded
        func decode<T: Decodable>(_ type: List<T>.Type, forKey key: Key) throws -> List<T> {
          // Use decode if present, falling back to an empty list
            try decodeIfPresent(type, forKey: key) ?? List<T>()
        }
    }
    
  • Realm v10+:

    class Driver: Object, Decodable {
        @Persisted var vehicles: List<Vehicle>
        @Persisted var name: String = ""
        // etc
    }
    
    class Vehicle: Object, Decodable {
        @Persisted var drivers: List<Driver>
        @Persisted var make: String = ""
        // etc
    }
    
    extension KeyedDecodingContainer {
        // This will be called when any @Persisted List<> is decoded
        func decode<T: Decodable>(_ type: Persisted<List<T>>.Type, forKey key: Key) throws -> Persisted<List<T>> {
            // Use decode if present, falling back to an empty list
            try decodeIfPresent(type, forKey: key) ?? Persisted<List<T>>(wrappedValue: List<T>())
        }
    }
    

Edit: Clarified code examples, fixed typo

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Johana Lopez 1327
Solution 2 omid
Solution 3