2012-07-10 81 views
40

有沒有一種方法來定義某種Android中 iOS的處理機制,讓我做攔截下列操作之一:的Android/iOS版 - 自定義的URI /協議處理

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

我d喜歡爲協議或主機「偵聽」,並打開相應的Activity/ViewController。

我想如果這些可能儘可能系統寬。我想這在iOS上會更成問題,但我理想的情況是能夠從任何應用程序中單擊這兩種方案中的任意一種,作爲超鏈接。 Gmail中,Safari等

回答

20

對於iOS,是的,你可以做兩件事情:

  1. 了您的應用通告它可以使用給定的方案來處理URL。

  2. 安裝協議處理程序來處理您喜歡的任何方案。

第一個選項非常簡單,並在Implementing Custom URL Schemes中描述。爲了讓系統知道你的應用程序可以處理一個給定的方案:

  • 更新應用的一個CFBundleURLTypes進入

  • Info.plist中實現應用程序委託-application:didFinishLaunchingWithOptions:

第二種可能性是編寫自己的協議處理程序。這隻適用於您的應用程序,但您可以將其與上述技術結合使用。使用上面的方法讓系統啓動您的應用程序對於給定的URL,然後用你的應用程序中的自定義URL協議處理程序利用的iOS的網址加載系統的功率:

  • 創建自己的子類的NSURLProtocol

  • 覆蓋+canInitWithRequest: - 通常您只需查看URL方案並接受它,如果它與要處理的方案相匹配,但您也可以查看請求的其他方面。

  • 註冊你的子類:[MyURLProtocol registerClass];

  • 覆蓋-startLoading-stopLoading啓動和停止分別裝載要求。

閱讀上面鏈接的NSURLProtocol文檔以獲取更多信息。這裏的難度很大程度上取決於你想要實現的目標。 iOS應用程序通常會實施自定義網址處理程序,以便其他應用程序可以發出簡單的請求。實現你自己的HTTP或FTP處理程序需要多一點參與。

對於它的價值,這正是PhoneGap在iOS上的工作原理。 PhoneGap包含一個稱爲PGURLProtocol的NSURLProtocol子類,該子類查看應用程序嘗試加載的任何URL的方案,並在其識別的方案之一接管它。 PhoneGap的開源表哥是Cordova - 你可能會發現看看它有幫助。

+10

接受的答案應該能夠解決整個問題。你的回答沒有提到Android。這個問題有一個粗體的「和」。 – ToothlessRebel 2013-01-13 19:24:30

+6

這個問題真的應該分成兩個問題 - 沒有任何一種方法可以在兩個平臺上處理自定義URI。 – 2014-01-30 06:22:24

74

編輯2014分之5,因爲這似乎是一個流行的問題,我已經添加了很多細節答案:

安卓:

對於Android,請參閱Intent Filter to Launch My Activity when custom URI is clicked

您可以使用一個意圖過濾器:

<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一起被調用。

最後,如果你不是想處理的自定義協議的UIWebView的本機應用中託管,您可以使用:

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

的iOS:

對於iOS,請參閱Lauching App with URL (via UIApplicationDelegate's handleOpenURL) working under iOS 4, but not under iOS 3.2

通過信息定義您的URL方案。plist中鍵類似於:

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

如果你想處理在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程序(iOS 8 +),你可以改用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); 
} 
+1

我發現的一件事是GMail(iOS應用程序,Android應用程序,網絡)從電子郵件中刪除非標準鏈接。 – dzeikei 2013-08-13 05:20:06

+4

@dzeikei我們使用重定向到我們的自定義應用程序URL的網址。作爲獎勵,我們可以更輕鬆地將其與我們的網絡/電子郵件分析結合起來。 – 2013-08-13 17:53:38

+1

@JasonDenizac是的,這就是我們不得不做的,但如果你可以避開瀏覽器,它會是一個更好的用戶體驗:) – dzeikei 2013-08-13 23:48:14