1. kazuhiro4949

    No comment

    kazuhiro4949
Changes in body
Source | HTML | Preview
@@ -1,71 +1,71 @@
iOS11の新機能の一つに**Screen Recording**というものがあります。
とても素敵な機能で、簡単に画面の録画が実現できるようになりました。(超便利!)
しかしアプリによっては「この画面を録画されると都合が悪い」といったケースもあるでしょう。
そこで、アプリの中で録画の検知をする方法をTipsとしてまとめます。
# アプリ内で録画を検知するためのプロパティ
Screen Recordingへ合わせる形で、iOS11からUIScreenに以下のAPIが追加されました。
- [isCaptured - UIScreen | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uiscreen/2921651-iscaptured)
このプロパティは、**「スクリーンのキャプチャ」**が行われている間はtrueを返します。
```swift
UIScreen.main.isCaptured
```
ここでいう「スクリーンのキャプチャ」にはScreen Recordingも含まれます。
レコードを開始した上でプロパティの値を確認してみるとわかるのですが、確かにレコード中はtrueを返して、やめるとfalseを返します。
注意点として、「含まれます」というのが曲者で、AirPlayやミラーリング中でも同じくtrueを返す仕様となっています。
従って、AirPlayをサポートしている映像サービスだと、AirPlayのケースを取り除かないとならないでしょう。
AVPlayerを使って映像を再生しているケースであれば、以下のAPIを組み合わせることで**Screen Recording中であるがAirPlayではない**というのを判定できるかと思います。
- [isExternalPlaybackActive - AVPlayer | Apple Developer Documentation](https://developer.apple.com/documentation/avfoundation/avplayer/1388982-isexternalplaybackactive)
Screen Recordingもしくはミラーリング中であるかどうかは上記2つのプロパティを使って判定します。
```swift
// player: AVPlayer
UIScreen.main.isCaptured && !player.isExternalPlaybackActive
```
残念ながらミラーリングかどうかを判定するためのプロパティは見つけられませんでした。。。(もしご存知のかたがいたら教えてください)
# アプリ内で録画を検知するためのNotification
前述のプロパティを使い、UIのライフサイクルイベントや通信完了ハンドラなどで検知できるようになりました。
ただしこのままだと不十分です。映像の再生中にコントロールセンターを開き、再生を開始したときにはどうすればいいでしょうか。(寧ろそういうパターンのほうが多いでしょう。)
そういった場合でも対応できるよう、Notificationにも新たな通知が追加されました。
- [UIScreenDidConnectNotification - UIKit | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uiscreendidconnectnotification)
リファレンスを見る限り、通知を受け取ってもuserInfoには何も入っていないようです。通知の中で先程のisCapturedを呼んで、判定をしましょう。
```swift
let obserber = NotificationCenter
.default
.addObserver(forName: .UIScreenCapturedDidChange, object: nil, queue: .main) { [weak self] (notif) in
if let player = self?.player, !player.isExternalPlaybackActive, UIScreen.main.isCaptured {
// ここで何とかする
}
}
```
# まとめ
1. 画面遷移してデータを取ってきたタイミングで検知したいのであればUIScreenの***isCaptured***を呼ぶ
2. ただし1.のみだとAirPlayやミラーリングも検知してしまうので、AVPlayerの***isExternalPlaybackActive***なども適宜組み合わせる
-3. レコーディング開始のタイミングを検知したければUIScreenCapturedDidChangeを使う
+3. レコーディング開始のタイミングを検知したければ**UIScreenCapturedDidChange**を監視する
以上です。
# 参考資料
- [iOS 11 Screen Recording - Copyright Risks | Apple Developer Forums](https://forums.developer.apple.com/thread/86521)
- [isCaptured - UIScreen | Apple Developer Documentation](https://developer.apple.com/documentation/uikit/uiscreen/2921651-iscaptured)
- [isExternalPlaybackActive - AVPlayer | Apple Developer Documentation](https://developer.apple.com/documentation/avfoundation/avplayer/1388982-isexternalplaybackactive)