I am trying to setup react-native application but I got stuck doing really basic changes to AooDekegate.m file. I have no experience in xCode. I have no idea what am I doing.
I was following this tutorial http://www.proreactnative.com/How-to-Develop-iOS-Apps-on-Linux-Using-React-Native/ . I got stuct doing Edit AppDelegate.m.
Could you please help me out?
This is my code:
/** * Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#implementation AppDelegate
NSDictionary *appDefaults = #{ // ERROR !! Initializer element is not a compile-time constant
#"host_preference": #"localhost",
#"port_preference": #"8081",
};
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; // ERROR !! Expected ']'
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
NSString *host = [[NSUserDefaults standardUserDefaults] stringForKey: #"host_preference"];
NSString *port = [[NSUserDefaults standardUserDefaults] stringForKey: #"port_preference"];
NSString * urlString = [NSString stringWithFormat: #"http://%#:%#/index.ios.bundle?platform=ios&dev=true", host, port];
jsCodeLocation = [NSURL URLWithString: urlString];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:#"AwesomeProject"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
#end
you do initialize a data object outside of a function, which would be fine for certain types.
In this case, I would rather declare the given values as constants or simply in the method that makes use of your variables:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *appDefaults = #{
#"host_preference": #"localhost",
#"port_preference": #"8081",
};
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
// Rest of your code
...
}
In addition:
If you do not need these values later on again (I don't know the react native framework in detail). You don't have to use NSUserDefaults for this. (NSUserDefaults are an attempt to persist data for the application).
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
NSString *host = #"localhost";
NSString *port = #"8081";
NSString * urlString = [NSString stringWithFormat: #"http://%#:%#/index.ios.bundle?platform=ios&dev=true", host, port];
jsCodeLocation = [NSURL URLWithString: urlString];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:#"AwesomeProject"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
Related
Production build crashes on launch with error
'NSInvalidArgumentException', reason: '-[EXExpoAppDelegate
appController:didStartWithSuccess:]: unrecognized selector sent to
instance 0x600001dcad60'
But everything works great on development mode. It builds and archives without any errors also. I use React-Native.
My AppDelegate.mm
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTConvert.h>
#import <React/RCTAppSetupUtils.h>
#import "RNBootSplash.h"
#if RCT_NEW_ARCH_ENABLED
#import <React/CoreModulesPlugins.h>
#import <React/RCTCxxBridgeDelegate.h>
#import <React/RCTFabricSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <react/config/ReactNativeConfig.h>
#endif
#interface AppDelegate () <RCTBridgeDelegate>
#property (nonatomic, strong) NSDictionary *launchOptions;
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTAppSetupPrepareApp(application);
// self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]];
#if RCT_NEW_ARCH_ENABLED
_contextContainer = std::make_shared<facebook::react::ContextContainer const>();
_reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
_contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
_bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
#endif
// UIView *rootView = RCTAppSetupDefaultRootView(bridge, #"t7travel", nil);
self.launchOptions = launchOptions;
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
#ifdef DEBUG
[self initializeReactNativeApp];
#else
EXUpdatesAppController *controller = [EXUpdatesAppController sharedInstance];
controller.delegate = self;
[controller startAndShowLaunchScreen:self.window];
#endif
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:self.launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:#"main" initialProperties:nil];
id rootViewBackgroundColor = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"RCTRootViewBackgroundColor"];
if (#available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[super application:application didFinishLaunchingWithOptions:launchOptions];
[RNBootSplash initWithStoryboard:#"BootSplash" rootView:rootView];
return YES;
}
- (RCTBridge *)initializeReactNativeApp
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:self.launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:#"main" initialProperties:nil];
id rootViewBackgroundColor = [[NSBundle mainBundle] objectForInfoDictionaryKey:#"RCTRootViewBackgroundColor"];
if (#available(iOS 13.0, *)) {
rootView.backgroundColor = [UIColor systemBackgroundColor];
} else {
rootView.backgroundColor = [UIColor whiteColor];
}
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[RNBootSplash initWithStoryboard:#"BootSplash" rootView:rootView];
return bridge;
}
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
return #[];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index"];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
#if RCT_NEW_ARCH_ENABLED
#pragma mark - RCTCxxBridgeDelegate
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
{
_turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
delegate:self
jsInvoker:bridge.jsCallInvoker];
return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
}
#pragma mark RCTTurboModuleManagerDelegate
- (Class)getModuleClassFromName:(const char *)name
{
return RCTCoreModulesClassProvider(name);
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
{
return nullptr;
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
initParams:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return nullptr;
}
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
{
return RCTAppSetupDefaultModuleFromClass(moduleClass);
}
#endif
#end
Problem was very simple. expo-updates library changed configuration for an iOS and there are lines of code that I needed to add in my AppDelegate.mm.
- (void)appController:(EXUpdatesAppController *)appController didStartWithSuccess:(BOOL)success {
appController.bridge = [self initializeReactNativeApp];
}
For finding all configurations look at docs
we have create a bridge react native to native for send location.
we use react RCT_EXPORT_METHOD for callback.
we create a object c global variable "coordinate" to store our location value and send to callback method
when call RCT_EXPORT_METHOD for callback our global variable "coordinate" show null in RCT_EXPORT_METHOD
Also we append static value in callback they send value to react native
RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback )
{
callback(#[#"Test"]);
}
how to pass global variable value in callback or any other way to send my location data to react native
My .m file code:
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <Firebase.h>
#implementation AppDelegate{
RCTRootView *rootView;
NSMutableDictionary *coordinate;
}
RCT_EXPORT_MODULE();
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
*)launchOptions
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"OHCSMobile1"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
if ([FIRApp defaultApp] == nil) {
[FIRApp configure];
}
self.manager = [[APScheduledLocationManager alloc] initWithDelegate:self];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index"
fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
-(void)scheduledLocationManager:(APScheduledLocationManager *)manager didFailWithError:
(NSError *)error{
NSLog(#"error");
}
-(void)scheduledLocationManager:(APScheduledLocationManager *)manager didUpdateLocations:
(NSArray<CLLocation *> *)locations{
NSLog(#"locations");
CLLocation * location = locations[0];
double latitute = location.coordinate.latitude;
double longitute = location.coordinate.longitude;
coordinate = [[NSMutableDictionary alloc] init];
[coordinate setValue:[NSNumber numberWithDouble: latitute] forKey:#"LAT"];
[coordinate setValue:[NSNumber numberWithDouble: longitute] forKey:#"LONG"];
NSLog(#"%#oordinate", coordinate);
}
-(void)scheduledLocationManager:(APScheduledLocationManager *)manager
didChangeAuthorization:
(CLAuthorizationStatus)status{
NSLog(#"Authorization");
if (status == kCLAuthorizationStatusAuthorizedAlways || status ==
kCLAuthorizationStatusAuthorizedWhenInUse) {
// The user accepted authorization
[self.manager startUpdatingLocationWithInterval:30 acceptableLocationAccuracy:100];
}
}
RCT_EXPORT_METHOD(findEvents:(RCTResponseSenderBlock)callback )
{
if(coordinate != nil){
callback(#[coordinate]);
}else{
callback(#[#"null"]);
}
}
#end
PLease Help
Hi firstly I learning react-native and I use onesignal for notification everything awesome but
sometimes iphone 6s hasnt token one signal error is 'Apns Delegate Never Fired' but 6 plus alwasy has a token and background notification very nice. If the application is open while sending a notification, the notification does not occur above. It occurs on a dialog screen.
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"doyurunbenicomproje"
initialProperties:nil];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:#"main" withExtension:#"jsbundle"];
#endif
}
#end
check your os version between on 6s and 6plus.
If the app is foreground,notification will show on your screen, if the app is background,notification will show above.
EDIT
add this code to your AppDelegate.m
(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(#"didFailToRegisterForRemoteNotificationsWithError %#", error);
}
kOSSettingsKeyInFocusDisplayOption=2 I aded this code and notifications will display as normal notifications.
I'm sitting here doing the quickstart on AppHub after finishing my React Native project, and when it gets to the point of trying to uncomment out these lines, I get a No bundle URL present error.
AHBuild *build = [[AppHub buildManager] currentBuild];
jsCodeLocation = [build.bundle URLForResource:#"main"
withExtension:#"jsbundle"];
How can I fix this?
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[AppHub setApplicationID:#"25QLeX4o6N8Xm0naFxnx"];
NSURL *jsCodeLocation;
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:#"index.ios" fallbackResource:nil];
/**
* OPTION 3 - AppHub
*
* Load cached code and images from AppHub.
*
*/
AHBuild *build = [[AppHub buildManager] currentBuild];
jsCodeLocation = [build.bundle URLForResource:#"main"
withExtension:#"jsbundle"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:#"Hang"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
Documentation is rather poor in this regards and code be more informative. When you archive the application the code will work - it just won't in debug mode
It does state that to uncomment the following code when deploying.
AHBuild *build = [[AppHub buildManager] currentBuild];
jsCodeLocation = [build.bundle URLForResource:#"main"
withExtension:#"jsbundle"];
To test this on the simulator change the schema to release by going to
Product > Schema > Edit Schema > Change build configuration to release
This is basically what an archive does.
I'm very new to React Native (iOS) and I have read a lot about Bridging, however I cannot seem to make this working.
I need to be able to send an object/string from AppDelegate to JavaScript. My AppDelegate returns a UserName which is retrieved by a native code in one of my methods inside AppDelegate.
I tried to use in AppDelegate.m
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
and then
#synthesize bridge = _bridge;
and inside my method
NSString *eventName = notification.userInfo[#"name"];
[self.bridge.eventDispatcher sendAppEventWithName:#"EventReminder"
body:#{#"name": eventName}];
but none of the above works and I'm getting errors. Do I need to do anything to AppDelegate.h as well?
Can anyone please help me? What is the easiest way to sent data from native to javascript?
UPDATE:
I found a workaround, but I don't think it's effective as I'm calling RCTRootView twice. First to load the app with initialProperties nil, like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
jsCodeLocation = [NSURL URLWithString:#"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:#"myApp"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
[self getUsername];
}
And for the second time when I retrieve a UserName I then update initialProperties like this:
-(void) getUsername {
//3rd party code to retrieve the username
NSString *username = username
NSURL *jsCodeLocation;
jsCodeLocation = [NSURL URLWithString:#"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:jsCodeLocation moduleProvider:nil launchOptions:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:#"myApp"
initialProperties: #{#"username" : username}];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
}
By doing the way above I'm then able to send and receive username via this.props in JavaScript.
But like I said, I'm not sure this is an effective way as I'm calling RCTRootView twice.
Any help is appreciated please.
You could, instead of trying to put it in the initial launch code on the iOS side, put it in a Native Module that you export a function to return the information from. See React Natives official documentation on it: https://facebook.github.io/react-native/docs/native-modules-ios.html