[RN] Simplify handling of universal / deeps links
Handle them directly on the application and call view.loadURL instead of having a static method which needs to figure out what view to load the URL on. On iOS, update the deep link method delegate since we don't support iOS 8. In addition, remove linking handling from the JS side, so now changing props of the root component is The One And Only Way to change the URL at runtime.
This commit is contained in:
parent
d521deecc4
commit
205dc5f0c3
|
@ -208,14 +208,6 @@ Helper method which should be called from the activity's `onResume` method.
|
|||
|
||||
This is a static method.
|
||||
|
||||
#### onNewIntent(intent)
|
||||
|
||||
Helper method for integrating the *deep linking* functionality. If your app's
|
||||
activity is launched in "singleTask" mode this method should be called from the
|
||||
activity's `onNewIntent` method.
|
||||
|
||||
This is a static method.
|
||||
|
||||
#### JitsiMeetViewListener
|
||||
|
||||
`JitsiMeetViewListener` provides an interface apps can implement to listen to
|
||||
|
|
|
@ -200,7 +200,12 @@ public class JitsiMeetActivity
|
|||
*/
|
||||
@Override
|
||||
public void onNewIntent(Intent intent) {
|
||||
JitsiMeetView.onNewIntent(intent);
|
||||
Uri uri;
|
||||
|
||||
if (Intent.ACTION_VIEW.equals(intent.getAction())
|
||||
&& (uri = intent.getData()) != null) {
|
||||
view.loadURLString(uri.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,8 +19,6 @@ package org.jitsi.meet.sdk;
|
|||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -207,34 +205,6 @@ public class JitsiMeetView extends FrameLayout {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activity lifecycle method which should be called from
|
||||
* <tt>Activity.onNewIntent</tt> so we can do the required internal
|
||||
* processing. Note that this is only needed if the activity's "launchMode"
|
||||
* was set to "singleTask". This is required for deep linking to work once
|
||||
* the application is already running.
|
||||
*
|
||||
* @param intent - <tt>Intent</tt> instance which was received.
|
||||
*/
|
||||
public static void onNewIntent(Intent intent) {
|
||||
// XXX At least twice we received bug reports about malfunctioning
|
||||
// loadURL in the Jitsi Meet SDK while the Jitsi Meet app seemed to
|
||||
// functioning as expected in our testing. But that was to be expected
|
||||
// because the app does not exercise loadURL. In order to increase the
|
||||
// test coverage of loadURL, channel deep linking through loadURL.
|
||||
Uri uri;
|
||||
|
||||
if (Intent.ACTION_VIEW.equals(intent.getAction())
|
||||
&& (uri = intent.getData()) != null
|
||||
&& loadURLStringInViews(uri.toString())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reactInstanceManager != null) {
|
||||
reactInstanceManager.onNewIntent(intent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The unique identifier of this {@code JitsiMeetView} within the process
|
||||
* for the purposes of {@link ExternalAPI}. The name scope was inspired by
|
||||
|
|
|
@ -91,34 +91,6 @@ Loads a specific URL which may identify a conference to join. If the specified
|
|||
URL is `nil` and the Welcome page is enabled, the Welcome page is displayed
|
||||
instead.
|
||||
|
||||
#### Universal / deep linking
|
||||
|
||||
In order to support Universal / deep linking, `JitsiMeetView` offers 2 class
|
||||
methods that you app's delegate should call in order for the app to follow those
|
||||
links.
|
||||
|
||||
```objc
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler
|
||||
{
|
||||
return [JitsiMeetView application:application
|
||||
continueUserActivity:userActivity
|
||||
restorationHandler:restorationHandler];
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation
|
||||
{
|
||||
return [JitsiMeetView application:application
|
||||
openURL:url
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation];
|
||||
}
|
||||
```
|
||||
|
||||
### JitsiMeetViewDelegate
|
||||
|
||||
This delegate is optional, and can be set on the `JitsiMeetView` instance using
|
||||
|
|
|
@ -28,22 +28,29 @@
|
|||
|
||||
#pragma mark Linking delegate methods
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
|
||||
return [JitsiMeetView application:application
|
||||
continueUserActivity:userActivity
|
||||
restorationHandler:restorationHandler];
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
|
||||
|
||||
if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
|
||||
JitsiMeetView *view
|
||||
= (JitsiMeetView *) self.window.rootViewController.view;
|
||||
[view loadURL:userActivity.webpageURL];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation {
|
||||
return [JitsiMeetView application:application
|
||||
openURL:url
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation];
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
|
||||
|
||||
JitsiMeetView *view = (JitsiMeetView *) self.window.rootViewController.view;
|
||||
[view loadURL:url];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -28,15 +28,6 @@
|
|||
+ (BOOL)application:(UIApplication *_Nonnull)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary *_Nonnull)launchOptions;
|
||||
|
||||
+ (BOOL)application:(UIApplication * _Nonnull)application
|
||||
continueUserActivity:(NSUserActivity * _Nonnull)userActivity
|
||||
restorationHandler:(void (^ _Nullable)(NSArray * _Nullable))restorationHandler;
|
||||
|
||||
+ (BOOL)application:(UIApplication * _Nonnull)application
|
||||
openURL:(NSURL * _Nonnull)URL
|
||||
sourceApplication:(NSString * _Nullable)sourceApplication
|
||||
annotation:(id _Nullable)annotation;
|
||||
|
||||
- (void)loadURL:(NSURL * _Nullable)url;
|
||||
|
||||
- (void)loadURLObject:(NSDictionary * _Nullable)urlObject;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include <mach/mach_time.h>
|
||||
|
||||
#import <React/RCTAssert.h>
|
||||
#import <React/RCTLinkingManager.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
#import "JitsiMeetView+Private.h"
|
||||
|
@ -133,48 +132,6 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
|||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark Linking delegate helpers
|
||||
// https://facebook.github.io/react-native/docs/linking.html
|
||||
|
||||
+ (BOOL)application:(UIApplication *)application
|
||||
continueUserActivity:(NSUserActivity *)userActivity
|
||||
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler
|
||||
{
|
||||
// XXX At least twice we received bug reports about malfunctioning loadURL
|
||||
// in the Jitsi Meet SDK while the Jitsi Meet app seemed to functioning as
|
||||
// expected in our testing. But that was to be expected because the app does
|
||||
// not exercise loadURL. In order to increase the test coverage of loadURL,
|
||||
// channel Universal linking through loadURL.
|
||||
if ([userActivity.activityType
|
||||
isEqualToString:NSUserActivityTypeBrowsingWeb]
|
||||
&& [JitsiMeetView loadURLInViews:userActivity.webpageURL]) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
return [RCTLinkingManager application:application
|
||||
continueUserActivity:userActivity
|
||||
restorationHandler:restorationHandler];
|
||||
}
|
||||
|
||||
+ (BOOL)application:(UIApplication *)application
|
||||
openURL:(NSURL *)url
|
||||
sourceApplication:(NSString *)sourceApplication
|
||||
annotation:(id)annotation {
|
||||
// XXX At least twice we received bug reports about malfunctioning loadURL
|
||||
// in the Jitsi Meet SDK while the Jitsi Meet app seemed to functioning as
|
||||
// expected in our testing. But that was to be expected because the app does
|
||||
// not exercise loadURL. In order to increase the test coverage of loadURL,
|
||||
// channel Universal linking through loadURL.
|
||||
if ([JitsiMeetView loadURLInViews:url]) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
return [RCTLinkingManager application:application
|
||||
openURL:url
|
||||
sourceApplication:sourceApplication
|
||||
annotation:annotation];
|
||||
}
|
||||
|
||||
#pragma mark Initializers
|
||||
|
||||
- (instancetype)init {
|
||||
|
@ -281,32 +238,6 @@ static NSMapTable<NSString *, JitsiMeetView *> *views;
|
|||
|
||||
#pragma mark Private methods
|
||||
|
||||
/**
|
||||
* Loads a specific {@link NSURL} in all existing {@code JitsiMeetView}s.
|
||||
*
|
||||
* @param url - The {@code NSURL} to load in all existing
|
||||
* {@code JitsiMeetView}s.
|
||||
* @return {@code YES} if the specified {@code url} was submitted for loading in
|
||||
* at least one {@code JitsiMeetView}; otherwise, {@code NO}.
|
||||
*/
|
||||
+ (BOOL)loadURLInViews:(NSURL *)url {
|
||||
BOOL handled = NO;
|
||||
|
||||
if (views) {
|
||||
for (NSString *externalAPIScope in views) {
|
||||
JitsiMeetView *view
|
||||
= [JitsiMeetView viewForExternalAPIScope:externalAPIScope];
|
||||
|
||||
if (view) {
|
||||
[view loadURL:url];
|
||||
handled = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope {
|
||||
return [views objectForKey:externalAPIScope];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* global __DEV__ */
|
||||
|
||||
import React from 'react';
|
||||
import { Linking } from 'react-native';
|
||||
|
||||
import '../../analytics';
|
||||
import '../../authentication';
|
||||
|
@ -47,9 +46,6 @@ export class App extends AbstractApp {
|
|||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
this._onLinkingURL = this._onLinkingURL.bind(this);
|
||||
|
||||
// In the Release configuration, React Native will (intentionally) throw
|
||||
// an unhandled JavascriptException for an unhandled JavaScript error.
|
||||
// This will effectively kill the application. In accord with the Web,
|
||||
|
@ -57,34 +53,6 @@ export class App extends AbstractApp {
|
|||
this._maybeDisableExceptionsManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to notifications about activating URLs registered to be handled
|
||||
* by this app.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
* @see https://facebook.github.io/react-native/docs/linking.html
|
||||
*/
|
||||
componentWillMount() {
|
||||
super.componentWillMount();
|
||||
|
||||
Linking.addEventListener('url', this._onLinkingURL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from notifications about activating URLs registered to be
|
||||
* handled by this app.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
* @see https://facebook.github.io/react-native/docs/linking.html
|
||||
*/
|
||||
componentWillUnmount() {
|
||||
Linking.removeEventListener('url', this._onLinkingURL);
|
||||
|
||||
super.componentWillUnmount();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to disable the use of React Native
|
||||
* {@link ExceptionsManager#handleException} on platforms and in
|
||||
|
@ -122,20 +90,6 @@ export class App extends AbstractApp {
|
|||
global.ErrorUtils.setGlobalHandler(newHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notified by React's Linking API that a specific URL registered to be
|
||||
* handled by this App was activated.
|
||||
*
|
||||
* @param {Object} event - The details of the notification/event.
|
||||
* @param {string} event.url - The URL registered to be handled by this App
|
||||
* which was activated.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onLinkingURL({ url }) {
|
||||
this._openURL(url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue