My application has the following steps:
Send file with own extension to user's email
When file is opened, the app is started (after user has select it)
Now I want to use the data from the file.
But how?
I added following function to my AppDelegate.m file in Xcode.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if (url){
NSString *information = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
UIViewController *rootViewController = [UIViewController new];
//this is not the way to display this on the screen
NSLog(#"The file contained: %#",information);
}
return YES;
}
Is it possible to use this information string in react-native? What do I need to add to use it as 'this.props.information' in my react-native app?
Related
I want to use both Firebase UI (for signup/login) and Facebook SDK (for sharing/posting) in my React Native app.
Both SDKs want to control the application:(UIApplication *)app openURL:(NSURL *)url handler.
Here's Facebook openURL code and Firebase UI openURL.
What is the correct way to combine the two snippets? I've come up with the code below, but neither SDK explains what URLs do they handle and when, so I'm not sure which one should execute first?
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
NSString *sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey];
id annotation = options[UIApplicationOpenURLOptionsAnnotationKey];
BOOL handled = [[FUIAuth defaultAuthUI] handleOpenURL:url sourceApplication:sourceApplication];
if (!handled) {
handled = [[FBSDKApplicationDelegate sharedInstance] application:app
openURL:url
sourceApplication:sourceApplication
annotation:annotation
];
}
return handled;
}
I'm building SDK for my product and there will be no app delegate class. I used Dropbox Integration in my SDK, so I'm bound to use following method.
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
NSString *stringUrl = [url absoluteString];
if ([stringUrl containsString:#"cancel"]) {
// Handle if user cancelled the login
[[NSNotificationCenter defaultCenter] postNotificationName:#"dropboxRegistrationCancel" object:self];
return NO;
}
if ([[DBSession sharedSession] handleOpenURL:url]) {
if ([[DBSession sharedSession] isLinked]) {
NSLog(#"App linked successfully!");
// At this point you can start making API calls
[[NSNotificationCenter defaultCenter] postNotificationName:ApplicationComeBackFromDropBoxLoginPage object:self];
}
return YES;
}
// Add whatever other url handling code your app requires here
return NO;
}
So Issue is there is no app delegate than how can use above method?
Or any alternate solution for this to use this in another class (like to inherit UIResponder class).
Looking for help.
If you are building a SDK with no appDelegate, then well, you have nothing to do. It will be in your project where you will be using your sdk that you will have to add this line.
By the way, the line NSString *stringUrl = [url absoluteString]; is absolutly useless since you are not using stringUrl later on, and the
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
// NSString *stringUrl = [url absoluteString];
return YES;
}
just means: yes you can quit my app to open another app when the user click on a link.
No biggy....
Well I tried my best to resolve this but had absoultely no luck.
I have this paragraph that use to work properly. But need to resolve the deprecate method.
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(#"%#",url.scheme);
NSString *path = [[NSBundle mainBundle] pathForResource: #"Info" ofType: #"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile: path];
NSString *str = [NSString stringWithFormat:#"fb%#",[dict objectForKey: #"FacebookAppID"]] ;
BOOL result = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation
];
if (result) {
return YES;
}
return [self.instagram handleOpenURL:url];
}
I see that it is now deprecated.
iOS (4.2 and later) Deprecated:Use application:openURL:options: instead. Which produces the following. But this is not called. What am I missing?
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
NSLog(#"%#",url.scheme);
NSString *path = [[NSBundle mainBundle] pathForResource: #"Info" ofType: #"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile: path];
NSString *str = [NSString stringWithFormat:#"fb%#",[dict objectForKey: #"FacebookAppID"]] ;
BOOL result = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:annotation
];
if (result) {
return YES;
}
return [self.instagram handleOpenURL:url];
}
Thank you in advance for reviewing and any help is greatly appreciated.
The method "application:openURL:sourceApplication:annotation:" is deprecated from iOS9 onwards. So basically as #user2559325 suggests , this call back will not work in devices below iOS9. Please refer the following SDK interface.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(nullable NSString *)sourceApplication annotation:(id)annotation
NS_DEPRECATED_IOS(4_2, 9_0, "Please use application:openURL:options:")
Look at this post. It's is in swift but its basically the same implementation.
In objective-c it would be something like this
NSString *sourceApplication = options[UIApplicationOpenURLOptionsSourceApplicationKey];
return [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:sourceApplication
annotation:nil];
The method you are using is available from iOS 9.0 onwards. It will not be called in devices below iOS 9.0.
Also for it to work in iOS 9+ devices. You have to add the LSApplicationQueriesSchemes key to your Info plist
LSApplicationQueriesSchemes (Array - iOS) Specifies the URL schemes
you want the app to be able to use with the canOpenURL: method of the
UIApplication class. For each URL scheme you want your app to use with
the canOpenURL: method, add it as a string in this array. Read the
canOpenURL: method description for important information about
declaring supported schemes and using that method.
To learn about the converse operation of registering the URL schemes
an app can handle, read the description of the CFBundleURLTypes key.
This key is supported in iOS 9.0 and later.
Here is the simple solution for this in Swift 3.
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
}
i have implemented URL Scheme in my App so that whenever i click the URL, it will open up my app. I have also inserted some request in the URL such as
Yuvtime//:?registerName=Puppy&Passwords=67825
and i use the openUrl in AppDelegate to handle the processing of the URL and pass the data (registerName=Puppy&Passwords=67825`) to my rootViewController which is the registration page of my app, the code is as shown below.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
// Check the calling application Bundle ID
if ([[url scheme] isEqualToString:#"yuvitime"])
{
NSLog(#"Calling Application Bundle ID: %#", sourceApplication);
NSLog(#"URL scheme:%#", [url scheme]);
self.yuvitimeRequest = [url query];
NSLog(#"URL query: %#", yuvitimeRequest);
return YES;
}
else
return NO;
}
And in the RegistrationviewController, I implemented the code as follows.
-(void)viewWillAppear:(BOOL)animated{
[super viewDidAppear:animated];
AppDelegate * myAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.requestFromURL = myAppDelegate.yuvitimeRequest;
NSLog(#"%# hello google", self.requestFromURL);
if (self.requestFromURL.length > 0){
self.isRequestFromURL = YES;
}
if(self.isRequestFromURL == YES){
self.mainViewController.joinRoomName = self.requestFromURL;
self.isRequestFromURL = NO;
self.requestFromURL = #"";
[self presentViewController:self.mainViewController animated:YES completion:nil];
}
}
However, the problem i encounter is that:
If the user already has its app opened, this viewWilAppear in the RegistrationViewController will not be called again, so the data will not be passed automatically from the URL. (Only by killing the app, and click the URL will the data be passed as what we initially desired).
I also understand that when an App is already open and called again, only
(void)applicationWillEnterForeground:(UIApplication *)application &
(void)applicationDidBecomeActive:(UIApplication *)application
will be called in sequence in the app delegate. But somehow i stuck on how do i pass data to my registrationViewController from these two methods and if i can manage to do it in these two application methods, that would mean that my app checks every time on whether there is any registration data available from URL when the app comes to the foreground.
Since we already have the
(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
to handle the URL scheme, is it possible that we only check once without using the foreground and didBecomeActive app delegate functions when we click the URL?
EDIT: After implementing URL scheme, whenever you click a URL, a delegate method in AppDelegate.m will be triggered.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
This is also the function that will enable us to process the URL in our app and pass it around to other viewControllers.
I was kinda thinking, is there a way that we can implement a notification/function such that only when this openURL function is called, we then call the triggerURL function in registrationViewController.
Just out of curiosity!
Thanks
Regards
In your RegistrationViewController, you can register for UIApplicationDidBecomeActiveNotification and get notified of application being awakened even when your view controller was already loaded.
Add this line in your loadView:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(triggerURL) name:UIApplicationDidBecomeActiveNotification object:[UIApplication sharedApplication]];
This will allow the function updateSettings to be called every time your app wakes. Also remember to remove this listener at the end by:
[[NSNotificationCenter defaultCenter] removeObserver:self];
in your dealloc method.
Post that, this is how your viewWillAppear & triggerURL will look like:
- (void)viewWillAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self triggerURL];
}
- (void)triggerURL {
AppDelegate * myAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.requestFromURL = myAppDelegate.yuvitimeRequest;
NSLog(#"%# hello google", self.requestFromURL);
if (self.requestFromURL.length > 0){
self.isRequestFromURL = YES;
}
if(self.isRequestFromURL == YES){
self.mainViewController.joinRoomName = self.requestFromURL;
self.isRequestFromURL = NO;
self.requestFromURL = #"";
[self presentViewController:self.mainViewController animated:YES completion:nil];
}
}
I have an issue with URL Scheme in plist file as "m.zameen.com"
but i type this in iPhone's safari browser not op[en but when i open using :// it opened
// In AppDelegate.m file
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
if([[url host] isEqualToString:#"page"]){
if([[url path] isEqualToString:#"/main"]){
[self.mainController setViewControllers:#[[[DLViewController alloc] init]] animated:YES];
}
else if([[url path] isEqualToString:#"/page1"]){
[self.mainController pushViewController:[[Page1ViewController alloc] init] animated:YES];
}
return YES;
}
else{
return NO;
}
}
// In DLViewController.m file
- (IBAction)page1Clicked:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"m.zameen.com://page/page1"]];
}
// In Page1ViewController.m file
- (IBAction)mainPageClicked:(id)sender {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"m.zameen.com://page/main"]];
}
In your project Info tab, add a new URL Type with the scheme you want to use to open the app, for example 'myAwesomeAppScheme', using your app bundle identifier 'com.myCompany.myAwesomeApp' in the identifier field and the scheme you want in the URL Schemes field:
Then in you app delegate you can check if the opened url has your scheme with something like this
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
if ([url.scheme isEqualToString:#"myAwesomeAppScheme"]) {
...
}
}
And finally to open the app from an external app, the link has to be something like myAwesomeAppScheme://parameters/for/opening/viewcontrollers?otherParam=blahblah