React-Native Scrollview Implementation
IOS SDK
Add PrimisPlayer to a react-native application as a Native UI Component
Please remember to add PrimisPlayer SDK and IMA SDK to your xcode project as described earlier.
Create an RCTViewManager for PrimisPlayer
Add a new Objective-c file to your XCode project: PrimisPlayerManager.m
// PrimisPlayerManager.m
#import <React/RCTViewManager.h>
#import <PrimisPlayerSdk/PrimisPlayerSdk-Swift.h>
@protocol PrimisRNContainerDelegate <NSObject>
-(void)onContainerLayout:(UIView*)view;
@end
@interface PrimisRNContainerView : UIView
@property(nonatomic,copy) NSString* placementID;
@property(nonatomic,copy) NSString* floatingParentID;
@property(nonatomic,copy) NSString* additionalParams;
@property(nonatomic,assign) BOOL debugLogActive;
@property(nonatomic,retain) PrimisPlayer *player;
@property(nonatomic, strong) id<PrimisRNContainerDelegate> delegate;
@property(atomic, assign) BOOL doOnce;
@end
@implementation PrimisRNContainerView
- (void)layoutSubviews {
[super layoutSubviews];
if (!_doOnce) {
_doOnce = YES;
// Set width/height constraints
CGFloat width = self.frame.size.width ? self.frame.size.width : self.reactSuperview.frame.size.width;
self.translatesAutoresizingMaskIntoConstraints = NO;
[self.widthAnchor constraintEqualToConstant: width].active = YES;
[self.heightAnchor constraintEqualToConstant: 0].active = YES;
// Notify the view manager
[_delegate onContainerLayout:self];
}
}
-(void)didSetProps:(NSArray<NSString *> *)changedProps {
RCTLog(@"didSetProps: %@", changedProps.description);
if (!_placementID) { _placementID = @""; }
if (!_floatingParentID) { _floatingParentID = @""; }
if (!_additionalParams) { _additionalParams = @""; }
}
- (void) willMoveToSuperview: (UIView *) newSuperview{
if(newSuperview == nil){
RCTLog(@"willMoveToSuperview: The container view was removed from superview. Removing Primis player.");
[_player remove];
_player = nil;
}
}
@end
@interface PrimisPlayerManager : RCTViewManager <PrimisRNContainerDelegate>
@end
@implementation PrimisPlayerManager
RCT_EXPORT_MODULE(PrimisPlayerViewManager1)
RCT_EXPORT_VIEW_PROPERTY(floatingParentID, NSString);
RCT_EXPORT_VIEW_PROPERTY(placementID, NSString);
RCT_EXPORT_VIEW_PROPERTY(debugLogActive, BOOL);
RCT_EXPORT_VIEW_PROPERTY(additionalParams, NSString);
/// Force running on main thread
+ (BOOL)requiresMainQueueSetup {
return YES;
}
/// Return a container view to react-native
- (UIView *)view {
PrimisRNContainerView *view = [[PrimisRNContainerView alloc] init];
view.delegate = self;
return view;
}
/// Delegate method of PrimisRNContainerDelegate, called by PrimisRNContainerView when layoutSubviews is called
- (void)onContainerLayout:(UIView *)view {
RCTLog(@"onContainerLayout");
PrimisRNContainerView* containerView = (PrimisRNContainerView*)view;
UIView *floatParentView = [self findFloatingParentView:containerView];
containerView.player = [self setupPrimisPlayer:containerView floatParentView:floatParentView];
}
/// Create Primis player and configure it with props values
- (PrimisPlayer*)setupPrimisPlayer: (PrimisRNContainerView *)container floatParentView:(UIView*)floatParentView {
// Create a player
NSMutableDictionary* config = @{
@(PrimisConfigKeyContainerView): container,
@(PrimisConfigKeyDebugLogActive): @(container.debugLogActive),
@(PrimisConfigKeyPlacementId): container.placementID,
@(PrimisConfigKeyAdditionalParams): container.additionalParams,
}.mutableCopy;
if (floatParentView) {
config[@(PrimisConfigKeyFlowParentView)] = floatParentView;
}
PrimisPlayer* player = [[PrimisPlayer alloc] init];
[player configure:config];
[player addTo: container.reactViewController];
return player;
}
/// A helper method to find the floating Parent view by 'nativeID', allowing only a single result.
- (UIView *)findFloatingParentView:(PrimisRNContainerView*)containerView {
// Find all views with a specified nativeID
NSMutableArray *array = @[].mutableCopy;
if (containerView.floatingParentID.length) {
[self recursiveFindView:containerView.reactViewController.view nativeId:containerView.floatingParentID results:array];
}
// Allow only a single result
switch (array.count) {
case 0:
RCTLog(@"Couldn't find a floatingParentView with nativeID %@", containerView.floatingParentID);
return nil;
case 1:
RCTLog(@"Found a floatingParentView with nativeID %@", containerView.floatingParentID);
return array.firstObject;
default:
RCTLog(@"Found multiple floatingParentViews with nativeID %@. Aborting", containerView.nativeID);
return nil;
}
}
/// A recursive helper method to find views by 'nativeID'
- (void)recursiveFindView: (UIView*)currentView nativeId:(NSString*)nativeId results:(NSMutableArray*)array {
if ([currentView.nativeID isEqualToString: nativeId]) {
[array addObject:currentView];
}
for (UIView *subview in currentView.subviews) {
[self recursiveFindView:subview nativeId:nativeId results:array];
}
}
@end
Create a native component
Create a file named PrimisPlayerView.js and add it to the root directory of your react-native app.
// PrimisPlayerView.js
import { requireNativeComponent } from 'react-native';
// requireNativeComponent automatically resolves 'RNTMap' to 'RNTMapManager'
module.exports = requireNativeComponent('PrimisPlayerViewManager');
Add Primis Player view to your page
Add the following to your App.js file
// App.js
import PrimisPlayerView from './PrimisPlayerView.js';
. . .
<PrimisPlayerView
placementID={'YOUR_PLACEMENT_ID'}
debugLogActive={true}
style=...
/>
Optional: Add nativeID to specify a custom floating parent view
// App.js
import PrimisPlayerView from './PrimisPlayerView.js';
<View nativeID={'UNIQUE_ID'}>
. . .
<PrimisPlayerView
...
floatingParentID={'UNIQUE_ID'} />
</View>
Updated about 1 year ago