Android / iOS - пользовательский URI / обработка протокола
Есть ли способ определить какой-то механизм обработки в Android и iOS, который позволил бы мне перехватить одно из следующих:
myapp:///events/3/
- or -
http://myapp.com/events/3/
Я бы хотел "прослушать" протокол или хост и открыть соответствующий Activity / ViewController.
Я бы тоже хотел, если бы они были как можно более системными. Я предполагаю, что это будет больше проблемой для iOS, но в идеале я бы мог выбрать любую из этих двух схем, как гиперссылки, из любого приложения. Gmail, Safari и т. Д.
3 ответа
Обновление: это очень старый вопрос, и многое изменилось на iOS и Android. Я оставлю оригинальный ответ ниже, но всем, кто работает над новым проектом или обновляет старый, следует вместо этого рассмотреть возможность использования глубоких ссылок, которые поддерживаются на обеих платформах.
На iOS глубокие ссылки называются универсальными ссылками. Вам нужно будет создать файл JSON на вашем веб-сайте, который связывает ваше приложение с URL-адресами, которые указывают на части вашего веб-сайта. Затем обновите ваше приложение, чтобы принять NSUserActivity
Объект и настроить приложение для отображения содержимого, которое соответствует данному URL. Вам также необходимо добавить разрешение в приложение, в котором перечислены URL-адреса, которые может обрабатывать приложение. При использовании операционная система заботится о загрузке файла ассоциации с вашего сайта и запуске вашего приложения, когда кто-то пытается открыть один из URL-адресов, которые обрабатывает ваше приложение.
Настройка ссылок приложений на Android работает аналогично. Во-первых, вы установите связь между вашим веб-сайтом (-ами) и вашим приложением, а затем добавите фильтры намерений, которые позволяют вашему приложению перехватывать попытки открыть URL-адреса, которые может обрабатывать ваше приложение.
Хотя детали, очевидно, различны, подход практически одинаков для обеих платформ. Это дает вам возможность вставлять ваше приложение в отображение содержимого вашего веб-сайта независимо от того, какое приложение пытается получить к нему доступ.
Оригинальный ответ:
Для iOS, да, вы можете сделать две вещи:
Сделайте так, чтобы ваше приложение сообщало, что оно может обрабатывать URL по заданной схеме.
Установите обработчик протокола для обработки любой схемы, которая вам нравится.
Первый вариант довольно прост и описан в разделе "Реализация пользовательских схем URL". Чтобы система знала, что ваше приложение может обрабатывать данную схему:
обновить Info.plist вашего приложения с записью CFBundleURLTypes
воплощать в жизнь
-application:didFinishLaunchingWithOptions:
в вашем приложении делегат.
Вторая возможность - написать собственный обработчик протокола. Это работает только в вашем приложении, но вы можете использовать его в сочетании с методикой, описанной выше. Используйте метод, описанный выше, чтобы система запустила ваше приложение для данного URL, а затем используйте собственный обработчик протокола URL в вашем приложении, чтобы использовать возможности системы загрузки URL iOS:
Создайте свой собственный подкласс
NSURLProtocol
,Override
+canInitWithRequest:
- обычно вы просто смотрите на схему URL и принимаете ее, если она соответствует схеме, которую вы хотите обработать, но вы также можете посмотреть и на другие аспекты запроса.Зарегистрируйте свой подкласс:
[MyURLProtocol registerClass];
Override
-startLoading
а также-stopLoading
начать и остановить загрузку запроса соответственно.
Прочитайте NSURLProtocol документы, связанные выше для получения дополнительной информации. Уровень сложности здесь во многом зависит от того, что вы пытаетесь реализовать. В приложениях iOS обычно реализован пользовательский обработчик URL-адресов, чтобы другие приложения могли выполнять простые запросы. Реализация вашего собственного обработчика HTTP или FTP немного сложнее.
Для чего это стоит, именно так PhoneGap работает на iOS. PhoneGap включает в себя подкласс NSURLProtocol, называемый PGURLProtocol, который просматривает схему любого URL, который приложение пытается загрузить, и принимает его, если это одна из схем, которые оно распознает. Двоюродный брат PhoneGap с открытым исходным кодом - Cordova - вам может быть полезно посмотреть.
РЕДАКТИРОВАТЬ 5/2014, так как это, кажется, популярный вопрос, я добавил много деталей к ответу:
Android:
Для Android обратитесь к Intent Filter, чтобы запустить My Activity при нажатии на пользовательский URI.
Вы используете интент-фильтр:
<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 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-адресом (через handleOpenURL UIApplicationDelegate), работающим под iOS 4, но не под iOS 3.2.
Определите свою схему URL с помощью ключей Info.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 (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: //