Swift - кодирует и расшифровывает словарь [String: Any] в plist - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь сохранить словарь в своем классе Marker, но он выдает ошибку о том, что он не кодируется и не декодируется.Я вижу, что ошибка вызвана [String: Any], но как мне обойти это?

var buttonActions : [String: [String: [String:Any]]] = [:]

Сохранить и загрузить

func saveData() {
    let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")

    let encoder = PropertyListEncoder()
    do {
        let data = try encoder.encode(markerArray)
        try data.write(to: dataFilePath!)
        print("Saved")
    } catch {
        print("Error Encoding \(error)")
    }
}

func loadData() {
    let dataFilePath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("\(fileName).plist")

    if let data = try? Data(contentsOf: dataFilePath!){
        let decoder = PropertyListDecoder()
        do {
            markerArray = try decoder.decode([Marker].self, from: data)
        } catch {
            print("Decode Error \(error)")
        }
    }

Класс

class Marker : Encodable, Decodable {
    var UUIDpic: UUID = UUID()
    var alpha: Int = 1
    var buttonType: Int = 0
    var buttonActions : [String: [String: [String:Any]]] = [:]
    var buttonNameColor: String = ""
    var buttonNameFontSize: Int = 10
    var buttonShape: String = ""
    var loggerRect: String = ""
    var maskColor: String = ""
    var name: String = ""
}

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Итак, наконец-то все получилось с помощью Андрады.

Я добавил вторую структуру, которая содержала действие, и передал необходимость использовать [string: any]

class Marker : Encodable, Decodable {
var UUIDpic: UUID = UUID()
var alpha: Int = 1
var buttonType: Int = 0
var buttonAction : [String: [ButtonAction]] = [:] //Dictionary I edited using the new struct
var buttonNameColor: String = ""
var buttonNameFontSize: Int = 10
var buttonShape: String = ""
var loggerRect: String = ""
var maskColor: String = ""
var name: String = ""
}

Нижеэто структура, которую я добавил

struct ButtonAction: Codable {
var action: String
var array_linked_of_buttons: [[String:String]]

init(action: String, array_linked_of_buttons: [[String:String]]) {
 self.action = action
 self.array_linked_of_buttons = array_linked_of_buttons
    }
}

Убедитесь, что инициализировали свою структуру, иначе она не будет работать.

0 голосов
/ 03 декабря 2018

К сожалению, вы не можете использовать encode или decode для универсальных типов, содержащих Any (например, [String: Any] или [Any]).Any не соответствует протоколам Encodable и Decodable, и Swift не знает, как его кодировать / декодировать.Вы должны использовать конкретный универсальный тип для своего словаря (например, [String: String]).

Если вам все еще нужно использовать общий тип, такой как Any, вам необходимо реализовать методы encode(to:) и init(from:).Другой вариант - использовать struct вместо вашего [String: [String: [String:Any]]], что соответствует Codable (Encodable & Decodable).Вам все равно придется реализовать методы encode(to:) и init(from:) в этой структуре, но яркая сторона заключается в том, что вам не нужно будет писать историю encoder.encode() для всех свойств, как если бы вы реализовали их вMarker класс.

...