Следующая статья поможет вам: Как: Работа с Plist в Swift
Вернуться в блог
Список свойств, обычно называемый plist, представляет собой XML-файл, содержащий основные данные о ключах и значениях. Вы можете использовать список в своих приложениях iOS как простое хранилище данных «ключ-значение». Давайте узнаем, как это работает!
В этом руководстве по разработке приложений мы углубимся в:
- Что такое список свойств и как его использовать
- Как читать и писать в список свойств
- Что такое Info.plist и почему он полезен
- Как кодировать и декодировать списки свойств с помощью Codable
Список свойств, или plist, — это XML-файл, содержащий данные «ключ-значение». Проще всего сравнивать со словарем в Swift, так как это список значений, связанных с ключами. Вот пример:
На скриншоте выше вы видите файл списка свойств Fruit.plist. Он имеет массив верхнего уровня с несколькими элементами типа String. Вот тот же файл, но в формате XML:
Апельсин
Ананас
Малина
Банан
Груша
Apple
В Xcode вы можете увидеть XML-структуру списка, щелкнув правой кнопкой мыши файл .plist и выбрав «Открыть как» → «Исходный код».
Если присмотреться, можно заметить различные значения и структуры в XML. Вот краткий обзор сверху вниз:
- Строки , и представляют собой шаблонный код, который предоставляет информацию о самом XML. Типичный XML-файл имеет так называемый DTD, который содержит информацию о структуре XML.
- Тег верхнего уровня оборачивает в него элементы массива. Каждый элемент XML имеет открывающий тег с форматом и закрывающий тег с форматом.
- Внутри массива вы видите 6 тегов. Массив содержит несколько названий фруктов в виде строк.
Элемент верхнего уровня списка, называемый корнем, всегда является массивом или словарем.
Список свойств может содержать элементы нескольких типов, включая массивы, словари, логические значения, даты, данные и числа, например целые числа. Каждый из этих типов соответствует собственным типам Swift, таким как Array и Bool. Вы также можете вкладывать массивы и словари, т. е. добавлять массив внутрь другого массива и т. д., чтобы создавать более сложные структуры данных.
Пары ключ-значение словаря в списках не заключены в элемент-контейнер. Вместо этого они пишутся в двух отдельных строках. Так:
Вам не нужно редактировать список свойств в формате XML. Вот что в них такого удобного! Просто откройте их с помощью редактора списка свойств, выбрав «Открыть как» → «Список свойств», и напрямую редактируйте строки.
Общим списком свойств в проектах iOS является файл Info.plist. Этот список содержит информацию о вашем проекте iOS. Он распространяется как часть двоичного пакета вашего приложения, и iOS использует его, например, для отображения имени вашего приложения на главном экране iPhone.
Видите, сколько информации о вашем приложении содержится в Info.plist? При создании приложения иногда приходится добавлять дополнительную информацию в этот список свойств. Например, если вашему приложению требуется доступ к библиотеке фотографий iPhone, список приложений должен содержать ключ, объясняющий причину доступа к библиотеке фотографий.
Вы можете редактировать список свойств следующим образом:
- Чтобы добавить новую строку, щелкните правой кнопкой мыши редактор и выберите «Добавить строку».
- Чтобы изменить тип значения, нажмите кнопку выбора для строки в столбце «Тип».
- Чтобы изменить значение строки, дважды щелкните значение строки в столбце «Значение».
- Чтобы удалить строку, выделите ее и нажмите клавишу Backspace.
Некоторые списки свойств будут использовать собственный формат, например Info.plist. Если список свойств имеет собственный формат, вы не можете просто добавить к нему какое-либо значение. Например, файл Info.plist может содержать только элементы словаря с предустановленными ключами.
Давайте перейдем к тому, чтобы узнать, как можно использовать списки свойств в Swift.
Списки свойств идеально подходят для сохранения простых статических данных «ключ-значение» в вашем приложении. Вот как вы можете прочитать plist с помощью Swift:
func getPlist(withName name: String) -> [String]?
{
если пусть путь = Bundle.main.path(forResource: name, ofType: «plist»),
пусть xml = FileManager.default.contents(atPath: путь)
{
return (попробуйте? PropertyListSerialization.propertyList(from: xml, options: .mutableContainersAndLeaves, формат: ноль)) как? [String]
}
вернуть ноль
}
Вот как мы можем использовать вышеуказанную функцию:
if let Fruits = getPlist(withName: «Fruit») {
print(фрукты) // Вывод: [“Orange”, “Pineapple”, “Raspberry”, ]
}
Что происходит в коде?
- Во-первых, мы используем необязательную привязку, чтобы получить путь к файлу Fruit.plist и считывать данные из этого файла в константу xml. Если какая-либо из этих двух строк завершится неудачно, путь или xml будут равны нулю, и условие не будет выполнено.
- Затем внутри условия мы десериализуем данные из XML в виде списка свойств. Список свойств возвращается в виде массива, но нам придется привести его к [String] потому что propertyList(from:options:format:) возвращает Any.
- Если условие не выполнено, или приведение типа не выполнено, или вызов propertyList(from:options:format:) выдает ошибку, функция возвращает ноль. В противном случае он возвращает массив типа [String]?, поэтому, когда мы вызываем getPlist(withName:), мы снова используем необязательную привязку, чтобы получить необязательные плоды массива.
Важно отметить, что тип фруктов и тип возвращаемого значения getPlist(withName:) имеют тот же тип, что и данные в нашем plist. Plist содержит массив строк, поэтому тип фруктов также указывается. [String]. Вы всегда захотите использовать максимально строгий тип, например [String: Any].
Предупреждение: Для простоты: в приведенном выше коде нет обработки ошибок. Он просто заглушит ошибки и вернет ноль. Это плохая практика в производственных приложениях. Вам понадобится включить код обработки ошибок в случае, если путь к файлу не существует или если plist недействителен и возникает ошибка.
Предыдущий подход к чтению списка свойств далек от идеала. Он слишком многословен и не использует строгую проверку типов. Любое изменение в структуре plist потенциально может привести к поломке вашего кода.
Начиная с iOS 11, вы можете использовать протокол Codable для прямого декодирования различных типов данных, таких как JSON, в собственные классы и структуры Swift. И вы также можете использовать Codable со списками!
Вот Preferences.plist, который мы будем использовать:
Он содержит несколько простых пользовательских настроек для нашего приложения, аналогичных тем, которые вы указали в UserDefaults.
Теперь нам нужна структура Preferences, соответствующая протоколу Codable. Так:
Предпочтения структуры: Кодируемый {
вар вебсервисURL:String
вар itemsPerPage:Int
вар резервное копированиеEnabled:Bool
}
Важно, чтобы свойства структур точно соответствовали ключам в словаре plist. Обратите внимание, что мы используем протокол Codable.
Структура Preferences содержит произвольную информацию о резервных копиях, URL-адресе веб-сервиса и количестве элементов, которые мы хотим отображать на странице. Конечно, вы можете поместить что угодно в свой собственный список.
Теперь мы превратим файл Preferences.plist в экземпляр структуры Preferences. В этом сила Codable! Вот как:
если let path = Bundle.main.path(forResource: «Preferences», ofType: «plist»),
пусть xml = FileManager.default.contents(atPath: путь),
пусть предпочтения = попробую? PropertyListDecoder().decode(Preferences.self, from: xml)
{
печать (preferences.webserviceURL)
}
Мы используем тот же шаблонный код, что и раньше. Сначала мы получаем путь к списку, затем получаем данные из файла и присваиваем их XML.
Эта строка является наиболее актуальной:
пусть предпочтения = попробую? PropertyListDecoder().decode(Preferences.self, from: xml)
При вызове функции decode(_:from:) в экземпляре PropertyListDecoder() файл списка свойств декодируется в экземпляр Preferences. Мы указываем декодеру использовать эту структуру с первым аргументом Preferences.self. Для декодирования и кодирования списка свойств используется тот же синтаксис, что и для декодирования/кодирования JSON, но используется другой экземпляр декодера.
Когда декодирование завершится успешно, мы сможем использовать объект настроек как любой другой обычный тип Swift:
печать (preferences.webserviceURL)
Потрясающий!
Важный: Опять же, мы скрываем любые ошибки. Убедитесь, что вы правильно обрабатываете ошибки в своих приложениях.
Можете ли вы также записать словарь или массив обратно в файл списка свойств? Конечно! Допустим, у пользователя еще нет списка свойств Preferences, поэтому мы создадим для него значение по умолчанию. Вот как:
пусть предпочтения = Настройки (webserviceURL: «https://api.twitter.com», itemsPerPage: 10, backupEnabled: false)
С помощью приведенного выше кода мы создаем новый экземпляр Preferences, который еще не сохранен как список свойств. И вот как мы его сохраняем:
пусть кодировщик = PropertyListEncoder()
кодировщик.outputFormat = .xml
let path = FileManager.default.urls (для: .documentDirectory, в: .userDomainMask)[0].appendingPathComponent(“Preferences.plist”)
делать {
пусть данные = попробуйте encoder.encode(предпочтения)
попробуйте data.write(to: путь)
} ловить {
печать (ошибка)
}
Вот что происходит в приведенном выше коде:
- Сначала мы создаем объект PropertyListEncoder и устанавливаем выходной формат .xml. (Другие варианты — .binary и древний .openStep.)
- Затем мы создаем объект URL со ссылкой на файл Preferences.plist в каталоге документов приложения. Это каталог в контейнере приложения, в который нам разрешено помещать файлы.
- Затем в блоке do-try-catch мы сначала используем кодировщик для кодирования объекта предпочтений в объект данных. После этого мы просто записываем данные в файл, на который указывает путь.
Очень просто! Кодировщик преобразует объект Preferences в данные, использующие формат списка свойств XML, и записывает их в файл. А позже мы можем прочитать тот же URL-адрес файла, чтобы снова получить объект Preferences.
В iOS SDK есть несколько полезных компонентов для кодирования и декодирования форматов данных, таких как PropertyListEncoder, NSKeyedArchiver, NSCoding и JSONEncoder. Их стоит проверить!
И это все, что нужно! Списки свойств полезны для чтения и записи пользовательских настроек в файл, и их легко редактировать в Xcode.
Быстрая подсказка: В MacOS есть инструмент командной строки plutil, который можно использовать для редактирования списков свойств. Введите plutil -help в терминале, чтобы узнать, как его использовать.