change CustomViewController fields from AppDelegate - ios

I'm new to ios(android dev)
I'm handling opening my app from url, and i got the url in current method in my AppDelegate.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(#"Calling Application Bundle ID: %#", sourceApplication);
NSLog(#"URL scheme:%#", [url scheme]);
NSLog(#"URL query: %#", [url query]);
return YES;
}
There are certain params in my link which i'd like to use to fill the textField of my LoginViewController.
Can i communicate with LoginViewController from AppDelegate? consider that LoginViewController already didLoad.

You can define one property let’s say strName in appDelegate.
Then you have to assign it’s value from this method
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSLog(#"Calling Application Bundle ID: %#", sourceApplication);
NSLog(#"URL scheme:%#", [url scheme]);
NSLog(#"URL query: %#", [url query]);
//for example
self.strName = [url query];
return YES;
}
Now you can access this property from anywhere.
Create Instance of appDelegate In your viewController
#define AppDel ((AppDelegate *)[UIApplication sharedApplication].delegate)
Then assign as below
textfield.text = AppDel.strName;

You can communicate with your controller in several ways:
Hold instance in appDelegate and call methods.
Save your data in some sort of storage (UserDefault for ex.) and extract in in viewWillAppear or viewDidAppear methods.
Use your own observer pattern implementation or NotificationCenter

Related

Passing data from native to react native

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?

Can I possibly get the parameter in URL Scheme when my app set to not run in background?

I am trying to open my app using URL Scheme with a parameter on it, my problem is, is it possible to get the parameter when the app is set to not run in the background.
SampleApp-info.plist
<key>UIApplicationExitsOnSuspend</key>
<true/>
AppDelegate.m
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
{
NSLog(#"url recieved: %#", url);
NSLog(#"scheme: %#", [url scheme]);
NSLog(#"query string: %#", [url query]);
NSLog(#"host: %#", [url host]);
return YES;
}
When UIApplicationExitsOnSuspend is set to true and try to open my app from Safari, it's not creating any logs but when I remove the key it is working well. I have to restart my app to load the first viewcontroller and suspending it on the background is the best way, I think...
Can anyone help me on this? or a better way so I can reload my app starting in the first viewcontroller? Newbie here.
I really appreciate any help. Thank you and regards.
UIApplicationExitsOnSuspend Settings
You have to set UIApplicationExitsOnSuspend to false. URL Scheme Callback will not work with UIApplicationExitsOnSuspend set to true. If you want to have a simular behavior like UIApplicationExitsOnSuspend set to true just add the following code
- (void)applicationDidEnterBackground:(UIApplication *)application {
[super applicationDidEnterBackground:application];
exit(0);
}
First you have to make an entry in in Info.plist
e.g. entry your URL Scheme. In this case (in the picture) the callback will be blurry:// the identifier should be normally unique
Callback Implementation
For Pre iOS 9 swift
optional func application(_ application: UIApplication,
handleOpenURL url: NSURL) -> Bool {
NSLog("URL is %#", url)
return true
}
For Pre iOS 9 objective-c
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
// handler code here
NSLog(#"Url is %#, url);
return YES;
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
// handler code here
NSLog(#"Url is %#, url);
return YES;
}
IOS 9 objective-c
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<NSString *,
id> *)options {
NSLog(#"Url is %#", url);
return YES;
}
IOS 9 - Swift
optional func application(_ app: UIApplication,
openURL url: NSURL,
options options: [String : AnyObject]) -> Bool {
NSLog("URL is", NSURL)
return true
}
Test the callback
Just open the weburl in the example case blurry://test with the mobile safari on your Handy

How to replace - (BOOL)application: openURL: sourceApplication: annotation:(id)annotation

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)
}

Open IOS App Using URL Scheme and Pass Data For Registration

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];
}
}

My first iOS app. I have a UIWebView in my ViewController that I want to update

I have a UIWebView in my ViewController that I want to update when the UIApplicationDelegate is passed a URL, like
myApp://?changeWebView=newstuff
I am building the new URL fine based on the data I am passing in but I can't figure out how to update my UIWebView
I have this in my AppDelegate.m:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSLog(#"Calling Application Bundle ID: %#", sourceApplication);
NSLog(#"URL scheme:%#", [url scheme]);
NSLog(#"URL query: %#", [url query]);
NSLog(#"URL hash: %#", [url fragment]);
NSURL *newURL = [NSURL URLWithString:#"URL constructed with pieces of passed URL data"];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:newURL];
//now I want to update the UIWebview defined in my ViewController.h
return YES;
}
You can load the request in webView by using loadRequest
[self.myWebView loadRequest:requestObj];
put this line in your code
You can post notifications to let know your view controller that you can load webview.
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
NSLog(#"Calling Application Bundle ID: %#", sourceApplication);
NSLog(#"URL scheme:%#", [url scheme]);
NSLog(#"URL query: %#", [url query]);
NSLog(#"URL hash: %#", [url fragment]);
NSURL *newURL = [NSURL URLWithString:#"URL constructed with pieces of passed URL data"];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:newURL];
//Post Notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"loadRequest"
object:nil
userInfo:#{#"requestObj":requestObj}];
return YES;
}
Now in add notification observer in your viewController
-(void)viewDidLoad{
//Add observer for notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveEvent:) name:#"loadRequest" object:nil];
}
Write this method to load request in webView in your ViewController
- (void)receiveEvent:(NSNotification *)notification {
// handle event
NSURLRequest *requestObj = notification.userInfo[#"requestObj"];
[self.myWebView loadRequest:requestObj];
}
For starters, since you're doing this in the app delegate, you don't know that the view controller with the web view will be allocated. Because of this, you have a couple different options.
First, you could create a property (#property (nonatomic, weak) UIViewController *viewController;) in your app delegate. When your view controller loads, set this property to the view controller with the web view so you have a reference to it in the app delegate.
Second, you can send an NSNotification that also sends the url. The benefit to this is down the road you may want to send this url to many different classes, which NSNotification allows. Each class can individually add themselves as observers for the notification. Here's an example: Send and receive messages through NSNotificationCenter in Objective-C?

Resources