Tehnografi.com - Технологические новости, обзоры и советы

Как: Работа с Plist в Swift

Следующая статья поможет вам: Как: Работа с 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 в терминале, чтобы узнать, как его использовать.