В этой статье я расскажу о трех простых способах передачи различной информации из основного таргета приложения в таргет виджетов на примерах с кодом. Так или иначе, но в виджеты необходимо передавать информацию из основного приложения. Это может быть все что угодно: от выбранного пользователем формата времени до полученных писем в почтовом клиенте. В этой статье я расскажу об основных способах передачи данных между таргетами приложения. AppGroup Таргет виджетов не является чем-то уникальным и работает примерно так же, как и остальные таргеты других app extensions. И для передачи информации по разным таргетам сначала надо добавить в приложение AppGroup. Во вкладке Signing & Capabilities основного таргета вашего проекта нужно нажать на кнопку + Capability и в новом окно выбрать App Groups. Хорошей практикой является назвать AppGroup как “group.” + buindle id приложения. Рис. 1. Создание App Group После этого можно добавить id вашей AppGroups в константы, добавить файл констант в таргет виджетов и иметь доступ к id везде, где понадобится, например, так: import Foundation struct Constants { static let appGroupID = "group.com.nadzeya.widgetsSandbox" } Рис. 2. Добавление файла в таргет виджетов Теперь мы готовы передавать данные между таргетами, и начнем с самого простого – UserDefaults. Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека мобильного разработчика» Интересно, перейти к каналу UserDefaults UserDefaults в Swift – это класс, который предоставляет возможность сохранять пары ключ-значение в пользовательскую встроенную базу данных. В нее можно сохранять значения разных типов данных – String, Bool, Data, Date, Array, Dictionary и проч. В основном UserDefaults используются для хранения некоторых настроек приложения и/или пользовательских предпочтений, таких как выбранный формат времени и даты, темная или светлая тема приложения, если, конечно, приложение поддерживает это. Также еще в UserDefaults можно хранить что-то важное для аналитики или отображения некоторых экранов, например, дату первой сессии приложения. И для того, чтобы была возможность использовать в разных таргетах сохраненные в UserDefaults значения, нам надо их сохранять в главном таргете не в UserDefaults.standard: UserDefaults.standard.set("my_value", forKey: "myValueKey") а в наш контейнер AppGroup: UserDefaults(suiteName: Constants.appGroupID)!.set("my_value", forKey: "myValueKey") И мы тогда сможем читать сохраненные данные в таргете виджета таким образом. Допустим, мы сохранили что-то типом String: let savedValue = UserDefaults(suiteName: Constants.appGroupID)!.string(forKey: "myValueKey") Вот так просто меняется работа с UserDefaults и теперь мы можем через них передавать нужные нам данные в таргет виджета. File Container UserDefaults отлично справляются с хранением чего-то небольшого, но если есть задача передать в таргет виджетов нечто большее, чем пользовательские настройки, а базы данных в приложении нет, то можно использовать File Container и хранить необходимые данные, например в .plist-файле или в .json-файле. Для этого нам надо создать нужный нам файл в File Container для нашей App Group и записать в него информацию: let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupID)! let fileURL = containerURL.appendingPathComponent("savedDataForWidgets.json") do { let encoded = try JSONEncoder().encode(myWidgetData) try! encoded.write(to: fileURL) } catch { print( error) } И, соответственно, вот так можно читать эту информацию в таргете виджета: var widgetData: [MyWidgetData] = [] guard let data = try? Data(contentsOf: url) else { return widgetData } do { widgetData = try JSONDecoder().decode([MyWidgetData].self, from: data) } catch { print(error) } CoreData В большом количестве приложений используются CoreData для хранения данных, и для того, чтобы можно было ею пользоваться в таргете виджетов, надо создать общий CoreData контейнере в AppGroup: let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupID)! let storeURL = containerURL.appendingPathComponent("MyWidgetDataModel.sqlite") let description = NSPersistentStoreDescription(url: storeURL) let container = NSPersistentContainer(name: "MyWidgetDataModel") container.persistentStoreDescriptions = [description] container.loadPersistentStores { ... } И теперь мы можем получать наши данные в таргете виджета вот так: let managedObjectContext = CoreDataStack.shared.managedObjectContext let predicate = NSPredicate(format: "id == %@", "widgetID") let request = NSFetchRequest<SomeItem>(entityName: "MyWidget") let result = try managedObjectContext.fetch(request) Кроме CoreData, есть и другие базы данных, но принцип везде примерно одинаковый: можно добавить файлы базы данных в таргет виджета и уже в нем напрямую запрашивать необходимую информацию. Есть только одно но: виджеты ни в каком виде не поддерживают асинхронный код, то есть и запросы за данными надо будет делать синхронно. *** Я постаралась подробно рассказать об основных способах передачи данных из основного таргета приложения в таргет виджетов. Надеюсь, что эта статья была полезной. Я буду рада фидбэку и комментариям. Спасибо! Савицкая Надежда, iOS-разработчик. Материалы по теме ?Как работают таймлайны и как обновлять виджеты правильно
Так или иначе, но в виджеты необходимо передавать информацию из основного приложения. Это может быть все что угодно: от выбранного пользователем формата времени до полученных писем в почтовом клиенте. В этой статье я расскажу об основных способах передачи данных между таргетами приложения.
Таргет виджетов не является чем-то уникальным и работает примерно так же, как и остальные таргеты других app extensions. И для передачи информации по разным таргетам сначала надо добавить в приложение AppGroup. Во вкладке Signing & Capabilities основного таргета вашего проекта нужно нажать на кнопку + Capability и в новом окно выбрать App Groups. Хорошей практикой является назвать AppGroup как “group.” + buindle id приложения.
Рис. 1. Создание App Group
После этого можно добавить id вашей AppGroups в константы, добавить файл констант в таргет виджетов и иметь доступ к id везде, где понадобится, например, так:
id
import Foundation struct Constants { static let appGroupID = "group.com.nadzeya.widgetsSandbox" }
Рис. 2. Добавление файла в таргет виджетов
Теперь мы готовы передавать данные между таргетами, и начнем с самого простого – UserDefaults.
UserDefaults
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека мобильного разработчика» Интересно, перейти к каналу
UserDefaults в Swift – это класс, который предоставляет возможность сохранять пары ключ-значение в пользовательскую встроенную базу данных. В нее можно сохранять значения разных типов данных – String, Bool, Data, Date, Array, Dictionary и проч. В основном UserDefaults используются для хранения некоторых настроек приложения и/или пользовательских предпочтений, таких как выбранный формат времени и даты, темная или светлая тема приложения, если, конечно, приложение поддерживает это. Также еще в UserDefaults можно хранить что-то важное для аналитики или отображения некоторых экранов, например, дату первой сессии приложения. И для того, чтобы была возможность использовать в разных таргетах сохраненные в UserDefaults значения, нам надо их сохранять в главном таргете не в UserDefaults.standard:
UserDefaults.standard
UserDefaults.standard.set("my_value", forKey: "myValueKey")
а в наш контейнер AppGroup:
UserDefaults(suiteName: Constants.appGroupID)!.set("my_value", forKey: "myValueKey")
И мы тогда сможем читать сохраненные данные в таргете виджета таким образом. Допустим, мы сохранили что-то типом String:
let savedValue = UserDefaults(suiteName: Constants.appGroupID)!.string(forKey: "myValueKey")
Вот так просто меняется работа с UserDefaults и теперь мы можем через них передавать нужные нам данные в таргет виджета.
UserDefaults отлично справляются с хранением чего-то небольшого, но если есть задача передать в таргет виджетов нечто большее, чем пользовательские настройки, а базы данных в приложении нет, то можно использовать File Container и хранить необходимые данные, например в .plist-файле или в .json-файле. Для этого нам надо создать нужный нам файл в File Container для нашей App Group и записать в него информацию:
.plist
.json
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupID)! let fileURL = containerURL.appendingPathComponent("savedDataForWidgets.json") do { let encoded = try JSONEncoder().encode(myWidgetData) try! encoded.write(to: fileURL) } catch { print( error) }
И, соответственно, вот так можно читать эту информацию в таргете виджета:
var widgetData: [MyWidgetData] = [] guard let data = try? Data(contentsOf: url) else { return widgetData } do { widgetData = try JSONDecoder().decode([MyWidgetData].self, from: data) } catch { print(error) }
В большом количестве приложений используются CoreData для хранения данных, и для того, чтобы можно было ею пользоваться в таргете виджетов, надо создать общий CoreData контейнере в AppGroup:
let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupID)! let storeURL = containerURL.appendingPathComponent("MyWidgetDataModel.sqlite") let description = NSPersistentStoreDescription(url: storeURL) let container = NSPersistentContainer(name: "MyWidgetDataModel") container.persistentStoreDescriptions = [description] container.loadPersistentStores { ... }
И теперь мы можем получать наши данные в таргете виджета вот так:
let managedObjectContext = CoreDataStack.shared.managedObjectContext let predicate = NSPredicate(format: "id == %@", "widgetID") let request = NSFetchRequest<SomeItem>(entityName: "MyWidget") let result = try managedObjectContext.fetch(request)
Кроме CoreData, есть и другие базы данных, но принцип везде примерно одинаковый: можно добавить файлы базы данных в таргет виджета и уже в нем напрямую запрашивать необходимую информацию. Есть только одно но: виджеты ни в каком виде не поддерживают асинхронный код, то есть и запросы за данными надо будет делать синхронно.
***
Я постаралась подробно рассказать об основных способах передачи данных из основного таргета приложения в таргет виджетов. Надеюсь, что эта статья была полезной. Я буду рада фидбэку и комментариям. Спасибо!
Савицкая Надежда, iOS-разработчик.
Ваш адрес email не будет опубликован. Обязательные поля помечены *
Сохранить моё имя, email и адрес сайта в этом браузере для последующих моих комментариев.
Δ
Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.