【Swift UI】ScenePhaseの使い方!フォアグラウンド/バックグラウンドの検知
この記事からわかること
- Swift UIのScenePhaseの使い方
- アプリがフォアグラウンドやバックグラウンドであることを検知する方法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:14.3.1
- iOS:16.4
ScenePhaseの使い方
Swift UIではアプリがフォアグラウンドやバックグラウンドで動作していることを列挙型ScenePhase
の値で識別することが可能です。ScenePhase
型には@Environment
を使用して環境変数として参照することが可能です。
@Environment(\.scenePhase) private var scenePhase
おすすめ記事:【Swift UI】@Environmentとは?使い方と使用可能なキー値一覧
Swift UIに実際に組み込む場合は以下のようになります。
struct ContentView: View {
@Environment(\.scenePhase) private var scenePhase
var body: some View {
Text("Hello World")
.onChange(of: scenePhase) { phase in
switch phase {
case .active:
print("フォアグラウンド")
case .inactive:
print("フォアグラウンド(作業を一時停止する必要)")
case .background:
print("バックグラウンド")
@unknown default:
print("不明")
}
}
}
}
ScenePhase
は以下の3つの値を持っています。アプリを閉じた場合など状態が切り替わるたびに値は変化していくのでonChange
を使用して値の変化を観測することで検知することが可能です。
enum ScenePhase {
case active // フォアグラウンド
case inactive // フォアグラウンド(作業を一時停止する必要)
case background // バックグラウンド
}
NotificationCenterを使用して識別する
scenePhase
を使用した方法はSwift UIに依存しているのでクラスなどにまとめたい際に使いにくいです。なのでどこでも使いやすいようにNotificationCenterを使用することでアプリの状態を管理するクラスを作成してみます。
NotificationCenter
からpublisher
メソッドを使用します。引数for
には観測したいイベントNSNotification.Name型
を渡します。
class AppState {
private var cancellables = Set<AnyCancellable>()
init() {
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
.sink { _ in
print("アプリがアクティブになった")
}
.store(in: &cancellables)
NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification)
.sink { _ in
print("アプリが非アクティブになった")
}
.store(in: &cancellables)
NotificationCenter.default.publisher(for: UIApplication.didEnterBackgroundNotification)
.sink { _ in
print("アプリがバックグラウンドになった")
}
.store(in: &cancellables)
NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)
.sink { _ in
print("アプリがフォアグラウンドになった")
}
.store(in: &cancellables)
}
}
例えばSwift UIで使用するならインスタンス化するだけです。onAppear
の中でインスタンス化してもすぐに破棄されてしまい観測できないので注意してください。
struct ContentView: View {
private let state = AppState()
var body: some View {
Text("Test")
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。