Android / iOS – 自定义URI /协议处理
有没有一种方法可以在Android 和 iOS中定义某种处理机制,这样可以拦截以下任一项:
myapp:///events/3/ - or - http://myapp.com/events/3/
我想为协议或主机“侦听”,并打开相应的Activity / ViewController。
如果这些可能尽可能系统宽泛,我也想要。 我想这将是更多的iOS上的问题,但我最好能够从任何应用程序点击这两个计划之一,作为超链接。 Gmail,Safari等
对于iOS,是的,你可以做两件事情:
-
让您的应用程序宣传它可以使用给定的scheme处理URL。
-
安装一个协议处理程序来处理你喜欢的任何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://