How to use List type with Codable? (RealmSwift)

We can use an extension to make List conform to Codable:

extension List : Decodable where Element : Decodable {
    public convenience init(from decoder: Decoder) throws {
        self.init()
        var container = try decoder.unkeyedContainer()
        while !container.isAtEnd {
            let element = try container.decode(Element.self)
            self.append(element)
        }
    } }

extension List : Encodable where Element : Encodable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        for element in self {
            try element.encode(to: container.superEncoder())
        }
    } }

I also got an extension for RealmOptional, if others need.

https://gist.github.com/ansonyao/41137bb3cbbca8ef31a13b6bc96ee422


You are almost there. Inside the initializer, you can initialize the list using the decoded array. Basically, change

tags = try container.decode(List<Tag>.self, forKey: .tags)   // this is problem.

to

let tagsArray = try container.decode([Tag].self, forKey: .tags)   
tags = List(tagsArray) // Now you are good

As pointed out in the comments the List constructor no longer works like this

You now want:

tags.append(objectsIn: tagsArray)

There is only one problem with the accepted answer. Realm specifies that lists should be let(Constants) So to modify the solution to follow best practices you just have to make your list a let and then loop through appending the results to your array.

// Change this Line in [Your Code]
// to a let (Constant)

var tags = List<Tag>() to let tags = List<Tag>()

Then change

tags = try container.decode(List<Tag>.self, forKey: .tags)

to

let tagsArray = try container.decode([Tag].self, forKey: .tags)   
tagsArray.forEach{ tags.append($0) }