SwiftUIによるアプリ開発 / CoreData, Widget Kit, App Groups
May 16, 2021
SiwftUI, CoreData, WidgetKit, App Groupsを用いて開発した日付カウントアプリ“PinDay”をリリースしました。プロジェクトのソースコードと、つまずいたポイントを共有します。
アプリを閉じるとsheetが初期化される
sheetで表示しているViewは、親Viewが再レンダリングされると同じくレンダリングされます。これによって、入力していたTextFieldの値が失われてしまうなどの挙動が起こってしまいます。sheetで表示するViewをEquatable
に準拠させることで、不必要な再レンダリングを防いでいます。
Widgetがチカチカする
Widgetで使用できるメモリ上限は30MB程度ですが、これを超えるとWidgetがチカチカする現象が発生します。
この30MBの上限はWidget単体に対してではなく、同じアプリのWidgetがgetTimeline()
メソッド上で使用するメモリの合計であると考えられます。従って、以下のような状況でWidgetはチカチカし始めます。
- 1つの
TimelineEntry
が10MBの画像を持ち、これを3つ以上Timelineに追加した時(TimelineEntry
は構造体なので、画像は参照ではなくコピーされます) - 1つのWidgetが
getTimeline()
上で10MBのメモリを使用し、ユーザによってこのWidgetが3つ以上追加された時
後者の状況はユーザの使用方法によるものなので防ぎきれない部分もありますが、対処方法は以下の通りです。
TimelineEntry
のデータサイズを小さくする- Widgetに表示するViewで重たい処理はしない(静的な画面で構成する)
getTimeline()
で一度にTimelineに追加するEntryはなるべく少なくする
以上の対応をしても、Production環境で同様の症状を確認しています(一度にWidgetを複数追加した場合?)。知見をお持ちの方はご教授いただけると幸いです。