browniefed / react-native-flanimatedimage

32 stars 5 forks source link

Issue bridging with a UIViewController #3

Open niranjan-b-prajapati opened 7 years ago

niranjan-b-prajapati commented 7 years ago

I am new to react-native and your process and documentation helped me understand the integrating of the native module in our app, but i am getting error as in our app we have one native module code which has a webview loading a url which works in native ios mode only.

Following is the error:

[UIView setMmsUrl:]: unrecognized selector sent to instance
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setMmsUrl:]: unrecognized selector sent to instance

We have 2 files of native IOS code which are UIViewController which i need to integrate in the app.

I have created a manager class which will act as the a bridge between react-native code.

Can you please look at code and help me figure out how to make it run as the native code is working fine in a standalone IOS project.

Following are the code:

WebViewMMS.js

import React from 'react';
import {
  View,  
  ScrollView
} from 'react-native';

import MMSView from './MMSView';

var WebViewMMS = React.createClass({

  getInitialState: function() {
    //console.log('inside get initial state :: ', this.props.url);
      return {
        url: this.props.url,       
      };
    },    

    render() {

      console.log('WebViewMMS this.state.url :: ',this.state.url);

      return(        
        <MMSView mmsUrl={this.state.url}/>       
      );      
    }  
});

module.exports = WebViewMMS;

MMSView.js

import React from 'react';
import { 
    View,
    ScrollView,
    Dimensions,
    requireNativeComponent
} from 'react-native';
const window = Dimensions.get('window');
class MMSView extends React.Component {
  render() 
  {
    console.log('MMSView  mmsUrl ::: ', this.props.mmsUrl);
    return(
        <RCTMMSView {...this.props} style={[{width:window.width, height:window.height}]}/>      
    );
  }
}

MMSView.propTypes = {
  /**
   * When this property is set with `url` for loading mms activity homework
   */
  mmsUrl: React.PropTypes.string,
};

var RCTMMSView = requireNativeComponent('RCTMMSView', MMSView);

module.exports = MMSView;

RCTViewManager.h

#ifndef RCTMMSViewManager_h
#define RCTMMSViewManager_h

#endif

#import "RCTViewManager.h"

@interface RCTMMSViewManager : RCTViewManager

@end

RCTMMSViewManager.m

#import <Foundation/Foundation.h>
#import "RCTMMSViewManager.h"
#import "RCTBridge.h"

#import "ViewController.h"  // Importing mms library for implementation

@implementation RCTMMSViewManager

RCT_EXPORT_MODULE()

@synthesize bridge = _bridge;

- (UIView *) view
{ 
  SubViewController *vc = [[SubViewController alloc] initWithEventDispatcher:self.bridge.eventDispatcher];

  NSLog(@"SubViewController x ::: %f",vc.view.frame.origin.x);
  NSLog(@"SubViewController y ::: %f",vc.view.frame.origin.y);
  NSLog(@"SubViewController width ::: %f",vc.view.frame.size.width);
  NSLog(@"SubViewController height ::: %f",vc.view.frame.size.height);

  return vc.view; // Change initialising with MMS to access function of initMMS by passing mmsUrl from RCT_EXPORT_VIEW_PROPERTY to load Activity homework.
}

- (dispatch_queue_t)methodQueue
{
  return dispatch_get_main_queue();
}

RCT_EXPORT_VIEW_PROPERTY(mmsUrl, NSString);

@end

ViewController.h this is the native ios code which needs to be integrated in app. there are some code functions i cant reveal due to confidentiality of client request, which is of native ios module, sorry for not adding it in the doubt.

#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <CoreAudio/CoreAudioTypes.h>

#import "RCTEventDispatcher.h"

@interface SubViewController : UIViewController<WKScriptMessageHandler>

@property (strong, nonatomic) WKWebView* webView;
@property NSURLRequest* request;

- (instancetype)initWitRequest:(NSURLRequest*)request;

@property (nonatomic, assign) NSString *mmsUrl;

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;

@end

ViewController.m

#import <Foundation/Foundation.h>
#import "ViewController.h"
#import <WebKit/WebKit.h>
#include <string.h>

#import "RCTBridgeModule.h"
#import "RCTEventDispatcher.h"

@implementation SubViewController
{    
    RCTEventDispatcher *_eventDispatcher;
}
@synthesize mmsUrl;

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
  NSLog(@"initWithEventDispatcher  :::: %@",eventDispatcher);
  if ((self = [super init])) {
    _eventDispatcher = eventDispatcher;
  }
  return self;
}

- (instancetype)initWitRequest:(NSURLRequest*)request
{
    if (self = [super init])
    {
        instance = self;

        WKWebViewConfiguration* cfg = [self configForInjection:[self mmsInjectionJS] forMainFrameOnly:NO];
        _webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:cfg];
        _webView.scrollView.bounces = NO;
        /*
        CGRect newFrame = _webView.frame;

        newFrame.size.height = newFrame.size.height - 64;
        [_webView setFrame:newFrame];*/

        [self.view addSubview:_webView];
        [_webView loadRequest:request];
        NSLog(@"initWitRequest loaded");
    }
    return self;
}

-(void) initMMS:(NSString *)mmsurl
{
    NSLog(@"initMMS :::: %@",mmsurl);
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:mmsurl]
                                            cachePolicy:NSURLRequestUseProtocolCachePolicy
                                            timeoutInterval:60.0];
    [self initWitRequest:request];
}
- (void)setMmsUrl:(NSString*)_mmsurl
{
  NSLog(@"setMmsUrl  ::: %@ ",_mmsurl);
  self.mmsUrl = _mmsurl;

  [self initMMS:_mmsurl];
}
@end

There is one method which injects JS code in Webview and some other native functions which process the website which is loaded in Webview, which i can't reveal here. Sorry but i basically need to call initMMS function which i can call when i receive a URL from my WebViewMMS.js file. which eventually will be set here in setMmsUrl Method.

Please help me out with the error i am facing.

Basically i just want to pass one web url from react-native code to the webview created in native ios project code to load it.

browniefed commented 7 years ago

I'm not an Objective-C person honestly, so I'm sorry I can't be much help. http://stackoverflow.com/questions/2455161/unrecognized-selector-sent-to-instance

browniefed commented 7 years ago

I'd recommend going into the reactiflux discord channel and asking, or alternatively don't follow my outdated blog post and check out recent libraries that have been built and follow those.

wjljack commented 4 years ago

RCT_EXPORT_VIEW_PROPERTY only can export UIView property ,not UIViewController