mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-07 22:42:13 +08:00
Summary:
public
Map and Set are a standard JavaScript features, but are only supported in a subset of JSC versions that we target (e.g. iOS 7's JSC doesn't support Set).
The consequence of this is that failing to require('Set') before using it won't error during testing on a modern OS, but will fail on older OS versions. This diff makes the Map and Set polyfills available globally to all RN apps to avoid that problem.
Reviewed By: davidaurelio
Differential Revision: D2833997
fb-gh-sync-id: 713d8b69f6a1bce2472a1b2e6b84f69d75f30289
172 lines
4.7 KiB
JavaScript
172 lines
4.7 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule LinkingIOS
|
|
* @flow
|
|
*/
|
|
'use strict';
|
|
|
|
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
|
var RCTLinkingManager = require('NativeModules').LinkingManager;
|
|
var invariant = require('invariant');
|
|
|
|
var _notifHandlers = new Map();
|
|
var _initialURL = RCTLinkingManager &&
|
|
RCTLinkingManager.initialURL;
|
|
|
|
var DEVICE_NOTIF_EVENT = 'openURL';
|
|
|
|
/**
|
|
* `LinkingIOS` gives you a general interface to interact with both incoming
|
|
* and outgoing app links.
|
|
*
|
|
* ### Basic Usage
|
|
*
|
|
* #### Handling deep links
|
|
*
|
|
* If your app was launched from an external url registered to your app you can
|
|
* access and handle it from any component you want with
|
|
*
|
|
* ```
|
|
* componentDidMount() {
|
|
* var url = LinkingIOS.popInitialURL();
|
|
* }
|
|
* ```
|
|
*
|
|
* In case you also want to listen to incoming app links during your app's
|
|
* execution you'll need to add the following lines to you `*AppDelegate.m`:
|
|
*
|
|
* ```
|
|
* - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
|
|
* sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
|
|
* {
|
|
* return [RCTLinkingManager application:application openURL:url
|
|
* sourceApplication:sourceApplication annotation:annotation];
|
|
* }
|
|
*
|
|
* // Only if your app is using [Universal Links](https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/AppSearch/UniversalLinks.html).
|
|
* - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
|
|
* restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
|
|
* {
|
|
* return [RCTLinkingManager application:application
|
|
* continueUserActivity:userActivity
|
|
* restorationHandler:restorationHandler];
|
|
* }
|
|
*
|
|
* ```
|
|
*
|
|
* And then on your React component you'll be able to listen to the events on
|
|
* `LinkingIOS` as follows
|
|
*
|
|
* ```
|
|
* componentDidMount() {
|
|
* LinkingIOS.addEventListener('url', this._handleOpenURL);
|
|
* },
|
|
* componentWillUnmount() {
|
|
* LinkingIOS.removeEventListener('url', this._handleOpenURL);
|
|
* },
|
|
* _handleOpenURL(event) {
|
|
* console.log(event.url);
|
|
* }
|
|
* ```
|
|
*
|
|
* #### Triggering App links
|
|
*
|
|
* To trigger an app link (browser, email or custom schemas), call
|
|
*
|
|
* ```
|
|
* LinkingIOS.openURL(url)
|
|
* ```
|
|
*
|
|
* If you want to check if any installed app can handle a given URL beforehand, call
|
|
* ```
|
|
* LinkingIOS.canOpenURL(url, (supported) => {
|
|
* if (!supported) {
|
|
* AlertIOS.alert('Can\'t handle url: ' + url);
|
|
* } else {
|
|
* LinkingIOS.openURL(url);
|
|
* }
|
|
* });
|
|
* ```
|
|
*/
|
|
class LinkingIOS {
|
|
/**
|
|
* Add a handler to LinkingIOS changes by listening to the `url` event type
|
|
* and providing the handler
|
|
*/
|
|
static addEventListener(type: string, handler: Function) {
|
|
invariant(
|
|
type === 'url',
|
|
'LinkingIOS only supports `url` events'
|
|
);
|
|
var listener = RCTDeviceEventEmitter.addListener(
|
|
DEVICE_NOTIF_EVENT,
|
|
handler
|
|
);
|
|
_notifHandlers.set(handler, listener);
|
|
}
|
|
|
|
/**
|
|
* Remove a handler by passing the `url` event type and the handler
|
|
*/
|
|
static removeEventListener(type: string, handler: Function ) {
|
|
invariant(
|
|
type === 'url',
|
|
'LinkingIOS only supports `url` events'
|
|
);
|
|
var listener = _notifHandlers.get(handler);
|
|
if (!listener) {
|
|
return;
|
|
}
|
|
listener.remove();
|
|
_notifHandlers.delete(handler);
|
|
}
|
|
|
|
/**
|
|
* Try to open the given `url` with any of the installed apps.
|
|
*/
|
|
static openURL(url: string) {
|
|
invariant(
|
|
typeof url === 'string',
|
|
'Invalid url: should be a string'
|
|
);
|
|
RCTLinkingManager.openURL(url);
|
|
}
|
|
|
|
/**
|
|
* Determine whether or not an installed app can handle a given URL.
|
|
* The callback function will be called with `bool supported` as the only argument
|
|
*
|
|
* NOTE: As of iOS 9, your app needs to provide the `LSApplicationQueriesSchemes` key
|
|
* inside `Info.plist`.
|
|
*/
|
|
static canOpenURL(url: string, callback: Function) {
|
|
invariant(
|
|
typeof url === 'string',
|
|
'Invalid url: should be a string'
|
|
);
|
|
invariant(
|
|
typeof callback === 'function',
|
|
'A valid callback function is required'
|
|
);
|
|
RCTLinkingManager.canOpenURL(url, callback);
|
|
}
|
|
|
|
/**
|
|
* If the app launch was triggered by an app link, it will pop the link url,
|
|
* otherwise it will return `null`
|
|
*/
|
|
static popInitialURL(): ?string {
|
|
var initialURL = _initialURL;
|
|
_initialURL = null;
|
|
return initialURL;
|
|
}
|
|
}
|
|
|
|
module.exports = LinkingIOS;
|