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

  1. Replace <PLACEMENT_ID> with your placement ID
  2. 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>
 );