SwiftUI初心者が端末のロック/アンロックを取得できるようになるまでの道のりを簡単にメモしておきます。
以前はcom.apple.springboard.lockcompleteをゴニョゴニョする非公開APIを使う方法で無理やり検出していたのですが、SwiftUIになってうまく制御できなかったため(なにぶん初心者で技術力が無いなもので・・・)、もうちょっとスマートな方法を調べました。
とりあえず以下を参考にしています。
- 【iOS】非公開APIを使わずにiPhoneのロック状態を検知する
- How to set addObserver in SwiftUI?
- how to detect the locked/unlocked screen status with swift
- その他、Apple公式ドキュメントなど
ContentView.swift
- UIApplication.protectedDataDidBecomeAvailableNotification
- UIApplication.protectedDataDidBecomeAvailableNotification
を検出することで、ロック/アンロック検出を代替できるようです。
ただし、本来は保護されたデータにアクセスできるようなった/できないようになったを検出するためのもので、パスワードロックされているとこれらのデータにアクセスできない(アンロックされるとアクセスできる)という仕組みを利用しているようです。
そのため、そもそも画面ロックのパスワードを設定していない場合は検出できません(未確認)。
とりあえず、ロック/アンロック回数を表示するようにしました。
NotificationCenter.default.publisher(for:UIApplication.protectedDataDidBecomeAvailableNotification)
NotificationCenter.default.publisher(for:UIApplication.protectedDataWillBecomeUnavailableNotification)
を設定しおておいて、それぞれの出力を.onReceiveで受け取るようにしています。
ContentView.swift
import SwiftUI
struct ContentView: View {
@State var label_unlocked: String = "Unlocked: 0"
@State var label_locked: String = "Locked: 0"
@State var counter_unlocked: Int = 0
@State var counter_locked: Int = 0
//アンロックの検出用
let pub_unlocked = NotificationCenter.default.publisher(for: UIApplication.protectedDataDidBecomeAvailableNotification)
//ロックの検出用
let pub_locked = NotificationCenter.default.publisher(for: UIApplication.protectedDataWillBecomeUnavailableNotification)
var body: some View {
VStack {
Text(label_unlocked)
.onReceive(pub_unlocked, perform: { _ in
self.counter_unlocked = self.counter_unlocked + 1
label_unlocked = "Unlocked: \(counter_unlocked)"
})
Text(label_locked)
.onReceive(pub_locked, perform: { _ in
self.counter_locked = self.counter_locked + 1
label_locked = "Locked: \(counter_locked)"
})
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
画面ロック/アンロックの行為はセットになっているはずですので、表示される回数はどちらも同じになります。