ReplayKit同一会话无法二次录制问题求助
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
RPPreviewViewControllerreference 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
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 }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 } } }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

