Search code examples
iosobjective-cquery-stringopenurl

How to manage openUrl method inside called application in iOS?


I suppose that this is duplicate but I can not figure it out.

I have to call other app from my iOS app using openUrl method. After finishing its work the other app must return to my app using the same method. I figure out how to call the other App and its open my App too. My problem is how to intercept the return to my App. I need to check the value from query string.

I find that method handleOpenURL intercepts return and I can handle my query string.

And here I am stuck - how to use that info inside my ViewController? I set breakpoint in viewDidLoad but it was not hit. Which method I have to use?

EDIT:

My Code is (inside AppDelegate):

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    NSLog(@"url recieved: %@", url);
    NSLog(@"query string: %@", [url query]);
    NSLog(@"host: %@", [url host]);
    NSLog(@"url path: %@", [url path]);
    NSDictionary *dict = [self parseQueryString:[url query]];
    NSLog(@"query dict: %@", dict);

    return YES;
}

- (NSDictionary *)parseQueryString:(NSString *)query {
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:6];
    NSArray *pairs = [query componentsSeparatedByString:@"&"];

    for (NSString *pair in pairs) {
        NSArray *elements = [pair componentsSeparatedByString:@"="];
        NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSString *val = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

        [dict setObject:val forKey:key];
    }
    return dict;
}

Which works fine.

Inside my ViewController (VC):

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self setNeedsStatusBarAppearanceUpdate];

    // Instantiate App singleton
    singApp = [PESsingApplication sharedInstance];

    @try {

        // Localize resources using currently saved setting for language
        [self setLocalizedResources];

        // Init visual buttons
        [self baseInit];

        // Add code for keyboard management
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardShow:)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardHide:)
                                                     name:UIKeyboardWillHideNotification
                                                   object:nil];

        CGRect screenRect = [[UIScreen mainScreen] bounds];
        _screenHeight = screenRect.size.height;
        _screenWidth = screenRect.size.width;

    }
    @catch (NSException *exception) {
        [self throwUnknownException:exception];
    }
}

-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

My url:

URL identifier: xx.mydomain.MyUrlScheme

URL shcemes: MyUrlScheme

I have breakpoints inside my VC (on each of the method shown above).

I use following string to call other app: @"otherApp://openApp?param1=value1&callbackUrl=MyUrlScheme";

They call me from the otherApp using callbackUrl param.


Solution

  • If your viewDidLoad is not called perfectly try in viewWillAppear or viewDidAppear method.

    For example purpose:

    - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    
    NSDictionary *dict = [self parseQueryString:[url query]];
    NSLog(@"query dict: %@", dict);
    
    // add dictionary to standardUserDefaults for saving purpose, like 
    
     [[NSUserDefaults standardUserDefaults] setObject:dict forKey:@"DicKey"]; 
     [[NSUserDefaults standardUserDefaults] synchronize];
    
    // add code for navigation/present view controller
    
      UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" 
                                                             bundle: nil];
    YourViewController *yourController = (YourViewController *)[mainStoryboard 
      instantiateViewControllerWithIdentifier:@"YourViewControllerID"];
    self.window.rootViewController = yourController;
    
    return YES;
    }
    

    for retrieve

    - (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    NSMutableDictionary *mutableRetrievedDictionary = [[[NSUserDefaults standardUserDefaults] objectForKey:@"DicKey"] mutableCopy];
    
     // here parse the dictionary and do your work here, when your works is over 
    
     // remove the key of standardUserDefaults 
    
     [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"DicKey"];
     [[NSUserDefaults standardUserDefaults] synchronize];
    }