2012-07-10 9 views
40

Có cách nào để xác định một số loại xử lý cơ chế trong Android iOS mà sẽ cho phép tôi làm chặn một trong hai điều sau đây:Android/iOS - Tuỳ chỉnh URI/Giao thức Xử lý

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

tôi d muốn 'nghe' cho giao thức hoặc máy chủ, và mở một Activity/ViewController tương ứng.

Tôi cũng muốn nếu những hệ thống này có thể rộng như hệ thống nhất có thể. Tôi tưởng tượng điều này sẽ là một vấn đề trên iOS, nhưng tôi lý tưởng có thể nhấp vào một trong hai lược đồ đó, dưới dạng siêu liên kết, từ bất kỳ ứng dụng nào. Gmail, Safari vv

Trả lời

20

Đối với iOS, có, bạn có thể làm hai việc:

  1. Có ứng dụng của bạn quảng cáo rằng nó có thể xử lý URL với một lược đồ đã cho.

  2. Cài đặt trình xử lý giao thức để xử lý bất kỳ chương trình nào bạn thích.

Tùy chọn đầu tiên khá đơn giản và được mô tả trong Implementing Custom URL Schemes. Để cho hệ thống biết rằng ứng dụng của bạn có thể xử lý một chương trình đưa ra: Info.plist của

  • cập nhật ứng dụng của bạn với một mục CFBundleURLTypes

  • thực hiện -application:didFinishLaunchingWithOptions: trong đại biểu ứng dụng của bạn.

Khả năng thứ hai là viết trình xử lý giao thức của riêng bạn. Điều này chỉ hoạt động trong ứng dụng của bạn, nhưng bạn có thể sử dụng nó cùng với kỹ thuật được mô tả ở trên. Sử dụng phương pháp nêu trên để có được hệ thống để khởi động ứng dụng của bạn cho một URL nào đó, và sau đó sử dụng một trình xử lý giao thức URL tùy chỉnh trong ứng dụng của bạn để tận dụng sức mạnh của hệ thống URL tải iOS:

  • Tạo một lớp con của riêng bạn của NSURLProtocol.

  • Ghi đè +canInitWithRequest: - thường bạn sẽ chỉ xem lược đồ URL và chấp nhận nó nếu nó khớp với lược đồ bạn muốn xử lý, nhưng bạn cũng có thể xem các khía cạnh khác của yêu cầu.

  • đăng ký lớp con của bạn: [MyURLProtocol registerClass];

  • Override -startLoading-stopLoading bắt đầu và ngừng tải theo yêu cầu, tương ứng.

Đọc tài liệu NSURLProtocol được liên kết ở trên để biết thêm thông tin. Mức độ khó khăn ở đây phụ thuộc phần lớn vào những gì bạn đang cố gắng thực hiện. Thông thường, các ứng dụng iOS triển khai trình xử lý URL tùy chỉnh để các ứng dụng khác có thể thực hiện các yêu cầu đơn giản. Việc triển khai trình xử lý HTTP hoặc FTP của riêng bạn có liên quan nhiều hơn một chút.

Đối với những gì đáng giá, đây chính xác là cách PhoneGap hoạt động trên iOS. PhoneGap bao gồm một lớp con NSURLProtocol được gọi là PGURLProtocol, xem sơ đồ của bất kỳ URL nào mà ứng dụng cố tải và tiếp quản nếu đó là một trong các lược đồ mà nó nhận ra. Người anh em họ nguồn mở của PhoneGap là Cordova - bạn có thể thấy hữu ích khi xem.

+10

Câu trả lời được chấp nhận thực sự nên giải quyết toàn bộ câu hỏi. Câu trả lời của bạn không đề cập đến Android. Câu hỏi có chữ in đậm "và". – ToothlessRebel

+6

Câu hỏi thực sự cần phải được chia thành hai câu hỏi - không có cách nào để xử lý các URI tùy chỉnh trên cả hai nền tảng. –

74

EDIT 5/2014, vì điều này có vẻ là một câu hỏi phổ biến Tôi đã thêm nhiều chi tiết để câu trả lời:

Android:

Đối với Android, hãy tham khảo Intent Filter to Launch My Activity when custom URI is clicked.

Bạn sử dụng một ý định lọc:

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

này được gắn vào Hoạt động mà bạn muốn đưa ra. Ví dụ:

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

Sau đó, trong hoạt động của bạn, nếu không chạy, hoạt động sẽ được khởi chạy với URI được chuyển trong mục đích.

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

Nếu đã chạy, trênNewIntent() sẽ được gọi lại trong hoạt động của bạn, với URI theo ý định.

Cuối cùng, nếu bạn thay vì muốn xử lý giao thức tùy chỉnh trong UIWebView của tổ chức trong ứng dụng bản địa, bạn có thể sử dụng:

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

iOS:

Đối với iOS, hãy tham khảo Lauching App with URL (via UIApplicationDelegate's handleOpenURL) working under iOS 4, but not under iOS 3.2.

Xác định lược đồ URL của bạn thông qua Thông tin.phím plist tương tự như:

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

Sau đó xác định một hàm điều khiển để gọi trong ứng dụng của đại biểu

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

Nếu bạn muốn xử lý giao thức tùy chỉnh trong UIWebViews lưu trữ trong ứng dụng bản địa, bạn có thể sử dụng phương pháp 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"]) 
    { 
     ... 
    } 
    } 
} 

}

Đối WKWebView (iOS8 +), bạn thay vì có thể sử dụng một WKNavigationDelegate và phương pháp này:

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

Một điều tôi phát hiện ra là GMail (ứng dụng iOS, ứng dụng Android, web) loại bỏ các liên kết không chuẩn từ email. – dzeikei

+4

@dzeikei chúng tôi sử dụng URL web chuyển hướng đến url ứng dụng tùy chỉnh của chúng tôi. Là một phần thưởng, chúng tôi có thể gắn nó vào phân tích email/web của chúng tôi dễ dàng hơn. –

+1

@ JasonDenizac Vâng, đó là những gì chúng tôi phải làm là tốt nhưng nó sẽ là một trải nghiệm người dùng đẹp hơn nếu bạn có thể tránh xem xét qua trình duyệt :) – dzeikei