Skip to content

Broadcast Upload Extension for Screen Sharing

adamrangs edited this page Aug 8, 2022 · 3 revisions

In iOS 11, with a new built-in screen recording and broadcast feature, you can record your screen without using a jailbroken app or plug your iPhone into a computer with a software that can screen record. you can watch this [WWDC Video] talks about it at a high level.

In SDK screen sharing feature, we transfer iOS device screen recording data to other participants. That's why we need the broadcast upload extension.

An app that contains one or more extensions is called a containing app. What is the app extension? Apple Said, "An app extension lets you extend custom functionality and content beyond your app and make it available to users while they’re interacting with other apps or the system". You could get all the app extension knowledge on App Extension Programming Guide.

How to implementation broadcast upload extension(base on Xcode9/Swift4/iOS 11.2):

  1. Set up your own App Group, follow this guide to enable App Group capability and give it a name. It will be used in step 4&5.

  2. File->New->Target->In iOS Application Extension->Select BroadCast Upload Extension to create a new extension target (Broadcast Setup UI Extension is an optional target).

  3. Change your project Podfile, add WebexBroadcastExtensionKit for your broadcast extension target for example. Run pod install or pod update from your project directory.

target 'SDKExampleBroadcastExtension' do
    platform :ios, '13.0'
    pod 'WebexBroadcastExtensionKit'
end
  1. In Xcode, you will find SampleHandle.swift in your project broadcast extension folder. Use SDK broadcast extension API to make the screen share feature work. Start broadcast when your extension gets ready. Also, you need adding your app and your extension into same App Group and pass the App Group Identifier to SDK. See this wiki for setting up an app group setting up an app group.
WebexBroadcastExtension.sharedInstance.start(applicationGroupIdentifier: "group.your.application.group.identifier") {
   error in
   //...     
}

Finish broadcast screen when extension ended or whenever you want.

override func broadcastFinished() {
    // User has requested to finish the broadcast.
    WebexBroadcastExtension.sharedInstance.finish()
}

When system deliver video sample buffer to your extension, call the SDK

override func processSampleBuffer(_ sampleBuffer: CMSampleBuffer, with sampleBufferType: RPSampleBufferType) {
    switch sampleBufferType {
        case RPSampleBufferType.video:
            // Handle video sample buffer
            WebexBroadcastExtension.sharedInstance.handleVideoSampleBuffer(sampleBuffer: sampleBuffer)
            break
        case RPSampleBufferType.audioApp:
            // Handle audio sample buffer for app audio
            break
        case RPSampleBufferType.audioMic:
            // Handle audio sample buffer for mic audio
            break
    }
}

to handle it. And you can observe the broadcast server state change and do something when received some error coming from your containing app.

WebexBroadcastExtension.sharedInstance.onError = {
                    error in
                    switch error {
                    case .illegalOperation(let reason):
                        // The request is illegal.
                        break
                    case .illegalStatus(let reason):
                        // The request is in an illegal status.
                        break
                    case .serviceFailed(let code, let reason):
                        // A request to Webex SDK containing app failed.
                        break
                    }
                }

WebexBroadcastExtension.sharedInstance.onStateChange = {
                    state in
                    switch state {
                    case .Initiated:
                        break
                    case .Broadcasting:
                        //Connected with the containing app broadcast server.
                        break
                    case .Suspended:
                        //The containing app broadcast server connection is suspended.
                        break
                    case .Stopped:
                        break
                    }
                    
                }

Here is a simple example of these APIs usage:API Demo.

  1. Using call.oniOSBroadcastingChanged call back to observe user's broadcast extension is connected or not.
call.oniOSBroadcastingChanged = {
    event in
    switch event {
        case .extensionConnected :
            //....
            break
        case .extensionDisconnected:
            //...
            break
    }
}

After broadcast extension connected, simply use

call.startSharing() {
    error in
    // ...
}

to share your screen and

call.stopSharing() {
    error in
    // ...
}

to stop sharing with other participants. You can find the complete demo App on this GitHub repo.

  1. Run your Broadcast extension:

    • Add screen recording to control center: Open Settings -> Control Center -> Customize Controls. Tap '+' on Screen Recording.
    • To start your broadcast extension: Swipe up to open Control Center. Long press on recording button. Select your extension, tap Start Broadcast button.
  2. Debug your app extension:

    • If you already debugging your app by Xcode. you could find and attach to the app extension process when it gets started. Go to the menu of Xcode->Debug->Attach to Process->find your broadcast extension and click it.
    • Press menu Debug->Attach to Process->By Process Identifier (PID) or Name..., input the app extension's name, to start your extension, Xcode can attach it automatically.

Some suggestions for developing app extension:

  1. As Apple mentioned, app extension's life cycle and environment are different with an app. The app extension has some strict restrictions on memory/CPU usage and other system resources. So we recommend not to do any heavy work in the app extension.

  2. If you use some unavailable system APIs on the extension, you will get a compile warning or your app will be rejected by Apple's review process. Here is the Link Apple talk about it.

  3. You can create an embedded framework to share code between your app extension and its containing app. But please notice the API limitation on app extension. Check the "Allow app extension API only" box under Deployment Info in the General tab of the project settings for your framework.