Swift 4 .plist обработка - PullRequest
       11

Swift 4 .plist обработка

0 голосов
/ 26 июня 2018

У меня есть файл .plist, в котором я буду хранить различные места, которые пользователь позже сможет прочитать / изменить. Но я не могу заставить работать код ...

Мой .plist:

<dict>
    <key>MAIN TITLE</key>
    <array>
        <dict>
            <key>name</key>
            <string>NAME IN TABLECELL</string>
        </dict>
        <dict>
            <key>name</key>
            <string>X</string>
        </dict>
    </array>
</dict>

Я хочу сделать MAIN TITLE заголовком раздела. Мой код:

func readPlist() {
        guard let fileUrl = Bundle.main.url(forResource: "SavedPlaces", withExtension: "plist") else { return }
        do {
            let data = try Data.init(contentsOf: fileUrl)
            let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [[String:Any]]
            print(plist)

        } catch {
            print(error.localizedDescription)
        }
    }

Но это приводит к нескольким ошибкам, среди которых:

Thread 1: signal SIGABRT
Could not cast value of type '__NSCFDictionary' (0x10b39ddd8) to 'NSArray' (0x10b39e008).

Есть ли способ, где я могу получить все значения, без использования NSArray, NSDictionary и т. Д .?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 26 июня 2018

Как уже упоминалось, корневым объектом файла plist является <dict> ionary - который все еще легче идентифицировать, чем в JSON ?

Чтобы избавиться от массива и словаря типов коллекций, используйте протокол Decodable и две пользовательские структуры и PropertyListDecoder.

struct SavedPlaces: Decodable {
    private enum CodingKeys : String, CodingKey { case mainTitle = "MAIN TITLE" }

    let mainTitle : [Title]
}

struct Title: Decodable {
    let name : String
}

func readPlist() {
    let fileUrl = Bundle.main.url(forResource: "SavedPlaces", withExtension: "plist")!
    let data = try! Data(contentsOf: fileUrl)
    let plist = try! PropertyListDecoder().decode(SavedPlaces.self, from: data)
    print(plist.mainTitle)
}

Восклицательные знаки предназначены. Поскольку файл находится в комплекте, он неизменен, и код не должен падать. Если вы допустили ошибку при проектировании.

0 голосов
/ 26 июня 2018

Файл .plist представляет собой словарь, и вы принудительно преобразуете его в массив словаря [[String:Any]]

Замените строку ниже вашего кода:

let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [[String:Any]]

с:

if let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as? [String:Any] {
            print(plist)
}

Использование если разрешено будет дополнительным преимуществом, поскольку оно поможет вам проверить нулевое значение для ответа PropertyListSerialization.

Надеюсь, это поможет!

0 голосов
/ 26 июня 2018

Изменить эту строку

let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [[String:Any]]

до

let plist = try! PropertyListSerialization.propertyList(from:data, options: [], format: nil) as! [String:Any]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...