如何在iOS中调用被调用的应用程序中的openUrl方法?

时间:2015-09-15 08:03:31

标签: ios objective-c query-string openurl

我认为这是重复的,但我无法弄明白。

我必须使用openUrl方法从我的iOS应用中调用其他应用。完成其工作后,其他应用必须使用相同的方法返回到我的应用。我弄清楚如何调用其他应用程序并打开我的应用程序。我的问题是如何拦截返回我的应用程序。我需要检查查询字符串中的值。

我发现方法handleOpenURL拦截返回,我可以处理我的查询字符串。

在这里我被困 - 如何在我的ViewController中使用该信息?我在viewDidLoad中设置了断点,但没有被击中。我必须使用哪种方法?

修改

我的代码是(在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;
}

哪种方法正常。

在我的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.
}

我的网址:

网址标识符:xx.mydomain.MyUrlScheme

网址shcemes:MyUrlScheme

我的VC内部有断点(在上面显示的每个方法上)。

我使用以下字符串来调用其他应用:@"otherApp://openApp?param1=value1&callbackUrl=MyUrlScheme";

他们使用callbackUrl param从otherApp打电话给我。

3 个答案:

答案 0 :(得分:4)

您需要制作自己的自定义网址,请参阅下面的

How to implement Custom URL Scheme

定义应用程序的自定义URL方案都在Info.plist文件中完成。单击文件中的最后一行,然后单击" +"在右侧签名以添加新行。选择新项目的URL类型。添加完成后,点击"网址类型"旁边的灰色箭头。显示"项目0"。将您的URL标识符设置为唯一的字符串 - 类似于com.yourcompany.yourappname。

在您设置了网址标识符后,选择该行并点击" +"再次签名,并为URL Schemes添加一个新项目。然后单击" URL Schemes"旁边的灰色箭头。揭示"项目0"。将Item 0的值设置为您的URL方案名称。

enter image description here

处理自定义网址调用

为了让您的应用在收到自定义URL调用时进行响应,您必须在应用程序委托类中实现应用程序:handleOpenURL方法:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
    // your code
}

解析自定义网址

网址有几个部分:

方案://主机/路径查询

可以通过传递给应用程序的NSURL对象检索URL的各个部分:handleOpenURL方法。如果您有一个相当简单的URL命名方案,并希望允许访问特定的页面/键,您可以使用主机名:

[url host]的自定义网址值:

myapp://page1   page1
myapp://page2   page2
myapp://otherPage   otherPage

要将数据传递到您的应用中,您需要使用查询字符串。这是从url解析查询字符串的简单方法:

- (NSDictionary *)parseQueryString:(NSString *)query {
    NSMutableDictionary *dict = [[[NSMutableDictionary alloc] initWithCapacity:6] autorelease];
    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;
}

测试自定义网址

您可以在模拟器中轻松测试您的URL方案。只需在其中一个视图中添加一个测试按钮,然后按如下方式实现IBAction方法:

- (IBAction)getTest:(id)sender {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"myappscheme://test_page/one?token=12345&domain=foo.com"]];
}

然后在你的app委托中,实现应用程序:handleOpenURL方法:

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

最后,如果您正在寻找在任何地方接收数据的方法,您可以使用这两个方案。 您可以简单地使用Local notificationNSUserDefault

<强> NSUserDefault

- (BOOL)application:(UIApplication *)application handleopenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
     NSUserDefaults *userDefaults=[[NSUserDefaults alloc] init];
     [userDefaults synchronize];
     NSString *status = [defaults stringForKey:@"any status"];
}

本地通知

- (BOOL)application:(UIApplication *)application handleopenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
        return;
    localNotif.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:VAL, @"value", nil];

    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}

答案 1 :(得分:1)

如果未完全调用viewDidLoad,请尝试使用viewWillAppearviewDidAppear方法。

例如:

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

答案 2 :(得分:1)

当应用程序的ViewController启动时,从NSUserdefaults中的其他应用程序存储状态,将状态从NSUserdefaults提取到NSString中,并将其作为警报提升。

致电handleopenURL

中的appdelegate
- (BOOL)application:(UIApplication *)application handleopenURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
     NSUserDefaults *defaults=[[NSUserDefaults alloc] init];
     [defaults synchronize];
     NSString *status = [defaults stringForKey:@"status string from other app"];
}