iOS Swift代碼關(guān)閉RPSystemBroadcastPickerView

前言

最近做了ReplayKit2錄屏需求,拉起RPSystemBroadcastPickerView廣播列表,點(diǎn)擊開始直播,啟動(dòng)錄屏進(jìn)程后想優(yōu)雅的自動(dòng)關(guān)閉,而不是引導(dǎo)用戶去點(diǎn)擊關(guān)閉,查了些資料,參考了大佬們的做法,終于搞定了,iOS13、iOS16測(cè)試都沒(méi)問(wèn)題。

iOS14以下

RPSystemBroadcastPickerView是presnet模態(tài)彈出的,拿到RPBroadcastPickerStandaloneViewController即可dismiss,下面直接上代碼:
1、在拉起RPSystemBroadcastPickerView的控制器新增一個(gè)static變量存儲(chǔ)RPBroadcastPickerStandaloneViewController。
2、runtime拿到RPBroadcastPickerStandaloneViewController。

extension UIViewController {
    fileprivate static let swizzlePresentViewController: Void = {
        let originalSelector = #selector(present(_:animated:completion:))
        let swizzledSelector = #selector(swizzledPresent(_:animated:completion:))
        
        swizzleSelector(originalSelector, withAnotherSelector: swizzledSelector)
    }()
    
    @objc fileprivate func swizzledPresent(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?) {
        if let className = String(describing: type(of: viewControllerToPresent)) as? String {
            if className == "RPBroadcastPickerStandaloneViewController" {
                LanYouVenuciaVLinkHomeViewController.picker = viewControllerToPresent
            }
        }
        
        swizzledPresent(viewControllerToPresent, animated: flag, completion: completion)
    }
    
    fileprivate class func swizzleSelector(_ originalSelector: Selector, withAnotherSelector swizzledSelector: Selector) {
        let aClass: AnyClass = self
        
        guard let originalMethod = class_getInstanceMethod(aClass, originalSelector),
              let swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector) else {
            return
        }
        
        let didAddMethod = class_addMethod(aClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
        
        if didAddMethod {
            class_replaceMethod(aClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

合適的時(shí)機(jī)執(zhí)行 UIViewController.swizzlePresentViewController, 我是在拉起RPSystemBroadcastPickerView后執(zhí)行:

@objc private func startCastingAction() {
        // 正在錄屏中
        if LYUserDefault.isRecording {
            presenter?.pushToCastingVC()
            return
        }
        
        // 拉起RPSystemBroadcastPickerView
        if #available(iOS 12.0, *) {
            let picker = RPSystemBroadcastPickerView.init(frame: CGRectMake(0, 0, 1, 1))
            picker.preferredExtension = "你的extension bundle id"
            picker.showsMicrophoneButton = true
            
            for subView in picker.subviews {
                if let btn = subView as? UIButton {
                    btn.sendActions(for: .allTouchEvents)
                }
            }
            
            _ = UIViewController.swizzlePresentViewController
        } else {
            showAlert(withTitle: "提示", message: "手車互聯(lián)功能需要iOS 12以上", confirmStr: "確定") {
                
            }
        }
        
        //presenter?.pushToCastingVC()
    }

iOS 14以上

Xcode -> project -> traget選中宿主app -> info -> URL Types添加一個(gè)schemeURL scheme里面隨便填,比如我填的就是"myapp://broadcaststarted",記住里面填的,等下用得著。

使用示例

private func broadcastNotificationAction() {
        LYDarwinNotification.shared.setNotificationClosure(for: .broadcastStarted) { (name) in
            defer {
                LYDarwinNotification.shared.removeObserver(notificationName: .broadcastStarted)
            }
            
            // 更新錄制狀態(tài)
            LYUserDefault.isRecording = true
            
            // iOS14以下 關(guān)閉RPSystemBroadcastPickerView
            if let pick = LanYouVenuciaVLinkHomeViewController.picker as? UIViewController {
                pick.dismiss(animated: true)
            }
            
            // iOS 14以上 關(guān)閉RPSystemBroadcastPickerView方法
            guard let url = URL(string: "myapp://broadcaststarted") else {
                return
            }
            
            if UIApplication.shared.canOpenURL(url) {
                UIApplication.shared.open(url) { complete in
                    if complete {
                        self.presenter?.pushToCastingVC()
                    }
                }
            }
        }
    }

LYDarwinNotification.shared.setNotificationClosure : LYDarwinNotification是我封裝的一個(gè)進(jìn)程間通知類,開始直播,進(jìn)入SampleHandler中broadcastStarted方法時(shí),發(fā)送進(jìn)程間通信,通知宿主app執(zhí)行broadcastNotificationAction方法,關(guān)閉RPSystemBroadcastPickerView,以上就是本篇分享內(nèi)容。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容