React-Native WebView Implementation
IOS SDK
Add PrimisPlayer to a react-native application as a Native Module
Please remember to add PrimisPlayer SDK and IMA SDK to your xcode project as described earlier.### Create native module for PrimisPlayer
Add a new Objective-c header file to your XCode project: PrimisPlayerModule.h
// PrimisPlayerModule.h
#ifndef PrimisPlayerModule_h
#define PrimisPlayerModule_h
#import <React/RCTBridgeModule.h>
@interface PrimisPlayerModule : NSObject <RCTBridgeModule>
@end
#endif /* PrimisPlayerModule_h */
Add a new Objective-c implementation file to your XCode project: PrimisPlayerModule.m
// PrimisPlayerModule.m
#import <Foundation/Foundation.h>
#import "PrimisPlayerModule.h"
#import <React/RCTLog.h>
#import <React/UIView+React.h>
#import <WebKit/WebKit.h>
#import <PrimisPlayerSdk/PrimisPlayerSdk-Swift.h>
@interface PrimisPlayerModule()
@property(nonatomic,retain) PrimisPlayer *player;
@end
@implementation PrimisPlayerModule
RCT_EXPORT_MODULE(PrimisPlayerModule);
RCT_EXPORT_METHOD(addPrimisPlayer:(NSDictionary *)props)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSString *nativeId = [props objectForKey:@"nativeID"];
if (!nativeId) {
RCTLogInfo(@"'nativeID' property is missing. Aborting");
return;
}
WKWebView *webview = [self findWebView: nativeId];
if (!webview) {
return;
}
[self setupPrimisPlayer: webview props:props];
});
}
RCT_EXPORT_METHOD(removePrimisPlayer)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.player remove];
self.player = nil;
});
}
- (void)setupPrimisPlayer: (UIView *)webview props:(NSDictionary *)props {
NSString *placementId = props[@"placementId"];
NSString *debugLogActiveStr = props[@"debugLogActive"];
NSString *additionalParams = props[@"additionalParams"];
if (!placementId) {
RCTLogInfo(@"'placementId' property is missing. Aborting");
return;
}
additionalParams = additionalParams ? additionalParams : @"";
BOOL debugLogActive = [debugLogActiveStr isEqualToString:@"true"];
// Create Primis player and configure it
self.player = [[PrimisPlayer alloc] init];
[self.player configure: @{
@(PrimisConfigKeyPlacementId): placementId,
@(PrimisConfigKeyContainerView): webview,
@(PrimisConfigKeyDebugLogActive): [NSNumber numberWithBool:debugLogActive]
}];
// Add Primis player to the react-native view controller
UIViewController *rnVC = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[self.player addTo: rnVC];
}
- (void)dealloc {
[self.player remove];
self.player = nil;
}
- (WKWebView *)findWebView:(NSString*)nativeId { //(NSInteger)tag {
UIViewController *rnVC = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
// Find the RNCWebView with the provided nativeID.
NSMutableArray *array = @[].mutableCopy;
[self recursiveFindWebView:rnVC.view nativeId:nativeId results:array];
switch (array.count) {
case 0:
RCTLogInfo(@"Couldn't find a webView with nativeID %@. Aborting", nativeId);
return nil;
case 1:
RCTLogInfo(@"Found a webView with nativeID %@", nativeId);
break;
default:
RCTLogInfo(@"Found multiple webViews with nativeID %@. Aborting", nativeId);
return nil;
}
// RNCWebView is a React View which manages a private WKWebView.
// The WKWebView is a subview of the RNCWebView.
UIView *rncWebview = array[0];
for (UIView *subView in rncWebview.subviews) {
if ([subView isKindOfClass:[WKWebView class]]) {
return (WKWebView*)subView;
}
}
return nil;
}
- (void)recursiveFindWebView: (UIView*)currentView nativeId:(NSString*)nativeId results:(NSMutableArray*)array {
if ([currentView.nativeID isEqualToString: nativeId]) {
[array addObject:currentView];
}
for (UIView *subview in currentView.subviews) {
[self recursiveFindWebView:subview nativeId:nativeId results:array];
}
}
@end
Add Primis Player when your webview has done loading
Add the following to your App.js file
// App.js
import NativeModules from ' react-native';
const { PrimisPlayerModule } = NativeModules;
. . .
const App: () => Node = () => {
const contentLoaded = () => {
console.debug("webview content loaded, now creating Primis Player");
PrimisPlayerModule.addPrimisPlayer( { nativeID: '<UNIQUE_ID>',
placementId: '<PLACEMENT_ID>',
debugLogActive: 'true'
});
};
. . .
return (
<WebView
…
nativeID={'<UNIQUE_ID>'}
javaScriptEnabled={true}
…
onLoadEnd={contentLoaded.bind(this)}/>
);
};
Note
- Replace <PLACEMENT_ID> with your placement ID
- Create a unique id and replace <UNIQUE_ID> with your ID. In a case where multiple WebView Instances runs simultaneously, this ID has to be unique per WebView instance
Optional: Add nativeID to specify a custom floating parent view
// App.js
. . .
const contentLoaded = () => {
PrimisPlayerModule.addPrimisPlayer({
. . .
floatingParentID: '<FLOATING_PARENT_ID>' });
};
. . .
return (
<View nativeID={'FLOATING_NATIVE_ID'}>
<WebView . . . />
</View>
);
Updated about 1 year ago