你如何实现与 ReplayKit 的共享?

How do you implement sharing with ReplayKit?

我正在尝试使用 ReplayKit 来录制我的应用程序,然后让用户选择共享或删除录音。删除工作正常,但我无法让共享部分正常工作。我尝试将 RPPreviewViewControllerMode 与 .shared 一起使用,但 XCode 无法识别它。我还尝试了 UIActivityViewController,它会弹出共享菜单 - 但是,如果我尝试访问录音,它就不起作用。最后,我尝试了 previewControllerDelegate,它允许用户编辑和保存视频,但不能分享。

我已经在下面发布了我的代码。请指教,谢谢!

import UIKit
import ReplayKit



class ViewController: UIViewController, RPPreviewViewControllerDelegate {


@IBOutlet weak var statusLabel: UILabel!

@IBOutlet weak var imagePicker: UISegmentedControl!
@IBOutlet weak var selectedImageView: UIImageView!
@IBOutlet weak var micToggle: UISwitch!
@IBOutlet weak var recordButton: UIButton!

var recorder = RPScreenRecorder.shared()

private var isRecording = false

@IBAction func imagePicked(_ sender: UISegmentedControl) {
    switch sender.selectedSegmentIndex {
    case 0:
        selectedImageView.image = UIImage(named: "skate")
    case 1:
        selectedImageView.image = UIImage(named: "food")
    case 2:
        selectedImageView.image = UIImage(named: "cat")
    case 3:
        selectedImageView.image = UIImage(named: "nature")
    default:
        selectedImageView.image = UIImage(named: "skate")


    }
}

@IBAction func recordButtonPressed(_ sender: Any) {
    if !isRecording {
        startRecording()
    } else {
            stopRecording()
        }
    }


func startRecording() {
    guard recorder.isAvailable else {
        print("Recording not available at this time")
        return
    }
    if micToggle.isOn {
        recorder.isMicrophoneEnabled = true
    } else {
        recorder.isMicrophoneEnabled = false
    }
    recorder.startRecording { (error) in
        guard  error == nil else {
            print("There was an error startng the recording.")
            return
        }
        //Call DispatchQueue to update UI in the main thread rather than background
        DispatchQueue.main.async {
            self.micToggle.isEnabled = false
            self.recordButton.setTitleColor(#colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1), for: .normal)
            self.recordButton.setTitle("Stop", for: .normal)
            self.statusLabel.textColor = #colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1)
            self.statusLabel.text = "Recording..."
            self.isRecording = true

            print("Started Recording")
        }
    }
}


func stopRecording() {

    recorder.stopRecording { (preview, error) in

        guard preview != nil else {
            print("Preview controller not available")
            return
        }

        let alert = UIAlertController(title: "Recording finished", message: "Would you like to share or delete your recording?", preferredStyle: .alert
        )

        let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action) in
            self.recorder.discardRecording {
                print("Recording discarded successfully.")
            }
        })

        //First try:
        let recordedVideo = "Video goes here!" //I don't know how to modify this to get the video content.
        let activityViewController : UIActivityViewController = UIActivityViewController(
            activityItems: [recordedVideo], applicationActivities: nil)
        self.present(activityViewController, animated: true, completion: nil)

        //Second try:
        //This allows me to edit and save the video, but not share it.
        let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
            preview?.previewControllerDelegate = self
            self.present(preview!, animated: true, completion: nil)
        })

//            //Third try: not working!
//            var mode: RPPreviewViewControllerMode
//             let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
//                preview?.mode = .share // The error is: 'mode' has been explicitly marked unavailable here (ReplayKit.RPPreviewViewController)
//                preview?.previewControllerDelegate = self
//                self.present(preview!, animated: true, completion: nil)
//            })


        alert.addAction(deleteAction)
        alert.addAction(shareAction)
        self.present(alert, animated: true, completion: nil)

        self.isRecording = false
        self.viewReset()
    }
}

func viewReset() {
    micToggle.isEnabled = true
    statusLabel.text = "Ready to Record"
    statusLabel.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
    recordButton.setTitle("Record", for: .normal)
    recordButton.setTitleColor(#colorLiteral(red: 0.2994912565, green: 0.7500386834, blue: 0.3387371898, alpha: 1), for: .normal)
}

func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
    dismiss(animated: true, completion: nil)
}

}

可能是因为 .automatic 模态显示,因为在 iOS 13 中,当您弹出控制器时,它不会覆盖全屏。所以,试试 .fullScreen,它对我有帮助:

func stopRecording() {
    recorder.stopRecording { (preview, error) in

        guard preview != nil else {
            print("Preview controller not available")
            return
        }

        let alert = UIAlertController(title: "Recording finished", message: "Would you like to share or delete your recording?", preferredStyle: .alert
        )

        let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action) in
            self.recorder.discardRecording {
                print("Recording discarded successfully.")
            }
        })

        let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
            // Try .fullScreen
            preview?.modalPresentationStyle = .fullScreen
            preview?.previewControllerDelegate = self
            self.present(preview!, animated: true, completion: nil)
        })


        alert.addAction(deleteAction)
        alert.addAction(shareAction)
        self.present(alert, animated: true, completion: nil)

        self.isRecording = false
        self.viewReset()
    }
}