82560


ReplayKitで画面録画をしようとすると、ユーザーに録画許可を促すような画面が表示されます。

ReplayKitの録画を開始するためのコードと同じ場所に何らかの処理を書くと、録画許可を促す前に処理が始まってしまいます。  
以下の画像で言えば、「画面とマイクを収録」のボタンを押す前に処理が開始されてしまいます。  
試したコードを以下に示します。

[code]

    import UIKit
    import ReplayKit
    
    class ViewController: UIViewController, RPPreviewViewControllerDelegate {
    
        //processing count
        var count = 0
        var timer = Timer()
        
        @IBOutlet weak var recordingButton: UIButton!
        
        var coldFlag = false
        @IBAction func recordingButtonTapped(_ sender: UIButton)
        {
            if self.coldFlag == false
            {
                self.recordingButton.setTitle("Stop Recording", for: .normal)
                self.startRecording()
                
                //timer処理
                self.timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: { (timer) in
                    self.count += 1
                    //self.count値をコンソールへ出力
                    print(self.count)
                })
                
                self.coldFlag = true
            }
            else
            {
                self.recordingButton.setTitle("Start Recording", for: .normal)
                self.endRecording()
                
                //print停止
                self.timer.invalidate()
                
                self.coldFlag = false
            }
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            self.recordingButton.setTitle("Start Recording", for: .normal)
        }
    
        func startRecording() {
            // 既に録画中だと何もしない
            guard !RPScreenRecorder.shared().isRecording else { return }
            // 録画開始
            RPScreenRecorder.shared().startRecording(withMicrophoneEnabled: true, handler: { (error) in
                if let error = error {
                    debugPrint(#function, "recording something failed", error)
                }
            })
        }
    
        func endRecording() {
            // 録画中じゃないと終了しない
            guard RPScreenRecorder.shared().isRecording else { return }
            // 録画終了
            RPScreenRecorder.shared().stopRecording(handler: { (previewViewController, error) in
                guard let previewViewController = previewViewController else { return }
                previewViewController.previewControllerDelegate = self //delegateを実装しないとdismissされない
    
                // プレビューの表示
                self.present(previewViewController, animated: true, completion: nil)
            })
        }
    
        func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
            DispatchQueue.main.async {
                previewController.dismiss(animated: true, completion: nil)
            }
        }
    }
    
[/code]

上記のコードで言うと、recordingButtonTappedが呼び出された時に、画面収録に関する許可画面がユーザーに表示されますが、許可する前にtimerで値がprintされてしまいます。

どうしたら、許可した後にprintするようにできますでしょうか？

[![画像の説明をここに入力](https://i.stack.imgur.com/VRJ9l.jpg)](https://i.stack.imgur.com/VRJ9l.jpg)


CC BY-SA 4.0
2021-09-17T08:54:20.433
82553
2021-09-18T01:42:08.600
36446
question
swift
ReplayKitで録画開始と同時に処理したい


`startRecording(withMicrophoneEnabled:handler:)`は、すでにiOS10でdeprecatedとなっているので使用しない方がいいでしょう。

[startRecording(withMicrophoneEnabled:handler:)](https://developer.apple.com/documentation/replaykit/rpscreenrecorder/1620979-startrecording)

* * *

[`startRecording(handler:)`のドキュメント](https://developer.apple.com/documentation/replaykit/rpscreenrecorder/1649019-startrecording)において、`handler:`は、

> that is called when the request completes.

とされているので、録画終了後?とも取れたのですが、試してみる限り、リクエスト完了時というのはユーザが許可ダイアログを選択した時点のようです。

それを利用すると、こんな感じにできます。

[code]

        var isRecordingAvailable = true
        @IBAction func recordingButtonTapped(_ sender: UIButton) {
            if self.isRecordingAvailable {
                self.recordingButton.setTitle("Stop Recording", for: .normal)
                self.startRecording {
                    //timer処理
                    self.timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true, block: { (timer) in
                        self.count += 1
                        //self.count値をコンソールへ出力
                        print(self.count)
                    })
                }
                
                self.isRecordingAvailable = false
            } else {
                self.recordingButton.setTitle("Start Recording", for: .normal)
                self.endRecording {
                    //print停止
                    self.timer.invalidate()
                }
                
                self.isRecordingAvailable = true
            }
        }
    
        func startRecording(startHandler: @escaping ()->Void) {
            let recorder = RPScreenRecorder.shared()
            // 既に録画中だと何もしない
            guard !recorder.isRecording else { return }
            // 録画開始
            recorder.isMicrophoneEnabled = true
            recorder.startRecording { error in
                if let error = error {
                    debugPrint(#function, "recording something failed", error)
                    return
                }
                startHandler()
            }
        }
        func endRecording(stopHandler: @escaping ()->Void) {
            // 録画中じゃないと終了しない
            guard RPScreenRecorder.shared().isRecording else { return }
            // 録画終了
            RPScreenRecorder.shared().stopRecording(handler: { (previewViewController, error) in
                stopHandler()
                guard let previewViewController = previewViewController else { return }
                previewViewController.previewControllerDelegate = self //delegateを実装しないとdismissされない
    
                // プレビューの表示
                self.present(previewViewController, animated: true, completion: nil)
            })
        }
    
[/code]

実際のアプリに適用するには色々修正しないといけないかもしれませんが、まずは試してみてください。


CC BY-SA 4.0
2021-09-17T15:58:01.770
82560
2021-09-18T01:42:08.600
2021-09-18T01:42:08.600
13972
13972
82553
answer