【Swift】iPhoneのロック解除を検知する方法!
この記事からわかること
- SwiftでiPhoneのロックを検知する方法
- UIApplication. protectedDataDidBecomeAvailableNotification /protectedDataWillBecomeUnavailableNotificationの使い方
- バックグラウンドでは検知できない?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.0
- watchOS:10.0
- Swift:5.9
- macOS:Sonoma 14.1
iPhoneのロック解除を検知する方法
SwiftでiPhoneのロック/ロック解除を検知する方法を探していましたが、基本的に専用のメソッドはないようです。そもそもアプリからアクセスできるデバイス情報には限度があるので、ロック/ロック解除はサポートされていないようです。
調べてみるとUIApplication.protectedDataDidBecomeAvailableNotification
で似たようなことを実装できました。
UIApplication.protectedDataDidBecomeAvailableNotification
公式リファレンス:protectedDataDidBecomeAvailableNotification
UIApplication
クラスのprotectedDataDidBecomeAvailableNotification
はロック検知というより保護されたファイルがアクセス可能になったことを通知する役割を持っています。挙動してはiPhoneのロックを解除するとアクセスが可能になるので同じような意味になります。
逆にロックされた時(アクセスできなくなった時)を検知するにはprotectedDataDidBecomeAvailableNotification
を使用します。
NotificationCenter.default.publisher
を使用して観測しておけばアプリのロック/ロック解除を検知できるようになります。
// アプリのロック状態を観測するクラス(未使用)
class AppLockStateManager {
public var applock: AnyPublisher<Bool, Never> {
_applock.eraseToAnyPublisher()
}
private var _applock = CurrentValueSubject<Bool, Never>(false)
private var cancellables = Set<AnyCancellable>()
init() {
NotificationCenter.default.publisher(for: UIApplication.protectedDataDidBecomeAvailableNotification)
.sink { [weak self] _ in
guard let self else { return }
self._applock.send(false)
logger.debug("デバイスがアンロックがされた")
}.store(in: &cancellables)
NotificationCenter.default.publisher(for: UIApplication.protectedDataWillBecomeUnavailableNotification)
.sink { [weak self] _ in
guard let self else { return }
self._applock.send(true)
logger.debug("デバイスがロックされた")
}.store(in: &cancellables)
}
}
バックグラウンドでは動作しない
iOSアプリではバックグラウンドで許可されている動作時間はシビアです。Bluetoothなどであればアプリがバックグラウンドでも半永久的に動作を続けるようにすることが可能ですが、それ以外の場合は数十秒〜数分しか動作権限がありません。
アプリを立ち上げてバックグラウンドにした状態でロック/ロック解除の回数をカウントしようと思いましたが、どうやら今の仕様では実現できなさそうでした。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。