起動時になんかしたい
非同期処理というと堅苦しいが、Viewに関わることなく処理を行いたい。
画面への反映を急ぐことはない。
記事にした動機
起動時になにかしたいと迷うときが度々出現すると思ったので、備忘録に乗せておくことにした。
ChatGPTにきいてみた
回答はこんな感じ。
1: アプリ全体で使う状態やリソースの初期化はAppStateで行う。
2: 特定のビューに依存した初期処理はonAppearを使用する。
3: アプリ全体のセットアップ処理は、@main構造体のinitに記述する。
AppStateでの管理することにした。
アプリの起動時にappStateを環境変数として渡しているので、このタイミングでAppStateのinit処理が呼ばれる
@main
struct MyApp: App {
@StateObject private variable appState = AppState
var body: some Scene {
WindowGroup {
BrowserAppView()
.environmentObject(appState)
}
}
}
次は、初回起動時に呼ばれるAppStateの初期化処理。この中では、2つの変数に値を格納している。今回はブラウザアプリであり、起動時のurlは固定値で渡している。(将来的には、すでに開いていたページを開くもしくは、何もページがないとき、空のウィンドウにブックマーク一覧などが表示されているのが理想的だが・・・)
AppState内に、loadBookmarksメソッドを作成した。
Bookmark().fetchBookmark()の処理でRealmからデータを取得する処理を行うようにしている。
loadBookmarksメソッドの呼び出しは、次のコードに記述している。
init(initialURL: URL = URL(string:"https://game8.jp/kids/minecraft")!) {
self.currentURL = initialURL
self.webView = WKWebView()
}
func loadBookmarks() {
DispatchQueue.main.async {
self.bookmarks = Bookmark().fetchBookmark()
}
}
}
AppStateのloadBookmarksメソッドは、Viewが表示された後のタイミングで開始することにした。AppStateの初期化処理の中に含めても良さそうだったんだけど・・・起動直後に処理を呼び出すと、負荷がかかる想定なので、ややずらすためというのが理由だ。
var body: some View {
VStack(spacing: 0){
WebView(action: $webViewAction, isFooterVisible: $isFooterVisible)
if isFooterVisible {
TabView(webViewAction: $webViewAction)
.transition(.move(edge: .bottom))
}
}
.onAppear{
appState.loadBookmarks()
}
.animation(Animation.easeInOut, value: isFooterVisible)
}
}
この処理の流れ、忘れそう。
視覚的にいい感じにまとめられたらいいのにな。