iOS App と Widget 間でデータを共有する場合にいくつか注意が必要です。
まず、 App と Widget では Bunlde Identifier が異なり、 OS 側から両者は区別されます。 Apple は、こういった状況でデータを共有する仕組みとして App Groups を用意しています。
以下は、アプリから入力した値を Widget で表示するサンプルアプリです。このサンプルアプリの解説を通して App と Widget でのデータ共有について説明します。
もしクローンして手元の環境で試される場合は、以下の変更が必要です。
- Team
- Bundle Indentifier
- App Groups
App Groups の指定
App と Widget それぞれの Signing & Capabilities で同じ App Groups を指定しています。
コード上では、 HomeMemo.entitlements と HomeMemoWidgetExtension.entitlements の <key>com.apple.security.application-groups</key>
の部分で確認できます。
これで App と Widget でデータ共有する準備が整いました。
UserDefaults への保存
UserDefaults(suiteName)
で App Groups を指定して保存します。
UserDefaults(suiteName: appGroupId)?.set(name, forKey: "name")
この時、 App Groups には Capabilities に設定されているものと同じ値を指定します。違うものを指定すると、 Widget から読み込みできません。サンプルアプリでは、 appGroupId = "group.io.github.ykws.example.HomeMemo"
としています。
UserDefaults からの読み込み
保存した時と同じ App Groups を指定して読み込みます。
UserDefaults(suiteName: appGroupId)?.string(forKey: "name") ?? ""
Widget への反映
Widget に対してすぐに反映したい場合は再読み込みを明示します。
WidgetCenter.shared.reloadAllTimelines()
Demo イメージはサンプルアプリの README に添付しているのでそちらから確認できます。