WidgetKitで初心者の躓きどころ
WidgetKitで初心者の躓きどころ
WidgetKitをみたら、いくつか躓きどころが合ったのでまとめてみました。
特にWidgetはメインのTargeと別なので
Targetが違うと色々参照できるようにする必要があります。
1. メインのターゲットを参照できない
参照したいファイルのTargetMembershipにチェックを入れればOK
※一つのファイルにいろんな依存物があると、それら全てをtチェックしないといけないので、各オブジェクト毎にファイルを分けるべし。
2. メインのTargetとは別でWidgetのTargetを作成するのでLibraryが参照できない。
Testなどと同様LibraryのTargetも追加する必要がある。
Cocoa Podsの場合
podファイルのWidgetのTarget内にinherit! :search_paths
を指定OK
target 'SampleWidgetExtension' do
inherit! :search_paths
end
SwiftPMの場合
プロジェクトのWidgetのTargetのBuild Phasesで必要なLibraryを連携したらOK
3. DB内のデータが参照できない。
CoreDataやRealmを使っている場合
メインアプリのデータを参照するにはAppGroupで同じDBファイルを参照できるようにする必要がある。
AppGroupの設定
アプリの Target を選択し、Signing & Capabilities タブで、App Groups を追加します。
App Groupsの項目が無い場合は左上の+ボタンでダイアログの中からApp Groupsを選択。
新しいGroupを作成して下の更新ボタンをクリック。
※注意
Build Configurationが複数ある場合はそれぞれ必要なBuild ConfigurationでAppGroupの設定が必要
CoreDataの場合
NSPersistentStoreDescriptionのurlにAppGroup名を使って初期化します。
let container = NSPersistentContainer(name: TodoListStore.containerName)
container.persistentStoreDescriptions = [NSPersistentStoreDescription(url: FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.SampleWidget")!.appendingPathComponent("Sample.sqlite"))]
container.loadPersistentStores(completionHandler: { (description, error) in
if let error = error as NSError? {
print("Unresolved error \(error), \(error.userInfo)")
}
})
print(container.persistentStoreDescriptions.first?.url ?? "nil.splite")
return container
Realmの場合
Realmインスタンスを作成する時に同じDBを参照するためにConfigurationのfileURLにAppGroupのURLを設定します。
let realm = try! Realm()
このようにインスタンスを作っている箇所を下記に変更
var config = Realm.Configuration()
let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.SampleWidget")!
config.fileURL = url.appendingPathComponent("db.realm")
let realm = try! Realm(configuration: config)
URLから取得して画像を表示する場合は非同期では動かない。
Widgetに置いてURL画像の表示をする場合非同期処理は使えない。
Widgetでは同期的に取得するべし。
- 非同期処理の場合
DispatchQueue.global().async {
let data = try? Data(contentsOf: imageURL)
DispatchQueue.main.async {
self.downloadData = data
}
}
- 同期処理の場合
let data = try? Data(contentsOf: imageURL)
self.downloadData = data
最後に
WidgetはSwiftUIでの実装が必要なので、SwiftUIの勉強も兼ねてチャレンジしてみました。
まだ触り始めたばかりなので、また躓き所が出てきたら追記します。
参考
- https://www.amazon.co.jp/dp/4844378678
- https://developer.apple.com/documentation/widgetkit/
- https://developer.apple.com/documentation/foundation/filemanager/1412643-containerurl
- https://rightcode.co.jp/blog/information-technology/ios14-realm-data-widget-display
- https://qiita.com/4q_sano/items/c3c108198f7b162c5932
- https://qiita.com/shiz/items/309349d9cdb75084e74e
Author And Source
この問題について(WidgetKitで初心者の躓きどころ), 我々は、より多くの情報をここで見つけました https://qiita.com/terry-private/items/f70345845c563d141ec1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .