You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReplayKit同一会话无法二次录制问题求助

Fixing ReplayKit View Service Interrupted Error on Second Recording

Hey there, I’ve run into this exact ReplayKit issue before—super frustrating when it works the first time but breaks on subsequent recordings without restarting the app! Let’s break down what’s going wrong and how to fix it.

What’s Causing the Error?

The _UIViewServiceInterfaceErrorDomain Code=3 error usually happens because the ReplayKit view service isn’t being properly cleaned up after your first recording. Your current code has a couple of small issues that lead to this:

  • You’re creating a new reference to RPScreenRecorder.shared() every time you start/stop recording (while it’s a singleton, inconsistent referencing can cause state mismatches)
  • You’re holding onto the RPPreviewViewController reference without releasing it after dismissal, which keeps the view service alive incorrectly
  • No checks for existing recording state before starting a new session

Step-by-Step Fixes

  1. Use a shared recorder instance
    Declare the recorder as a property in your view controller instead of creating it inline each time. This ensures you’re always interacting with the same singleton instance:

    class MyViewController: UIViewController {
        private let recorder = RPScreenRecorder.shared()
        private var previewViewController: RPPreviewViewController?
        private var isRecording = false
        // ... rest of your code
    }
    
  2. Add state checks before starting recording
    Prevent accidental duplicate recording attempts and confirm recording is available before proceeding:

    @objc func startRecording() {
        // Check if we're already recording or if recording is unavailable
        guard !recorder.isRecording, recorder.isAvailable else {
            if recorder.isRecording {
                print("Already in a recording session")
            } else {
                print("Screen recording is not available")
            }
            return
        }
    
        recorder.startRecording { [unowned self] error in
            if let unwrappedError = error {
                print(unwrappedError.localizedDescription)
                print("NOT Recording")
                self.recordIcon.isHidden = false
                self.ring.isHidden = false
            } else {
                self.video.play()
                print("Recording")
                self.isRecording = true
                self.recordIcon.isHidden = true
                self.ring.isHidden = true
            }
        }
    }
    
  3. Clean up preview controller references properly
    When dismissing the preview controller, release its reference to let the view service terminate correctly:

    @objc func stopRecording() {
        guard recorder.isRecording else {
            print("No active recording to stop")
            return
        }
    
        recorder.stopRecording { [unowned self] previewViewController, error in
            if let error = error {
                print("\(error.localizedDescription)")
                self.isRecording = false
                self.recordIcon.isHidden = false
                self.ring.isHidden = false
                return
            }
    
            // Handle iPad presentation
            if UI_USER_INTERFACE_IDIOM() == .pad {
                previewViewController?.modalPresentationStyle = .popover
                previewViewController?.popoverPresentationController?.sourceRect = .zero
                previewViewController?.popoverPresentationController?.sourceView = self.view
            }
    
            if let previewVC = previewViewController {
                previewVC.previewControllerDelegate = self
                self.previewViewController = previewVC
                self.present(previewVC, animated: true)
            } else {
                // No preview controller available, reset UI
                self.isRecording = false
                self.recordIcon.isHidden = false
                self.ring.isHidden = false
            }
        }
    }
    
    func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
        dismiss(animated: true) { [unowned self] in
            // Release the preview controller reference to clean up the view service
            self.previewViewController = nil
            self.isRecording = false
            self.recordIcon.isHidden = false
            self.ring.isHidden = false
        }
    }
    

Why This Works

  • Reusing the same recorder instance ensures consistent state management with ReplayKit’s internal services
  • Releasing the preview controller reference after dismissal lets the system properly terminate the view service, so it can be reinitialized for your next recording
  • Adding state checks prevents race conditions that could corrupt the recording session

Give these changes a try—they should fix the service connection error and let users record multiple times without restarting the app!

内容的提问来源于stack exchange,提问作者Coding Hobbies

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:55:49