Add message flow for createScreenShareOffer
This commit is contained in:
@@ -11,18 +11,35 @@ open class BBBSampleHandler : RPBroadcastSampleHandler {
|
||||
// Logger (these messages are displayed in the console application)
|
||||
private var logger = os.Logger(subsystem: "BigBlueButtonMobileSDK", category: "BBBSampleHandler")
|
||||
private var appGroupName:String = "";
|
||||
private var observer:NSKeyValueObservation?;
|
||||
|
||||
open func setAppGroupName(appGroupName:String) {
|
||||
self.appGroupName = appGroupName;
|
||||
logger.info("Received appGroupName: \(appGroupName)")
|
||||
self.appGroupName = appGroupName
|
||||
}
|
||||
|
||||
// Called by IOS when the user authorized to start the broadcast
|
||||
open override func broadcastStarted(withSetupInfo setupInfo: [String : NSObject]?) {
|
||||
logger.info("ReplayKit2 event - broadcastStarted")
|
||||
|
||||
logger.info("ReplayKit2 event - broadcastStarted - persisting information on UserDefaults")
|
||||
BBBSharedData
|
||||
// Object used to share data
|
||||
let userDefaults = BBBSharedData
|
||||
.getUserDefaults(appGroupName: self.appGroupName)
|
||||
.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.broadcastStarted)
|
||||
|
||||
// Notify the UI app that the broadcast has been started
|
||||
logger.info("ReplayKit2 event - broadcastStarted - persisting information on UserDefaults")
|
||||
userDefaults.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.broadcastStarted)
|
||||
|
||||
// Listen for createOffer requests from the UI APP
|
||||
logger.info("Configuring observer")
|
||||
self.observer = userDefaults.observe(\.createScreenShareOffer, options: [.new]) { (defaults, change) in
|
||||
self.logger.info("Observer detected a createScreenShareOffer request!")
|
||||
BBBSharedData
|
||||
.getUserDefaults(appGroupName: self.appGroupName)
|
||||
.set(BBBSharedData.generatePayload(properties: [
|
||||
"sdp": "this is SDP from extension"
|
||||
]), forKey: BBBSharedData.SharedData.screenShareOfferCreated)
|
||||
}
|
||||
}
|
||||
|
||||
open override func broadcastPaused() {
|
||||
|
||||
@@ -14,12 +14,15 @@ open class BBBSharedData {
|
||||
private static var userDefaultsGroup:String?
|
||||
|
||||
public enum SharedData {
|
||||
public static let broadcastStarted = "broadcastStarted"
|
||||
public static let broadcastPaused = "broadcastPaused"
|
||||
public static let broadcastResumed = "broadcastResumed"
|
||||
public static let broadcastFinished = "broadcastFinished"
|
||||
public static let broadcastStarted = "broadcastStarted" // Broadcaster -> UI APP
|
||||
public static let broadcastPaused = "broadcastPaused" // Broadcaster -> UI APP
|
||||
public static let broadcastResumed = "broadcastResumed" // Broadcaster -> UI APP
|
||||
public static let broadcastFinished = "broadcastFinished" // Broadcaster -> UI APP
|
||||
public static let createScreenShareOffer = "createScreenShareOffer" // UI APP -> Broadcaster
|
||||
public static let screenShareOfferCreated = "screenShareOfferCreated" // Broadcaster -> UI APP
|
||||
}
|
||||
|
||||
// Get reference to userDefaults object (that's actually the object used to share information among UI APP and the BroadcastUploadExtension APP)
|
||||
public static func getUserDefaults(appGroupName:String) -> UserDefaults {
|
||||
if(userDefaults == nil || userDefaultsGroup == nil || userDefaultsGroup != appGroupName) {
|
||||
logger.info("getUserDefaults \(appGroupName) -> Created")
|
||||
@@ -33,10 +36,22 @@ open class BBBSharedData {
|
||||
}
|
||||
|
||||
// Generates a unique payload
|
||||
public static func generatePayload() -> String {
|
||||
// TODO - replace by UUID
|
||||
public static func generatePayload(properties:Dictionary<String,String> = [:]) -> String {
|
||||
let now=String(DateFormatter.localizedString(from: Date(), dateStyle: .medium, timeStyle: .short));
|
||||
|
||||
return "{\"timestamp\": \(now)}";
|
||||
var payload = properties;
|
||||
payload["uuid"] = UUID().uuidString;
|
||||
payload["timestamp"] = now;
|
||||
|
||||
let encoder = JSONEncoder()
|
||||
if let jsonData = try? encoder.encode(payload) {
|
||||
if let jsonString = String(data: jsonData, encoding: .utf8) {
|
||||
print("JSON = \(jsonString)")
|
||||
return jsonString
|
||||
}
|
||||
}
|
||||
|
||||
logger.error("JSON encoder error, returning empty object")
|
||||
return "{}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,21 +5,34 @@
|
||||
//
|
||||
|
||||
extension UserDefaults {
|
||||
|
||||
// Broadcaster -> UI APP
|
||||
@objc open dynamic var broadcastStarted: String {
|
||||
return string(forKey: BBBSharedData.SharedData.broadcastStarted) ?? ""
|
||||
}
|
||||
|
||||
// Broadcaster -> UI APP
|
||||
@objc open dynamic var broadcastPaused: String {
|
||||
return string(forKey: BBBSharedData.SharedData.broadcastPaused) ?? ""
|
||||
}
|
||||
|
||||
// Broadcaster -> UI APP
|
||||
@objc open dynamic var broadcastResumed: String {
|
||||
return string(forKey: BBBSharedData.SharedData.broadcastResumed) ?? ""
|
||||
}
|
||||
|
||||
// Broadcaster -> UI APP
|
||||
@objc open dynamic var broadcastFinished: String {
|
||||
return string(forKey: BBBSharedData.SharedData.broadcastFinished) ?? ""
|
||||
}
|
||||
|
||||
// UI APP -> Broadcaster
|
||||
@objc open dynamic var createScreenShareOffer: String {
|
||||
return string(forKey: BBBSharedData.SharedData.createScreenShareOffer) ?? ""
|
||||
}
|
||||
|
||||
// Broadcaster -> UI APP
|
||||
@objc open dynamic var screenShareOfferCreated: String {
|
||||
return string(forKey: BBBSharedData.SharedData.createScreenShareOffer) ?? ""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ open class BigBlueButtonSDK: NSObject {
|
||||
private static var broadcastExtensionBundleId = ""
|
||||
private static var appGroupName = ""
|
||||
private static var userDefaults:UserDefaults?
|
||||
private static var observer: NSKeyValueObservation?
|
||||
private static var observer1: NSKeyValueObservation?
|
||||
private static var observer2: NSKeyValueObservation?
|
||||
|
||||
public static func initialize(broadcastExtensionBundleId:String, appGroupName:String) {
|
||||
self.broadcastExtensionBundleId = broadcastExtensionBundleId
|
||||
@@ -26,10 +27,22 @@ open class BigBlueButtonSDK: NSObject {
|
||||
// Observe keys modified by BroadcastUploadExtension and emit this event to react native
|
||||
|
||||
//broadcastStarted
|
||||
observer = userDefaults?.observe(\.broadcastStarted, options: [.new]) { (defaults, change) in
|
||||
observer1 = userDefaults?.observe(\.broadcastStarted, options: [.new]) { (defaults, change) in
|
||||
logger.info("Detected a change in userDefaults for key broadcastStarted")
|
||||
ReactNativeEventEmitter.emitter.sendEvent(withName: ReactNativeEventEmitter.EVENT.onBroadcastStarted.rawValue, body: nil)
|
||||
}
|
||||
|
||||
//screenShareOfferCreated
|
||||
observer2 = userDefaults?.observe(\.screenShareOfferCreated, options: [.new]) { (defaults, change) in
|
||||
let payload:String = (change.newValue!);
|
||||
logger.info("Detected a change in userDefaults for key screenShareOfferCreated \(payload)")
|
||||
let payloadData = payload.data(using: .utf8)!
|
||||
|
||||
let decodedPayload = (try? JSONDecoder().decode([String: String].self, from: payloadData))!
|
||||
let sdp = decodedPayload["sdp"]
|
||||
|
||||
ReactNativeEventEmitter.emitter.sendEvent(withName: ReactNativeEventEmitter.EVENT.onScreenShareOfferCreated.rawValue, body: sdp)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,8 +50,13 @@ open class BigBlueButtonSDK: NSObject {
|
||||
return self.broadcastExtensionBundleId;
|
||||
}
|
||||
|
||||
public static func getAppGroupName() -> String {
|
||||
return self.appGroupName;
|
||||
}
|
||||
|
||||
public static func deinitialize () {
|
||||
observer?.invalidate()
|
||||
observer1?.invalidate()
|
||||
observer2?.invalidate()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ open class ReactNativeEventEmitter: RCTEventEmitter {
|
||||
case onBroadcastPaused = "onBroadcastPaused"
|
||||
case onBroadcastResumed = "onBroadcastResumed"
|
||||
case onBroadcastFinished = "onBroadcastFinished"
|
||||
case onScreenShareOfferCreated = "onScreenShareOfferCreated"
|
||||
}
|
||||
|
||||
override init() {
|
||||
|
||||
@@ -10,4 +10,5 @@
|
||||
@interface RCT_EXTERN_REMAP_MODULE(BBBN_ScreenShareService, ScreenShareServiceManager, NSObject)
|
||||
|
||||
RCT_EXTERN_METHOD(initializeScreenShare)
|
||||
RCT_EXTERN_METHOD(createScreenShareOffer)
|
||||
@end
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
import Foundation
|
||||
import os
|
||||
import bigbluebutton_mobile_sdk_common
|
||||
|
||||
@objc(ScreenShareServiceManager)
|
||||
class ScreenShareServiceManager: NSObject {
|
||||
@@ -25,4 +26,17 @@ class ScreenShareServiceManager: NSObject {
|
||||
ReactNativeEventEmitter.emitter.sendEvent(withName: eventName, body: nil);
|
||||
}
|
||||
|
||||
// React native exposed method (called when user click the button to share screen)
|
||||
@objc func createScreenShareOffer() -> Void {
|
||||
logger.info("createScreenShareOffer")
|
||||
|
||||
// Send request of SDP to the broadcast upload extension
|
||||
// TIP - the handling of SDP response is done in observer2 of BigBlueButtonSDK class
|
||||
logger.info("createScreenShareOffer - persisting information on UserDefaults")
|
||||
BBBSharedData
|
||||
.getUserDefaults(appGroupName: BigBlueButtonSDK.getAppGroupName())
|
||||
.set(BBBSharedData.generatePayload(), forKey: BBBSharedData.SharedData.createScreenShareOffer)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
32
src/methods/createScreenShareOffer.tsx
Normal file
32
src/methods/createScreenShareOffer.tsx
Normal file
@@ -0,0 +1,32 @@
|
||||
import { createScreenShareOffer as nativeCreateScreenShareOffer } from '../native-components/BBBN_ScreenShareService';
|
||||
import nativeEmitter from '../native-messaging/emitter';
|
||||
|
||||
// Reference to the resolver of last call
|
||||
let resolve = (a: String) => {
|
||||
console.log(
|
||||
`default resolve function called, this should never happen: ${a}`
|
||||
);
|
||||
};
|
||||
|
||||
// Resolve promise when SDP offer is available
|
||||
nativeEmitter.addListener('onScreenShareOfferCreated', (sdp) => {
|
||||
resolve(sdp);
|
||||
});
|
||||
|
||||
// Entry point of this method
|
||||
function createScreenShareOffer() {
|
||||
return new Promise((res, rej) => {
|
||||
// store the resolver for later call (when event is received)
|
||||
resolve = res;
|
||||
|
||||
try {
|
||||
console.log(`>nativeCreateScreenShareOffer`);
|
||||
// call native swift method that triggers the broadcast popup
|
||||
nativeCreateScreenShareOffer();
|
||||
} catch (e) {
|
||||
rej(`Call to nativeCreateScreenShareOffer failed`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export default createScreenShareOffer;
|
||||
@@ -2,7 +2,7 @@ import { initializeScreenShare as nativeInitializeScreenShare } from '../native-
|
||||
import nativeEmitter from '../native-messaging/emitter';
|
||||
|
||||
// Reference to the resolver of last call
|
||||
let resolve = (a: String) => {
|
||||
let resolve = (a: String | null) => {
|
||||
console.log(
|
||||
`default resolve function called, this should never happen: ${a}`
|
||||
);
|
||||
@@ -15,7 +15,7 @@ nativeEmitter.addListener('onBroadcastRequested', () => {
|
||||
|
||||
// Resolve promise when broadcast is started (this event means that user confirmed the screenshare)
|
||||
nativeEmitter.addListener('onBroadcastStarted', () => {
|
||||
resolve('null');
|
||||
resolve(null);
|
||||
});
|
||||
|
||||
// Entry point of this method
|
||||
@@ -26,9 +26,10 @@ function initializeScreenShare() {
|
||||
|
||||
try {
|
||||
// call native swift method that triggers the broadcast popup
|
||||
console.log(`>nativeInitializeScreenShare`);
|
||||
nativeInitializeScreenShare();
|
||||
} catch (e) {
|
||||
rej(`Call to nativeInitializeScreenShare failed`);
|
||||
rej(`Call to nativeInitializeScreenShare failed zzy`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,3 +5,7 @@ const ScreenShareService = NativeModules.BBBN_ScreenShareService;
|
||||
export function initializeScreenShare() {
|
||||
ScreenShareService.initializeScreenShare();
|
||||
}
|
||||
|
||||
export function createScreenShareOffer() {
|
||||
ScreenShareService.createScreenShareOffer();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { MutableRefObject } from 'react';
|
||||
import type { WebView, WebViewMessageEvent } from 'react-native-webview';
|
||||
import initializeScreenShare from '../methods/initializeScreenShare';
|
||||
import createScreenShareOffer from '../methods/createScreenShareOffer';
|
||||
|
||||
function observePromiseResult(
|
||||
webViewRef: MutableRefObject<WebView>,
|
||||
@@ -39,6 +40,9 @@ export function handleWebviewMessage(
|
||||
case 'initializeScreenShare':
|
||||
promise = initializeScreenShare();
|
||||
break;
|
||||
case 'createOffer':
|
||||
promise = createScreenShareOffer();
|
||||
break;
|
||||
default:
|
||||
throw `Unknown method ${data?.method}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user