Android / iOS-пользовательский URI / обработка протоколов

есть ли способ определить какой-то механизм обработки в Android и iOS, что позволило бы мне сделать перехват любого из следующих:

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

Я хотел бы "прослушать" протокол или хост и открыть соответствующее действие / ViewController.

Я бы тоже хотел, чтобы они были как можно шире в системе. Я предполагаю, что это будет больше проблемой на iOS, но в идеале я мог бы щелкнуть любую из этих двух схем, так как гиперссылки, из любого приложения. Gmail, Safari и т. д.

3 ответов


обновление: это очень старый вопрос, и многое изменилось как на iOS и Android. Я оставлю оригинальный ответ ниже, но любой, кто работает над новым проектом или обновляет старый, должен вместо этого рассмотреть возможность использования внешние ссылки, которые поддерживаются на обеих платформах.

в iOS глубокие ссылки называются универсальный ссылки. Вам нужно будет создать файл JSON на вашем веб-сайте, который связывает ваше приложение с URL-адресами, указывающими на части вашего веб-сайта. Затем обновите приложение, чтобы принять NSUserActivity объект и настроить приложение для отображения содержимого, соответствующего заданному URL-адресу. Кроме того, необходимо добавить право на приложение со списком URL-адресов, которые приложение может обрабатывать. При использовании операционная система позаботится о загрузке файла ассоциации с вашего сайта и запуске приложения, когда кто-то пытается открыть один из URL-адресов, которые обрабатывает ваше приложение.

настройка app ссылки на Android работает аналогично. Во-первых, вы создадите связь между вашим веб-сайтом (- ами) и вашим приложением, а затем вы добавите фильтры намерениях это позволит вашему приложению перехватывать попытки открыть URL-адреса, которые может обрабатывать ваше приложение.

хотя детали, очевидно, разные, подход в значительной степени одинаковый на обеих платформах. Это дает вам возможность вставлять приложение в отображение содержимого вашего веб-сайта независимо от того, какое приложение пытается получить доступ к этому содержание.


оригинальный ответ:

для iOS, да, вы можете сделать две вещи:

  1. пусть ваше приложение рекламирует, что оно может обрабатывать URL-адреса с заданной схемой.

  2. установите обработчик протокола для обработки любой схемы, которая вам нравится.

первый вариант довольно прост и описан в реализация пользовательских схем URL. Позволить системе знайте, что ваше приложение может обрабатывать заданную схему:

  • обновите информацию о своем приложении.plist с записью CFBundleURLTypes

  • реализовать -application:didFinishLaunchingWithOptions: в делегате приложения.

вторая возможность-написать свой собственный обработчик протокола. Это работает только в вашем приложении, но вы можете использовать его в сочетании с описанным выше методом. Используйте приведенный выше метод, чтобы система запустила приложение по заданному URL-адресу, а затем используйте пользовательский обработчик протокола URL в своем приложении, чтобы использовать мощь системы Загрузки URL-адресов iOS:

  • создайте свой собственный подкласс NSURLProtocol.

  • переопределить +canInitWithRequest: -- обычно вы просто смотрите на схему URL и принимаете ее, если она соответствует схеме, которую вы хотите обработать, но вы также можете посмотреть на другие аспекты запроса.

  • зарегистрируйте свой подкласс: [MyURLProtocol registerClass];

  • переопределить -startLoading и -stopLoading для запуска и остановки загрузки запроса, соответственно.

прочитайте документы NSURLProtocol, связанные выше для получения дополнительной информации. Уровень сложности здесь во многом зависит от того, что вы пытаетесь реализовать. Для приложений iOS обычно используется пользовательский обработчик URL, чтобы другие приложения могли выполнять простые запросы. Реализация собственного обработчика HTTP или FTP немного больше вовлеченный.

для чего это стоит, это именно то, как PhoneGap работает на iOS. PhoneGap включает подкласс NSURLProtocol под названием PGURLProtocol, который смотрит на схему любого URL-адреса, который приложение пытается загрузить и берет на себя, если это одна из схем, которые он распознает. Кузен PhoneGap с открытым исходным кодом Кордова - вы можете найти его полезным, чтобы взглянуть.


EDIT 5/2014, так как это кажется популярным вопросом, я добавил много деталей к ответу:

Android:

для Android, обратитесь к фильтр намерений для запуска моей деятельности при нажатии пользовательского URI.

вы используете intent-фильтр:

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

затем, в вашей деятельности, если не работает, деятельность будет запущенный с 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 приложение с URL (через UIApplicationDelegate в handleOpenURL) работает под iOS 4, но не под iOS 3.2.

определите схему URL через Info.ключи файлы, похожие на:

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