SwiftUI добавляет соответствие Codable для свойств @Published с использованием свойства id - PullRequest
0 голосов
/ 08 мая 2020

Я только начинаю изучать SwiftUI. Где я go не прав? Я пытаюсь добавить соответствие Codable в свой класс (ManyItems). Таким образом, я в конечном итоге могу сохранить массив на диск, используя JSON. Две ошибки:

1) В обоих случаях "required init (...)" id = try ... "и encode fun c:" try container.encode ... "приводят к "'id' недоступен в Swift: 'id' недоступен в Swift; используйте 'Any' "

2) В обоих требуемых init (...) и fun c encode: " Использование неразрешенного идентификатора 'one'. " I предполагается, что идентификатор в структуре будет перенесен в класс?

struct Item: Identifiable {
    var id = UUID()
    var one: String
}

class ManyItems: ObservableObject, Codable {
    @Published var manyitems = [Item]()
    enum CodingKeys: CodingKey {
        case id
        case one
    }
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decode(UUID.self, forKey: .id)
        one = try container.decode(String.self, forKey: .one)
    }
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encode(one, forKey: .one)
    }
}

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Ваши модели Codable должны быть:

struct Item: Codable, Identifiable {
    var id = UUID()
    var one: String
}

class ManyItems: Codable, ObservableObject {
    @Published var manyitems = [Item]()
}

Как видно из вашего кода, вы не обрабатываете какие-либо специфические c случаи синтаксического анализа. Таким образом, нет необходимости явно реализовывать методы init(from:) и encode(to:).

0 голосов
/ 12 мая 2020

Я нашел решение, но мне пришлось пойти по другому пути. Надеюсь, это поможет кому-то еще, кому нужно использовать коллекцию, соответствующую Codable и ObservableObject, для сохранения в Apps documentDirectory.

Я согласовал структуру 'Item' с Codable (то есть не с классом 'ManyItem'). Я добавил код для кодирования JSON и сохранения коллекции в каталог документов приложений. Это происходит автоматически c при изменении значения свойства. Класс инициируется либо путем чтения / декодирования файла JSON из каталога документов приложений, либо как новый пустой экземпляр, если файл JSON еще недоступен.

struct Item: Identifiable, Codable {
    var id = UUID()
    var one: String    
}

class ManyItems: ObservableObject {
    @Published var manyitems: [Item] {
        didSet {
            // Saves the array 'items' to disc
            do {
                // find the documentDirectory and create an URL for the JSON
                file
                let filename = getDocumentsDirectory().appendingPathComponent("manyitems.json")
            let data = try JSONEncoder().encode(self.manyitems)
            try data.write(to: filename, options: [.atomicWrite])
        } catch {
            print("Unable to save data.")
        }
    }
}
init() {
    // replaces a call to 'getDocumentsDirectory()' methode as it created an initialisation error.
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    // Add the first [0] path to the filename and create 'filename'
    let filename = paths[0].appendingPathComponent("manyitems.json")
    //print(filename)
    do {
        // Try to read the file (if it exist) and load the data into the array 'manyitem'
        let data = try Data(contentsOf: filename)
        manyitems = try JSONDecoder().decode([Item].self, from: data)
        // Yes all good then exit
        return
    } catch {
        // Something whent wrong. Initialize by creating an empty array 'manyitems'
        self.manyitems = []
        print("Unable to load saved data.")
    }
}
// retreives the App's first DocumentDirectory
func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    return paths[0]
}

}

...