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

有没有一种方法可以在Android iOS中定义某种处理机制,这样可以拦截以下任一项:

myapp:///events/3/ - or - http://myapp.com/events/3/ 

我想为协议或主机“侦听”,并打开相应的Activity / ViewController。

如果这些可能尽可能系统宽泛,我也想要。 我想这将是更多的iOS上的问题,但我最好能够从任何应用程序点击这两个计划之一,作为超链接。 Gmail,Safari等

对于iOS,是的,你可以做两件事情:

  1. 让您的应用程序宣传它可以使用给定的scheme处理URL。

  2. 安装一个协议处理程序来处理你喜欢的任何scheme。

第一个选项非常简单,在实现自定义URLscheme中有介绍 。 让系统知道您的应用程序可以处理给定的scheme:

  • 使用CFBundleURLTypes条目更新您的应用的Info.plist

  • 在应用程序委托中实现-application:didFinishLaunchingWithOptions:

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

  • 创build一个你自己的NSURLProtocol的子类。

  • Override +canInitWithRequest: – 通常你只要看一下URLscheme,并接受它,如果它符合你想要处理的scheme,但你也可以看看请求的其他方面。

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

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

阅读上面链接的NSURLProtocol文档以获取更多信息。 这里的难度在很大程度上取决于你想要实现什么。 iOS应用程序通常会实现自定义URL处理程序,以便其他应用程序可以发出简单的请求。 实现你自己的HTTP或FTP处理程序有一点涉及。

对于它的价值,这正是PhoneGap在iOS上的工作原理。 PhoneGap包含一个名为PGURLProtocol的NSURLProtocol子类,用于查看应用程序尝试加载的任何URL的scheme,如果它是其识别的scheme之一,则接pipe该scheme。 PhoneGap的开源表哥是cordova – 你可能会发现看看是有帮助的。

编辑5/2014,因为这似乎是一个受欢迎的问题,我已经添加了很多细节的答案:

安卓:

对于Android, 单击自定义URI时 ,请参阅意图filter以启动“我的活动” 。

您使用意图filter:

 <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> 

这附加到您要启动的活动。 例如:

 <activity android:name="com.MyCompany.MyApp.MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <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" android:host="com.MyCompany.MyApp" /> </intent-filter> </activity> 

然后,在你的活动中,如果没有运行,活动将通过在Intent中传递的URI来启动。

 Intent intent = getIntent(); Uri openUri = intent.getData(); 

如果已经运行,onNewIntent()将在您的活动中被调用,同样在意图中使用URI。

最后,如果您不想在您的本机应用程序中托pipeUIWebView托pipe的自定义协议,则可以使用:

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

iOS版:

对于iOS,请参阅在iOS 4下工作的URL(通过UIApplicationDelegate的handleOpenURL),但不在iOS 3.2下 。

通过Info.plist键定义您的URLscheme,类似于:

 <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> 

然后定义一个处理函数在你的应用程序委托中被调用

 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { // parse and validate the URL } 

如果您想在您的本机应用程序中托pipe的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); } 

对于你的问题的第二个选项:

 http://myapp.com/events/3/ 

iOS 9引入了一种新技术,称为Universal Links,它允许您截取到您网站的链接,如果它们是https://

https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/UniversalLinks.html