美文网首页
iOS Swift代码关闭RPSystemBroadcastPi

iOS Swift代码关闭RPSystemBroadcastPi

作者: 沉船无数 | 来源:发表于2024-02-25 20:03 被阅读0次

前言

最近做了ReplayKit2录屏需求,拉起RPSystemBroadcastPickerView广播列表,点击开始直播,启动录屏进程后想优雅的自动关闭,而不是引导用户去点击关闭,查了些资料,参考了大佬们的做法,终于搞定了,iOS13、iOS16测试都没问题。

iOS14以下

RPSystemBroadcastPickerView是presnet模态弹出的,拿到RPBroadcastPickerStandaloneViewController即可dismiss,下面直接上代码:
1、在拉起RPSystemBroadcastPickerView的控制器新增一个static变量存储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)
        }
    }
}

合适的时机执行 UIViewController.swizzlePresentViewController, 我是在拉起RPSystemBroadcastPickerView后执行:

@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: "手车互联功能需要iOS 12以上", confirmStr: "确定") {
                
            }
        }
        
        //presenter?.pushToCastingVC()
    }

iOS 14以上

Xcode -> project -> traget选中宿主app -> info -> URL Types添加一个schemeURL scheme里面随便填,比如我填的就是"myapp://broadcaststarted",记住里面填的,等下用得着

使用示例

private func broadcastNotificationAction() {
        LYDarwinNotification.shared.setNotificationClosure(for: .broadcastStarted) { (name) in
            defer {
                LYDarwinNotification.shared.removeObserver(notificationName: .broadcastStarted)
            }
            
            // 更新录制状态
            LYUserDefault.isRecording = true
            
            // iOS14以下 关闭RPSystemBroadcastPickerView
            if let pick = LanYouVenuciaVLinkHomeViewController.picker as? UIViewController {
                pick.dismiss(animated: true)
            }
            
            // iOS 14以上 关闭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是我封装的一个进程间通知类,开始直播,进入SampleHandler中broadcastStarted方法时,发送进程间通信,通知宿主app执行broadcastNotificationAction方法,关闭RPSystemBroadcastPickerView,以上就是本篇分享内容。

相关文章

网友评论

      本文标题:iOS Swift代码关闭RPSystemBroadcastPi

      本文链接:https://www.haomeiwen.com/subject/sxbaadtx.html