💡 해당 공유 프로세스를 구축하기 전에 전제로 Braodcast Extension과 App Group, Pakcakge에 대한 설정이 필요하였습니다. 이를 구축하였다는 전제에 실제 개발을 진행합니다.
💡 [해당 개발을 위한 흐름]
1. 사용자가 “화면공유” 버튼을 누르면 함수가 수행이 됩니다. 2. 해당 함수는 SwiftUI 환경에서 UIViewController를 불러오는 형태로 구성하였습니다. 3. UIViewController가 호출이 될 때 Broadcast를 수행시킵니다. 4. App Group으로 서로 연결된 Extenstion이 수행이 됩니다. 5. 해당 BroadCast Extenstion은 Pacakage를 불러와서 쉽게 처리를 위해 사용합니다. 6. 실시간은 공유되는 정보에 대해서 값을 전달받습니다.
2) 기술 구현 : 설명 및 소스코드
1. 권한을 추가해 줍니다 : NSPhotoLibraryAddUsageDescription
💡 해당 기술에서는 화면공유한 결과물을 사진폴더에 저장을 하도록 구현이 되어 있습니다. 그렇기에 앱이 사용자의 사진 라이브러리에 대한 추가 전용 액세스를 요청합니다.
💡 해당 화면에서는 UIKit으로 구성된 화면을 SwiftUI에서 호출하는 과정입니다. 💡 해당 버튼을 누르면 실제 화면 공유를 위한 페이지가 출력이 됩니다. 💡 해당 화면에서는 UIKit으로 구성된 화면을 SwiftUI에서 호출하는 과정입니다. 💡 시스템 전체 화면공유 버튼을 누르면 ScreenShareViewController()의 UIViewController를 호출합니다.
//
// ContentView.swift
// TestApp
//
// Created by Lee on 2023/03/08.
//
import SwiftUI
import Foundation
struct ContentView: View {
var body: some View {
NavigationView{
VStack{
NavigationLink(destination: ScreenShareView()) {
Text("시스템 전체 화면공유")
.frame(width: 350, height: 20)
.foregroundColor(Color.white)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}.padding()
}
}
}
/**
* UIKit으로 구성된 ScreenShareViewController를 호출합니다
*/
struct ScreenShareView : UIViewControllerRepresentable {
typealias UIViewControllerType = ScreenShareViewController
// MARK: UIViewController를 생성합니다.
func makeUIViewController(context: Context) -> UIViewControllerType {
return ScreenShareViewController() // MARK: ScreenShareViewController의 UIViewController를 호출합니다.
}
// MARK: UIViewController를 변경하였을때 수행합니다.
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
//
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
💡 UIKit으로 구성된 UIViewController이며 화면공유에 사용되는 팝업을 띄어주는 형태로 구성되어 있습니다. 💡 해당 부분에서는 App Group으로 ‘Broadcast upload Extension’ 타깃과의 연결을 하며 시작을 할 경우 데이터가 전달이 됩니다.
//
// ScreenShareViewController.swift
// TestApp
//
// Created by Lee on 2023/03/08.
//
import ReplayKit
import UIKit
// MARK: Extenstion을 구동시키는 방법
class ScreenShareViewController: UIViewController {
let broadcastPicker = RPSystemBroadcastPickerView(frame: CGRect(x: 10, y: 50, width: 100, height: 100))
override func viewDidLoad() {
super.viewDidLoad()
// Broadcast Upload Extension의 Bundle ID 값
broadcastPicker.preferredExtension = "org.test.app.TestApp.SampleHandler"
// 화면 공유시 마이크 사용여부
broadcastPicker.showsMicrophoneButton = false
// MARK: 버튼을 누르지 않고 페이지에 접근되었을때 즉시 수행되는 방법
for subview in broadcastPicker.subviews {
if let button = subview as? UIButton {
button.sendActions(for: UIControl.Event.allTouchEvents)
}
}
// MARK: 버튼을 눌렀을때 수행하는 방법
// for subview in broadcastPicker.subviews {
// let b = subview as! UIButton
// b.setImage(nil, for: .normal)
// b.setTitle("녹화시작", for: .normal)
// b.setTitleColor(.black, for: .normal)
// }
view.addSubview(broadcastPicker)
}
}
3) 실행 화면
1. 앱 실행
💡 일반 앱을 수행하는 것이 아니라 SampleHandler를 통해서 앱을 실행해야 수행이 됩니다.
2. 동작과정
💡 구성한 View 화면에서 "시스템 전체 화면공유" 버튼을 누릅니다.
💡 아래와 같은 화면이 출력되고 "방송 시작" 버튼을 누릅니다.
💡 방송이 시작되며 녹화 기능이 수행되면서 전체 화면 공유를 할 수 있는 데이터 전송됩니다.
💡 녹화한 데이터의 경우 즉시 처리 할 수 있지만 해당 예시에서는 동영상 파일로 사진폴더에 저장되도록 구성되어 있습니다.