Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/185.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android/iOS-自定义URI/协议处理_Android_Ios_Protocols_Manifest_Custom Url Protocol - Fatal编程技术网

Android/iOS-自定义URI/协议处理

Android/iOS-自定义URI/协议处理,android,ios,protocols,manifest,custom-url-protocol,Android,Ios,Protocols,Manifest,Custom Url Protocol,有没有办法在Android和iOS中定义某种处理机制,允许我执行以下任一操作: myapp:///events/3/ - or - http://myapp.com/events/3/ 我想“侦听”协议或主机,并打开相应的活动/视图控制器 我也希望这些能尽可能的在全系统范围内。我想这在iOS上会是一个更大的问题,但我最好能从任何应用程序中点击这两个方案中的任何一个,作为超链接。Gmail、Safari等。编辑2014年5月,由于这似乎是一个热门问题,我在答案中添加了很多细节: Android:

有没有办法在AndroidiOS中定义某种处理机制,允许我执行以下任一操作:

myapp:///events/3/
- or -
http://myapp.com/events/3/
我想“侦听”协议或主机,并打开相应的活动/视图控制器


我也希望这些能尽可能的在全系统范围内。我想这在iOS上会是一个更大的问题,但我最好能从任何应用程序中点击这两个方案中的任何一个,作为超链接。Gmail、Safari等。

编辑2014年5月,由于这似乎是一个热门问题,我在答案中添加了很多细节:

Android:

对于Android,请参阅

您可以使用意图过滤器:

<intent-filter>
  <action android:name="android.intent.action.VIEW" /> 
  <category android:name="android.intent.category.DEFAULT" /> 
  <category android:name="android.intent.category.BROWSABLE" /> 
  <data android:scheme="myapp" /> 
</intent-filter>
如果已经在运行,那么将在活动中调用onNewIntent(),并在意图中再次使用URI

最后,如果您希望在本机应用程序中处理UIWebView中托管的自定义协议,则可以使用:

myWebView.setWebViewClient(new WebViewClient()
{
 public Boolean shouldOverrideUrlLoading(WebView view, String url)
 {
  // inspect the url for your protocol
 }
});
iOS:

有关iOS,请参阅

通过Info.plist键定义URL方案,类似于:

<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>com.yourcompany.myapp</string>
        </dict>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>myapp</string>
            </array>
        </dict>
    </array>
如果要在本机应用程序中托管的UIWebViews中处理自定义协议,可以使用UIWebViewDelegate方法:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
 NSURL *urlPath = [request URL];
 if (navigationType == UIWebViewNavigationTypeLinkClicked)
 {
    // inspect the [URL scheme], validate
    if ([[urlPath scheme] hasPrefix:@"myapp"]) 
    {
      ...
    }
  }
}
}

对于WKWebView(iOS8+),您可以改为使用WKNavigationDelegate和以下方法:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
 NSURL *urlPath = navigationAction.request.URL;  
 if (navigationAction.navigationType == WKNavigationTypeLinkActivated)
 {
   // inspect the [URL scheme], validate
   if ([[urlPath scheme] hasPrefix:@"myapp"])
   {
    // ... handle the request
    decisionHandler(WKNavigationActionPolicyCancel);
    return;
   }
 }

 //Pass back to the decision handler
 decisionHandler(WKNavigationActionPolicyAllow);
}

更新:这是一个非常古老的问题,iOS和Android上的情况都发生了很大变化。我将保留下面的原始答案,但是任何一个从事新项目或更新旧项目的人都应该考虑在两个平台上支持的使用。

在iOS上,调用深层链接。您需要在您的网站上创建一个JSON文件,将您的应用程序与指向部分网站的URL相关联。接下来,更新应用程序以接受
nsserActivity
对象,并将应用程序设置为显示与给定URL对应的内容。您还需要向应用程序添加权限,列出应用程序可以处理的URL。在使用中,操作系统负责从您的站点下载关联文件,并在有人试图打开您的应用程序句柄之一时启动您的应用程序

设置类似的工作。首先,你将在你的网站和你的应用程序之间建立一个关联,然后你将添加该关联,让你的应用程序拦截打开你的应用程序可以处理的URL的尝试

尽管细节明显不同,但两种平台上的方法几乎相同。它使您能够将应用程序插入到网站内容的显示中,无论哪个应用程序试图访问该内容


原始答案:

对于iOS,您可以做两件事:

  • 让你的应用程序宣传它可以用给定的方案处理URL

  • 安装一个协议处理程序来处理您喜欢的任何方案

  • 第一个选项非常简单,如中所述。要让系统知道您的应用程序可以处理给定方案,请执行以下操作:

    • 使用CbundleUrlTypes条目更新应用程序的Info.plist

    • 在应用程序代理中使用选项实现
      -应用程序:didFinishLaunching:

    第二种可能是编写自己的协议处理程序。这只适用于你的应用程序,但你可以将其与上述技术结合使用。使用上述方法让系统为给定URL启动应用程序,然后在应用程序中使用自定义URL协议处理程序来利用iOS URL加载系统的强大功能:

    • 创建您自己的子类

    • Override
      +canInitWithRequest:
      ——通常您只需查看URL方案,如果它与您想要处理的方案匹配,则接受它,但您也可以查看请求的其他方面

    • 注册您的子类:
      [MyURLProtocol registerClass]

    • 覆盖
      -startLoading
      -stopLoading
      以分别启动和停止加载请求

    有关更多信息,请阅读上面链接的NSURLProtocol文档。这里的难度很大程度上取决于您试图实现的内容。iOS应用程序通常会实现自定义URL处理程序,以便其他应用程序可以发出简单的请求。实现自己的HTTP或FTP处理程序要复杂一些


    值得一提的是,这正是PhoneGap在iOS上的工作原理。PhoneGap包含一个名为PGURLProtocol的NSURLProtocol子类,该子类查看应用程序尝试加载的任何URL的方案,如果该方案是其识别的方案之一,则由其接管。PhoneGap的开源近亲是——您可能会发现,看一看很有帮助。

    关于您问题中的第二个选项:

    http://myapp.com/events/3/
    
    iOS 9引入了一种称为“通用链接”的新技术,它允许您拦截指向您网站的链接(如果是https)://


    公认的答案应该真正解决整个问题。你的回答没有提到Android。这个问题有一个粗体的“和”。这个问题真的应该分为两个问题-没有任何一种方法可以跨两个平台处理自定义URI。我发现的一件事是GMail(iOS应用程序、Android应用程序、web)删除电子邮件中的非标准链接。@dzeikei我们使用web URL重定向到自定义应用程序URL。作为奖励,我们可以更轻松地将其与我们的网络/电子邮件分析联系起来。@Jasonenizac是的,这也是我们必须做的,但如果您可以避免使用浏览器,这将是一种更好的用户体验:)
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
     NSURL *urlPath = [request URL];
     if (navigationType == UIWebViewNavigationTypeLinkClicked)
     {
        // inspect the [URL scheme], validate
        if ([[urlPath scheme] hasPrefix:@"myapp"]) 
        {
          ...
        }
      }
    }
    
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
    {
     NSURL *urlPath = navigationAction.request.URL;  
     if (navigationAction.navigationType == WKNavigationTypeLinkActivated)
     {
       // inspect the [URL scheme], validate
       if ([[urlPath scheme] hasPrefix:@"myapp"])
       {
        // ... handle the request
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
       }
     }
    
     //Pass back to the decision handler
     decisionHandler(WKNavigationActionPolicyAllow);
    }
    
    http://myapp.com/events/3/