Firstly, let me explain the app structure of how it is maintained
I have here two applications
First, a native objective-c based iOS application which is working perfectly, the task of the native application is to launch the camera once the application is launched, capture image and do some OpenGL processing, display the image captured.
This is done by calling ViewController class within my main.m file as shown below
#import <UIKit/UIKit.h>
#import "ViewController.h"
int main(int argc, char * argv[]) {
#autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([ViewController class]));
}
}
This ViewController class has some properties which gets the app up & running & launches a storyboard
Now for the cordova app, I created a plugin and integrated all the native files into the plugin, so once we add the plugin it adds all the resources including source files, resource files, assets, storyboard etc.
When we trigger the plugin within javascript, it will call the native class CustomPlugin which is the starting point of the plugin, below are the header & implementation code of the same
CustomPlugin.h
#import <Cordova/CDV.h>
#import "ViewController.h"
#interface CustomPlugin : CDVPlugin
- (void) pluginInitialize;
- (void) process:(CDVInvokedUrlCommand*)command;
#end
CustomPlugin.h
#import "CustomPlugin.h"
#import "ViewController.h"
#interface CustomPlugin()
#end
#implementation CustomPlugin
NSString *_routeChangedCallbackId;
#synthesize viewc;
- (void) pluginInitialize {
NSLog(#"CustomPlugin:pluginInitialize");
_routeChangedCallbackId = nil;
}
- (void) process:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:#"test"];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
#end
This implementation currently just sends back the response sample message to the caller
What I want to achieve is to be able to invoke/launch/initialize the ViewController feature as is working in native
Please oblige me for the lengthy question but it was required since I'm too much new to iOS.
The pluginInitialize method should be called between the CDVPluginResult and commandDelegate methods:
- (void) process:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:#"test"];
[self pluginInitialize];
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html
Successfully able to resolve my issue of launching a ViewController from Cordova plugin, refer the below post
Plugin with UIViewController
Related
I'm following the example posted in the official doc for native module ios. I've set up everything, build it and run the application.
// CAL.h
#import <React/RCTBridgeModule.h>
#interface CAL : NSObject <RCTBridgeModule>
#end
// CAL.m
#import <React/RCTLog.h>
#import "CAL.h"
#implementation CAL
RCT_EXPORT_MODULE(CAL);
RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name location:(NSString *)location)
{
RCTLogInfo(#"Pretending to create an event %# at %#", name, location);
}
#end
But when I check NativeModules from react-native it shows an empty object - {}.
I'm not sure what I'm missing.
Like #chengsam mentioned, when I access CAL directly in the following manner it works.
const { CAL } = NativeModules;
or
NativeModules.CAL
CAL still held the native module while NativeModules directly displayed {}
Note: I am new to Objective C
I have implemented the CXCallObserverDelegate callChanged delegate in my custom React Native module but it is not invoked when i receive a VOIP call
In didFinishLaunchingWithOptions of AppDelegate
CallManager *manager = [CallManager new];
[manager someMethod:#"Hoola"]; // sending a test string to print
In CallManager.m
#import "CallManager.h"
#import "RNCallKeep.h"
#implementation CallManager
RCT_EXPORT_MODULE();
-(void)someMethod: (NSString *)someString
{
NSLog(#"Hello world callObserver %#", someString); // Hoola string gets printed here means this method is working
CXCallObserver *callObserver = [[CXCallObserver alloc] init];
self.callObserver = callObserver;
[callObserver setDelegate:(id)self queue:nil];
}
-(void)callObserver:(CXCallObserver *)callObserver callChanged:(CXCall *)call {
NSLog(#"Hello world callObserver"); // this doesnt get printed when call is received or status changes
}
#end
In my CallManager.h file
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <CallKit/CallKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface CallManager : NSObject<RCTBridgeModule, CXCallObserverDelegate>
#property (atomic, strong) CXCallObserver *callObserver;
- (void)someMethod: (NSString *)someString;
#end
NS_ASSUME_NONNULL_END
App is compiling fine and launching and performing all things but when I receive a VOIP call and CallKIT UI is invoked, i don't get call status changed events on accept or reject. Note that NSLogs are printed correctly, i put them there for debug and they are working.
Setup:
react-native v0.41.2
react-native-cli v2.0.1
xcode v8.2.1
node v6.9.5
I started using RN v0.41.2 and found that v0.40 introduced a namespace breaking change stating that all react imports should be prepended with React/.
But the documentation shows otherwise.
So, is doing this the only thing that I have to do:
// RNLib.h
#import "RCTBridgeModule.h"
#interface RNLib : NSObject <RCTBridgeModule>
#end
to
// RNLib.h
#import <React/RCTBridgeModule.h>
#interface RNLib : NSObject <RCTBridgeModule>
#end
Or do I have to do it for my imports as well:
// RNLib.m
#import "RNLib.h"
#implementation RNLib
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(helloWorld:(NSString *)world)
{
return [NSString stringWithFormat:#"hello %#", world];
}
#end
to
// RNLib.m
#import <React/RNLib.h>
#implementation RNLib
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(helloWorld:(NSString *)world)
{
return [NSString stringWithFormat:#"hello %#", world];
}
#end
I'm currently unable to create a library and link it correctly (I've tried multiple things).
// somthing.m
#import "something.h"
This above line refers to something.h file which is present in same directory of the implementation file.
Only Modules from the React should be prepended with "React/RCTWhatever.h".
This has effective change in Header Search Paths of Xcode when you are linking the Native Libraries.
Thanks
I have recently made some significant changes to a Corona Enterprise app I am writing for iOS. The code was using a .xib file to launch the AppDelegate, and I have removed that and I am loading a different AppDelegate in my main.mm
The following is my main.mm
//
// main.mm
// Examples
//
#import <UIKit/UIKit.h>
#import "CoronaApplicationMain.h"
#import "MyAppDelegate.h"
int main(int argc, char *argv[])
{
#autoreleasepool
{
CoronaApplicationMain( argc, argv, [MyAppDelegate class] );
}
return 0;
}
This is my MyAppDelegate.h
//
// MyAppDelegate.h
//
#import <Foundation/Foundation.h>
#import "CoronaDelegate.h"
#interface MyAppDelegate : NSObject< CoronaDelegate >
#end
And finally, this is MyAppDelegate.mm
//
// MyAppDelegate.mm
//
#import "MyAppDelegate.h"
#import "CoronaRuntime.h"
#import "CoronaLua.h"
#implementation MyAppDelegate
- (void)willLoadMain:(id<CoronaRuntime>)runtime
{
NSLog ( #"willLoadMain" );
}
- (void)didLoadMain:(id<CoronaRuntime>)runtime
{
NSLog ( #"didLoadMain" );
}
#end
I am not posting my main.lua as it seem irrelevant. If I am not posting something that is important, then apparently I am assuming that it is not.
When I run the app in xcode iOS simulator, I get a black screen and my willLoadMain and didLoadMain are never called.
Please let me know if you see something that I am missing.
Thanks,
Roger
My problem was that somewhere I read that I should remove the .xib files (this was not needed). Once I re-added them to the project and updated the app-info.plist, everything began working again. Since I am rather new to Corona Enterprise, Lua and Objective C, I do not understand the details of why this failed and then began working. At any rate, this issue is now resolved.
I found similar questions on this site but not one that addresses the problem in a clear and basic way.
I have my ReadViewController.h and ReadViewController.m files along with my ChooseViewController.h and ChooseViewController.m files.
They both need to access the getProperties method which is currently in the ReadViewController.m file.
- (void) getProperties {
NSLog(#"Start getProperties");
//SOME CODE
NSLog(#"End getProperties");
}
Now ideally this will be in a third file called GeneralModel.m
Please give me a basic example of what code needs to be in the controller files for them to be able to call this method.
If this method Going to be used in many places in Application then in this case you should treat it as Global method and try to put this method in separate class may be type of NSObject Class.
#interface Utility :NSobject
- (void) getProperties
#end
#implementation Utility
- (void) getProperties {
NSLog(#"Start getProperties");
//SOME CODE
NSLog(#"End getProperties");
}
#end
Here Whenever you need that methods you just need to create the Object of Utility Class can access it easily wherever it needed.like
in ReadViewController just make object and access in this way
Utility * obje = [Utility alloc]init];
[obje getProperties ];
And One thing if you just talking about the App architecture ,Suppose you following the MVC in that Case you should keep your model(NSObject Type)Class for Making some DB call, Request call to server. Keep View Classes code Like UIView separately and put the Code inside Controller class only which needed to control the Logic of App.
Here is the Link which explain The MVC Architecture.
I hope it clears to you.
The solution I've implemented looks like this. I'll accept iOS-Developer's answer though since it set me on the right track.
//*********************
//ReadViewController.h
#import <UIKit/UIKit.h>
#import "GeneralModel.h"
#interface ReadViewController : UIViewController {
GeneralModel *generalModel;
}
#end
//*********************
//*********************
//ReadViewController.m
#import "ReadViewController.h"
#interface ReadViewController ()
#end
#implementation ReadViewController
NSArray *allProperties;
- (void) getProperties {
generalModel = [[GeneralModel alloc] init];
allProperties = [generalModel getProperties];
NSLog(#"ALLPROPERTIES: %#", allProperties);
[generalModel release];
}
//**********************
//**********************
//GeneralModel.h
#import <Foundation/Foundation.h>
#import "sqlite3.h"
#interface GeneralModel : NSObject {
}
-(NSArray *) getProperties;
#end
//**********************
//**********************
//GeneralModel.m
#import "GeneralModel.h"
#implementation GeneralModel
- (NSArray *) getProperties {
NSLog(#"Start getProperties");
NSArray *someProperties;
//Some nice code goes here for getting a lot of nice properties from somewhere else.
return someProperties
NSLog(#"End getProperties");
}
//***********************
If this method Going to be used in many places in Application then in this case you should treat it as Global method and try to put this method in separate class may be type of NSObject Class.
#interface Utility :NSobject
- (void) getProperties
#end
#implementation Utility
- (void) getProperties {
NSLog(#"Start getProperties");
//SOME CODE
NSLog(#"End getProperties");
}
#end
Here Whenever you need that methods you just need to create the Object of Utility Class can access it easily wherever it needed.like
in ReadViewController just make object and access in this way
Utility * obje = [Utility alloc]init];
[obje getProperties ];