前言
最近做了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添加一个scheme, URL 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,以上就是本篇分享内容。
网友评论