Swift Codable протокол со строками и UIImages - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь сохранить данные через кодируемый протокол. Это массив структур со структурами внутри. Есть строки, изображения и значения bool, и я думаю, что это один из этих типов данных, который не соответствует протоколу.

Вот фотография всех данных, которые я должен сохранить: оригинал

struct Checklist {

    var name: String
    var image: UIImage?
    var items: [Item] = []
}

struct Item {

    var nameOfNote: String
    var remind: Bool
    //var date: Date
}

struct alldata: Codable {

    var checklists: [Checklist] = []
}

Я попытался включить протокол во все структуры, но он также выдал ошибку. Вот картинка: попробовал решение фото

1 Ответ

0 голосов
/ 12 ноября 2018

JSON в Swift 4 - это весело (повторите это в 2 часа ночи;)).

Первым делом я всегда обращаюсь к хорошему блогу, например Окончательное руководство по синтаксическому анализу JSON с помощью Swift 4 . Хотя он может и не ответить на «прямой» вопрос, он предоставит много полезной информации.

Еще одна вещь, которую нужно сделать, это обратиться к документации Apple. При этом быстрый просмотр документации для UIImage покажет, что она не соответствует Codable, так что это проблема.

Другая проблема заключается в том, что JSON не поддерживает двоичные данные, это текстовое решение.

Это означает, что вам нужно разобраться, чтобы преобразовать двоичные данные изображения в текст. К счастью для нас, люди уже подумали об этом, и самый распространенный механизм - это использование кодировки Base 64.

Быстрый поиск в Google найдет любое количество решений для кодирования / декодирования UIImage в / из базы 64, например Преобразование между UIImage и строкой Base64

Теперь нам просто нужно настроить процесс кодирования и декодирования.

Прежде всего убедитесь, что все остальные поля / объекты / данные, которые мы используем, также соответствуют Codable ...

struct Item: Codable {
    var nameOfNote: String
    var remind: Bool
    //var date: Date
}

Затем мы можем настроить процесс кодирования и декодирования изображения, может быть, что-то вроде ...

struct Checklist: Codable {

    enum CodingKeys: String, CodingKey {
        case image
        case name
        case items
    }

    var name: String
    var image: UIImage?
    var items: [Item] = []

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        name = try container.decode(String.self, forKey: .name)
        items = try container.decode([Item].self, forKey: .items)

        if let text = try container.decodeIfPresent(String.self, forKey: .image) {
            if let data = Data(base64Encoded: text) {
                image = UIImage(data: data)
            }
        }
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)

        if let image = image, let data = image.pngData() {
            try container.encode(data, forKey: .image)
        }
        try container.encode(name, forKey: .name)
        try container.encode(items, forKey: .items)
    }
}

nb: Это основной процесс, который я использовал для нескольких проектов, я сам не проверял вышеизложенное, но он должен представлять основную идею, необходимую для начала работы

...