注意:自从引入自定义URL方案以来,这篇文章一直是博客上最热门的内容。虽然是相同的,但有一些细微的变化。这是对最新的iOS和Xcode版本的原始帖子的重写。

iPhone / iOS SDK最酷的功能之一就是应用程序能够将其自身“绑定”到自定义URL方案,并将该方案用于从浏览器或其他应用程序启动应用程序。


注册自定义URL方案

第一步是创建自定义URL方案 - 首先定位并单击Xcode Project Navigator中的项目info.plist。随着plist显示在右窗格中,右键单击列表,然后选择Add Row:

从列表中向下滚动并选择URL类型。


打开方向箭头,您将看到项目0,字典条目。展开项目0,您将看到URL标识符,字符串对象。此字符串是您定义的自定义URL方案的名称。建议确保您反转域名的名称的唯一性,如com.yourCompany.yourApp。


点击项目0,并添加一个新行,从下拉列表中选择URL方案,然后点击Enter完成行插入。


通知URL方案是一个数组,允许为应用程序定义多个URL方案。


展开阵列并点击项目0。您可以在此定义自定义URL方案的名称。输入名称,不要追加:// - 例如,如果您输入iOSDevApp,您的自定义网址将是iOSDevApp://


以下是完整定义如何看待这一点:


虽然我很欣赏Xcode在使用描述性名称时的意图,但我发现看到创建的实际键有帮助。这是一个方便的技巧,右键单击plist并选择显示原始键/值,输出如下所示:


还有另一种输出格式,也有优点,XML,因为它更容易看到字典和嵌套数组及其条目的结构。点击plist,此时选择Open As - 源代码:


从Safari调用自定义URL方案

通过定义URL方案,我们可以运行一个快速测试来验证应用程序可以如预期的使用URL来调用。在我们这样做之前,我将创建一个准系统UI,以便我们可以使用自定义URL来识别该应用。该应用程序只包含一个带有自定义URL的应用程序的UILabel。下载用于使用自定义URL方案创建iOS应用程序的源代码


使用模拟器,以下是如何调用应用程序:

- 从Xcode中运行 应用程序
- 一旦安装,现在将注册自定义URL方案
- 通过模拟器中的硬件菜单关闭应用程序,然后选择Home 
- Start Safari 
- 输入浏览器地址栏中先前定义的URL方案(见下文) )


此时Safari将关闭,该应用程序将被带到前台。恭喜,您刚刚使用自定义URL方案调用iPhone应用程序!

从H5页面中调起APP,这个方法用的最多,但是无法测试,需要把Html文件部署到服务器,因此可以用safari测试,然后写一个简单的html页面,部署到服务器,在来调起APP

这里附上Html的脚本:

<html>  
<meta charset="UTF-8">  
   <body>  
     <h1>标题</h1>
      <a href="iOSDevTips://?token=123abct">打开APP</a>  
   </body>  
</html>



从另一个iPhone应用程序调用自定义URL方案

我们来看看如何从另一个iPhone应用程序调用自定义URL方案。再次,我创建了一个非常简单的iPhone应用程序,只需一个UILabel和UIButton - 前者显示一条消息,这是通过自定义URL方案调用另一个应用程序的应用程序,该按钮启动该过程。下载源代码以创建iOS App以调用自定义URL方案


buttonPressed中的代码管理URL处理:


-(void)buttonPressed:(UIButton*)button
{
  NSString*customURL=@"iOSDevTips://";
 
  if([[UIApplication sharedApplication]
    canOpenURL:[NSURL URLWithString:customURL]])
  {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
  }
  else
  {
    UIAlertView*alert=[[UIAlertViewalloc] initWithTitle:@"URL error"
                          message:[NSString stringWithFormat:
                            @"No custom URL defined for %@",customURL]
                          delegate:self cancelButtonTitle:@"Ok"
                          otherButtonTitles:nil];
    [alertshow];
  }    
}




第5行我们检查自定义URL是否已定义,如果是,请使用共享应用程序实例打开URL(第8行)。openURL:方法启动应用程序并将URL传递到应用程序。在此过程中退出当前应用程序。

通过自定义URL方案传递参数以应用

您有可能需要使用自定义URL定义将参数传递到应用程序中。我们来看看我们如何做到这一点。

作为从一个应用程序调用到另一个应用程序的基础的NSURL类符合RFC 1808(相对统一资源定位符)。因此,您可能熟悉基于网络内容的URL格式也适用于此。

在具有自定义URL方案的应用程序中,应用程序委托必须实现具有以下签名的方法:


-(BOOL)application:(UIApplication*)application
  openURL:(NSURL*)url
  sourceApplication:(NSString*)sourceApplication
  annotation:(id)annotation



将参数从一个应用传递到另一个应用程序的窍门是通过URL。例如,假设我们使用以下自定义URL方案,并希望传入一个“令牌”值和一个表示注册状态的标志,我们可以按如下方式创建URL:

NSString*customURL=@"iOSDevTips://?token=123abct®istered=1";



在web开发中,字符串?token = 123abct&registered = 1被称为查询字符串。

在被调用的应用程序的应用程序代理(具有自定义URL的应用程序)中,检索参数的代码如下:


-(BOOL)application:(UIApplication*)application openURL:(NSURL*)url
        sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
{
  NSLog(@"Calling Application Bundle ID: %@",sourceApplication);
  NSLog(@"URL scheme:%@",[urlscheme]);
  NSLog(@"URL query: %@",[urlquery]);
 
  returnYES;
}



使用自定义URL(使用我的Bundle ID)从另一个应用程序调用的应用程序的输出如下所示:


CallingApplicationBundleID:com.3Sixty.CallCustomURL
URLscheme:iOSDevTips
URLquery:token=123abct®istered=1



记下“呼叫应用程序Bundle  ID”,您可以使用它来确保只有您定义的应用程序可以直接与您的应用程序交互。

我们来更改委托方法来验证调用应用程序Bundle ID是否已知:


-(BOOL)application:(UIApplication*)application openURL:(NSURL*)url
        sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
{
  // Check the calling application Bundle ID
  if([sourceApplication isEqualToString:@"com.3Sixty.CallCustomURL"])
  {
    NSLog(@"Calling Application Bundle ID: %@",sourceApplication);
    NSLog(@"URL scheme:%@",[url scheme]);
    NSLog(@"URL query: %@",[url query]);
 
    return YES;
  }
  else
    returnNO;
}



请注意,您无法阻止其他应用程序通过自定义URL方案调用应用程序,但是您可以跳过任何进一步的处理,并返回NO,如上所示。就这样说,如果你希望保持其他应用程序不要打电话给你的应用程序,创建一个唯一的(不明显的)URL方案。虽然这样可以保证你的应用不会被调用,但这样做将不太可能。

如果你的手机是IOS9以下,那么这个以上就已经OK了。

如果你的手机是IOS9以上,必须实现以下方法,否则刚才的回调会不执行。

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options
{
    NSString* scheme =[url scheme];
    if([scheme isEqualToString:@"iOSDevTips"])
    {
         NSLog(@"Calling Application Bundle ID: %@",sourceApplication);
  		NSLog(@"URL scheme:%@",[urlscheme]);
  		NSLog(@"URL query: %@",[urlquery]);
    }
    
    return true;
}




自定义URL方案示例项目

我意识到按照上述步骤可能有点棘手。我包括两个(非常基本的)iOS应用程序,一个定制的URL方案,一个调用该应用程序,传递一个简短的参数列表(查询字符串)。这些是尝试使用自定义网址的好起点。