'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 |
