Android / iOS - Custom URI / Protocol Handling
是否有一种方法可以在Android和iOS中定义某种处理机制,从而允许我截取以下任意一项:
1 2 3 | myapp:///events/3/ - or - http://myapp.com/events/3/ |
我想"监听"协议或主机,然后打开相应的Activity / ViewController。
我也想尽可能将它们扩展到整个系统。我想这将在iOS上成为更多问题,但理想情况下,我希望能够从任何应用程序中单击这两种方案中的任何一种,作为超链接。 Gmail,Safari等。
编辑5/2014,因为这似乎是一个受欢迎的问题,所以我为答案添加了很多细节:
Android:
对于Android,请单击单击自定义URI时,请参阅意图过滤器以启动我的活动。
您使用意图过滤器:
1 2 3 4 5 6 | <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" /> </intent-filter> |
此附件附加到您要启动的活动。例如:
1 2 3 4 5 6 7 8 9 10 11 | <intent-filter> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" android:host="com.MyCompany.MyApp" /> </intent-filter> </activity> |
然后,在您的活动中(如果未运行),将使用在Intent中传递的URI启动活动。
1 2 | Intent intent = getIntent(); Uri openUri = intent.getData(); |
如果已经运行,则将在您的活动中调用onNewIntent(),并再次使用该URI。
最后,如果您想在本机应用程序中托管的UIWebView中处理自定义协议,则可以使用:
1 2 3 4 5 6 7 | myWebView.setWebViewClient(new WebViewClient() { public Boolean shouldOverrideUrlLoading(WebView view, String url) { // inspect the url for your protocol } }); |
iOS:
对于iOS,请参考在iOS 4下工作但具有URL(通过UIApplicationDelegates handleOpenURL)的应用程序,而不是在iOS 3.2下工作。
通过类似于以下内容的Info.plist键定义URL方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <key>CFBundleURLTypes</key> <dict> <key>CFBundleURLName</key> <string>com.yourcompany.myapp</string> </dict> <dict> <key>CFBundleURLSchemes</key> <string>myapp</string> </array> </dict> </array> |
然后定义一个处理程序函数以在您的应用程序委托中调用
1 2 3 4 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { // parse and validate the URL } |
如果要在本机应用程序中托管的UIWebViews中处理自定义协议,则可以使用UIWebViewDelegate方法:
1 2 3 4 5 6 7 8 9 10 11 12 | - (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和以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | - (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相关联。接下来,更新您的应用程序以接受
在Android上设置应用程序链接的操作与此类似。首先,您将在网站和应用程序之间建立关联,然后添加意图过滤器,以使您的应用程序拦截尝试打开应用程序可以处理的URL的尝试。
尽管细节明显不同,但是两种平台上的方法几乎相同。它使您能够将应用程序插入网站内容的显示中,而不管是什么应用程序尝试访问该内容。
原始答案:
对于iOS,是的,您可以做两件事:
让您的应用广告宣传它可以使用给定的方案处理URL。
安装协议处理程序以处理您喜欢的任何方案。
第一个选项非常简单,在实现自定义URL方案中进行了介绍。让系统知道您的应用程序可以处理给定的方案:
-
使用CFBundleURLTypes条目更新应用程序的Info.plist
-
您的应用程序委托中的
实现
-application:didFinishLaunchingWithOptions: 。
第二种可能性是编写自己的协议处理程序。这仅在您的应用程序中有效,但是您可以将其与上述技术结合使用。使用上面的方法来使系统启动给定URL的应用程序,然后在应用程序中使用自定义URL协议处理程序来利用iOS URL加载系统的功能:
-
创建自己的
NSURLProtocol 子类。 -
覆盖
+canInitWithRequest: -通常,您仅查看URL方案并接受它(如果它与您要处理的方案匹配),但是您也可以查看请求的其他方面。 -
注册您的子类:
[MyURLProtocol registerClass]; -
重写
-startLoading 和-stopLoading 分别开始和停止加载请求。
阅读上面链接的NSURLProtocol文档以获取更多信息。这里的难易程度在很大程度上取决于您要实现的目标。 iOS应用通常会实现自定义URL处理程序,以便其他应用可以发出简单的请求。实现您自己的HTTP或FTP处理程序要复杂一些。
对于它的价值,这正是PhoneGap在iOS上的工作方式。 PhoneGap包含一个称为PGURLProtocol的NSURLProtocol子类,该子类查看应用程序尝试加载的任何URL的方案,如果该方案是它可以识别的方案之一,则进行接管。 PhoneGap的开源表弟是Cordova-您可能会发现看一下它很有帮助。
对于问题中的第二个选项:
1 | http://myapp.com/events/3/ |
iOS 9引入了一项称为通用链接的新技术,如果它们是https://
,则可以拦截到您网站的链接。
https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html