diff --git a/Examples/UIExplorer/AppStateExample.js b/Examples/UIExplorer/AppStateExample.js
deleted file mode 100644
index 04a58c5e80cfb4..00000000000000
--- a/Examples/UIExplorer/AppStateExample.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * 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.
- *
- * @flow
- */
-'use strict';
-
-var React = require('react-native');
-var {
- AppState,
- StyleSheet,
- Text,
- TouchableHighlight,
- View,
-} = React;
-
-var Button = React.createClass({
- render: function() {
- return (
-
-
- {this.props.label}
-
-
- );
- }
-});
-
-var styles = StyleSheet.create({
- button: {
- padding: 10,
- alignItems: 'center',
- justifyContent: 'center',
- },
- buttonLabel: {
- color: 'blue',
- },
-});
-
-exports.title = 'AppState';
-exports.description = 'App background status and badge value';
-exports.examples = [
-{
- title: 'Set Badge Number',
- render: function() {
- return (
-
-
- );
- },
-}];
diff --git a/Examples/UIExplorer/PushNotificationIOSExample.js b/Examples/UIExplorer/PushNotificationIOSExample.js
new file mode 100644
index 00000000000000..8201a9662f22c8
--- /dev/null
+++ b/Examples/UIExplorer/PushNotificationIOSExample.js
@@ -0,0 +1,152 @@
+/**
+ * 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.
+ *
+ * @flow
+ */
+'use strict';
+
+var React = require('react-native');
+var {
+ AlertIOS,
+ PushNotificationIOS,
+ StyleSheet,
+ Text,
+ TouchableHighlight,
+ View,
+} = React;
+
+var Button = React.createClass({
+ render: function() {
+ return (
+
+
+ {this.props.label}
+
+
+ );
+ }
+});
+
+class NotificationExample extends React.Component {
+ componentWillMount() {
+ PushNotificationIOS.addEventListener('notification', this._onNotification);
+ }
+
+ componentWillUnmount() {
+ PushNotificationIOS.removeEventListener('notification', this._onNotification);
+ }
+
+ render() {
+ return (
+
+
+
+ );
+ }
+
+ _sendNotification() {
+ require('RCTDeviceEventEmitter').emit('remoteNotificationReceived', {
+ aps: {
+ alert: 'Sample notification',
+ badge: '+1',
+ sound: 'default',
+ category: 'REACT_NATIVE'
+ },
+ });
+ }
+
+ _onNotification(notification) {
+ AlertIOS.alert(
+ 'Notification Received',
+ `Alert message: ${notification.getMessage()}`,
+ [{
+ text: 'Dismiss',
+ onPress: null,
+ }]
+ );
+ }
+}
+
+class NotificationPermissionExample extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {permissions: null};
+ }
+
+ render() {
+ return (
+
+
+
+ {JSON.stringify(this.state.permissions)}
+
+
+ );
+ }
+
+ _showPermissions() {
+ PushNotificationIOS.checkPermissions((permissions) => {
+ this.setState({permissions});
+ });
+ }
+}
+
+var styles = StyleSheet.create({
+ button: {
+ padding: 10,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ buttonLabel: {
+ color: 'blue',
+ },
+});
+
+exports.title = 'PushNotificationIOS';
+exports.description = 'Apple PushNotification and badge value';
+exports.examples = [
+{
+ title: 'Badge Number',
+ render(): React.Component {
+ PushNotificationIOS.requestPermissions();
+
+ return (
+
+ PushNotificationIOS.setApplicationIconBadgeNumber(42)}
+ label="Set app's icon badge to 42"
+ />
+ PushNotificationIOS.setApplicationIconBadgeNumber(0)}
+ label="Clear app's icon badge"
+ />
+
+ );
+ },
+},
+{
+ title: 'Push Notifications',
+ render(): React.Component {
+ return ;
+ }
+},
+{
+ title: 'Notifications Permissions',
+ render(): React.Component {
+ return ;
+ }
+}];
diff --git a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
index 59adccff32d6ed..ff024216a51050 100644
--- a/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
+++ b/Examples/UIExplorer/UIExplorer.xcodeproj/project.pbxproj
@@ -21,6 +21,7 @@
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 147CED4B1AB34F8C00DA3E4C /* libRCTActionSheet.a */; };
+ 14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14DC67F11AB71876001358AB /* libRCTPushNotification.a */; };
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */; };
/* End PBXBuildFile section */
@@ -88,6 +89,13 @@
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTActionSheet;
};
+ 14DC67F01AB71876001358AB /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 14DC67E71AB71876001358AB /* RCTPushNotification.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 134814201AA4EA6300B7C361;
+ remoteInfo = RCTPushNotification;
+ };
D85B829B1AB6D5CE003F4FE2 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */;
@@ -116,6 +124,7 @@
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = UIExplorer/Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = UIExplorer/Info.plist; sourceTree = ""; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = UIExplorer/main.m; sourceTree = ""; };
+ 14DC67E71AB71876001358AB /* RCTPushNotification.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTPushNotification.xcodeproj; path = ../../Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj; sourceTree = ""; };
14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../../Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; };
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../../Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = ""; };
/* End PBXFileReference section */
@@ -135,6 +144,7 @@
00D2771C1AB8C55500DC1E48 /* libicucore.dylib in Frameworks */,
00D2771A1AB8C3E100DC1E48 /* libRCTWebSocketDebugger.a in Frameworks */,
D85B829E1AB6D5D7003F4FE2 /* libRCTVibration.a in Frameworks */,
+ 14DC67F41AB71881001358AB /* libRCTPushNotification.a in Frameworks */,
147CED4C1AB3532B00DA3E4C /* libRCTActionSheet.a in Frameworks */,
134454601AAFCABD003F0779 /* libRCTAdSupport.a in Frameworks */,
134A8A2A1AACED7A00945AAE /* libRCTGeolocation.a in Frameworks */,
@@ -177,6 +187,7 @@
isa = PBXGroup;
children = (
D85B82911AB6D5CE003F4FE2 /* RCTVibration.xcodeproj */,
+ 14DC67E71AB71876001358AB /* RCTPushNotification.xcodeproj */,
14E0EEC81AB118F7000DECC3 /* RCTActionSheet.xcodeproj */,
13417FFA1AA91531003F314A /* ReactKit.xcodeproj */,
134454551AAFCAAE003F0779 /* RCTAdSupport.xcodeproj */,
@@ -259,6 +270,14 @@
name = Products;
sourceTree = "";
};
+ 14DC67E81AB71876001358AB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 14DC67F11AB71876001358AB /* libRCTPushNotification.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
@@ -371,6 +390,10 @@
ProductGroup = 134180271AA91779003F314A /* Products */;
ProjectRef = 134180261AA91779003F314A /* RCTNetwork.xcodeproj */;
},
+ {
+ ProductGroup = 14DC67E81AB71876001358AB /* Products */;
+ ProjectRef = 14DC67E71AB71876001358AB /* RCTPushNotification.xcodeproj */;
+ },
{
ProductGroup = 13417FEB1AA914B8003F314A /* Products */;
ProjectRef = 13417FEA1AA914B8003F314A /* RCTText.xcodeproj */;
@@ -453,6 +476,13 @@
remoteRef = 147CED4A1AB34F8C00DA3E4C /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
+ 14DC67F11AB71876001358AB /* libRCTPushNotification.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libRCTPushNotification.a;
+ remoteRef = 14DC67F01AB71876001358AB /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
D85B829C1AB6D5CE003F4FE2 /* libRCTVibration.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
diff --git a/Examples/UIExplorer/UIExplorerList.js b/Examples/UIExplorer/UIExplorerList.js
index d0996fcbbbc283..14de683873144f 100644
--- a/Examples/UIExplorer/UIExplorerList.js
+++ b/Examples/UIExplorer/UIExplorerList.js
@@ -48,7 +48,6 @@ var APIS = [
require('./ActionSheetIOSExample'),
require('./AdSupportIOSExample'),
require('./AlertIOSExample'),
- require('./AppStateExample'),
require('./AppStateIOSExample'),
require('./AsyncStorageExample'),
require('./CameraRollExample.ios'),
@@ -56,6 +55,7 @@ var APIS = [
require('./LayoutExample'),
require('./NetInfoExample'),
require('./PointerEventsExample'),
+ require('./PushNotificationIOSExample'),
require('./StatusBarIOSExample'),
require('./TimerExample'),
require('./VibrationIOSExample'),
diff --git a/Libraries/AppState/AppState.js b/Libraries/AppState/AppState.js
deleted file mode 100644
index f1ef2505db321c..00000000000000
--- a/Libraries/AppState/AppState.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * 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 AppState
- */
-'use strict';
-
-var NativeModules = require('NativeModules');
-var RCTAppState = NativeModules.AppState;
-
-var AppState = {
-
- setApplicationIconBadgeNumber: function(number) {
- RCTAppState.setApplicationIconBadgeNumber(number);
- },
-
- getApplicationIconBadgeNumber: function(callback) {
- RCTAppState.getApplicationIconBadgeNumber(callback);
- },
-
-};
-
-module.exports = AppState;
diff --git a/Libraries/Utilities/PushNotificationIOS.js b/Libraries/PushNotificationIOS/PushNotificationIOS.js
similarity index 66%
rename from Libraries/Utilities/PushNotificationIOS.js
rename to Libraries/PushNotificationIOS/PushNotificationIOS.js
index fe77c69b3e914d..733ab24926c3b8 100644
--- a/Libraries/Utilities/PushNotificationIOS.js
+++ b/Libraries/PushNotificationIOS/PushNotificationIOS.js
@@ -7,22 +7,34 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule PushNotificationIOS
+ * @flow
*/
'use strict';
var NativeModules = require('NativeModules');
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
-
-var RCTPushNotificationManager = NativeModules.PushNotificationManager;
-if (RCTPushNotificationManager) {
- var _initialNotification = RCTPushNotificationManager.initialNotification;
-}
+var RCTPushNotificationManager = require('NativeModules').PushNotificationManager;
+var invariant = require('invariant');
var _notifHandlers = {};
+var _initialNotification = RCTPushNotificationManager &&
+ RCTPushNotificationManager.initialNotification;
var DEVICE_NOTIF_EVENT = 'remoteNotificationReceived';
class PushNotificationIOS {
+ _data: Object;
+ _alert: string | Object;
+ _sound: string;
+ _badgeCount: number;
+
+ static setApplicationIconBadgeNumber(number) {
+ RCTPushNotificationManager.setApplicationIconBadgeNumber(number);
+ }
+
+ static getApplicationIconBadgeNumber(callback) {
+ RCTPushNotificationManager.getApplicationIconBadgeNumber(callback);
+ }
static addEventListener(type, handler) {
_notifHandlers[handler] = RCTDeviceEventEmitter.addListener(
@@ -33,6 +45,18 @@ class PushNotificationIOS {
);
}
+ static requestPermissions() {
+ RCTPushNotificationManager.requestPermissions();
+ }
+
+ static checkPermissions(callback) {
+ invariant(
+ typeof callback === 'function',
+ 'Must provide a valid callback'
+ );
+ RCTPushNotificationManager.checkPermissions(callback);
+ }
+
static removeEventListener(type, handler) {
if (!_notifHandlers[handler]) {
return;
@@ -68,24 +92,24 @@ class PushNotificationIOS {
});
}
- getMessage() {
+ getMessage(): ?string | ?Object {
// alias because "alert" is an ambiguous name
return this._alert;
}
- getSound() {
+ getSound(): ?string {
return this._sound;
}
- getAlert() {
+ getAlert(): ?string | ?Object {
return this._alert;
}
- getBadgeCount() {
+ getBadgeCount(): ?number {
return this._badgeCount;
}
- getData() {
+ getData(): ?Object {
return this._data;
}
}
diff --git a/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/project.pbxproj b/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/project.pbxproj
new file mode 100644
index 00000000000000..507f47aa0b84ef
--- /dev/null
+++ b/Libraries/PushNotificationIOS/RCTPushNotification.xcodeproj/project.pbxproj
@@ -0,0 +1,256 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 148699CF1ABD045300480536 /* RCTPushNotificationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 148699CE1ABD045300480536 /* RCTPushNotificationManager.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 58B511D91A9E6C8500147676 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "include/$(PRODUCT_NAME)";
+ dstSubfolderSpec = 16;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 134814201AA4EA6300B7C361 /* libRCTPushNotification.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTPushNotification.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 148699CD1ABD045300480536 /* RCTPushNotificationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPushNotificationManager.h; sourceTree = ""; };
+ 148699CE1ABD045300480536 /* RCTPushNotificationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTPushNotificationManager.m; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 58B511D81A9E6C8500147676 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 134814211AA4EA7D00B7C361 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 134814201AA4EA6300B7C361 /* libRCTPushNotification.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 58B511D21A9E6C8500147676 = {
+ isa = PBXGroup;
+ children = (
+ 148699CD1ABD045300480536 /* RCTPushNotificationManager.h */,
+ 148699CE1ABD045300480536 /* RCTPushNotificationManager.m */,
+ 134814211AA4EA7D00B7C361 /* Products */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 58B511DA1A9E6C8500147676 /* RCTPushNotification */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTPushNotification" */;
+ buildPhases = (
+ 58B511D71A9E6C8500147676 /* Sources */,
+ 58B511D81A9E6C8500147676 /* Frameworks */,
+ 58B511D91A9E6C8500147676 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RCTPushNotification;
+ productName = RCTDataManager;
+ productReference = 134814201AA4EA6300B7C361 /* libRCTPushNotification.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 58B511D31A9E6C8500147676 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0610;
+ ORGANIZATIONNAME = Facebook;
+ TargetAttributes = {
+ 58B511DA1A9E6C8500147676 = {
+ CreatedOnToolsVersion = 6.1.1;
+ };
+ };
+ };
+ buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTPushNotification" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 58B511D21A9E6C8500147676;
+ productRefGroup = 58B511D21A9E6C8500147676;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 58B511DA1A9E6C8500147676 /* RCTPushNotification */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 58B511D71A9E6C8500147676 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 148699CF1ABD045300480536 /* RCTPushNotificationManager.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 58B511ED1A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ };
+ name = Debug;
+ };
+ 58B511EE1A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = YES;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 8.1;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 58B511F01A9E6C8500147676 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../ReactKit/**",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/ReactKit/build/Debug-iphoneos",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RCTPushNotification;
+ SKIP_INSTALL = YES;
+ };
+ name = Debug;
+ };
+ 58B511F11A9E6C8500147676 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
+ "$(SRCROOT)/../../ReactKit/**",
+ );
+ LIBRARY_SEARCH_PATHS = (
+ "$(inherited)",
+ "/Users/nicklockwood/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/ReactKit/build/Debug-iphoneos",
+ );
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = RCTPushNotification;
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTPushNotification" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511ED1A9E6C8500147676 /* Debug */,
+ 58B511EE1A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTPushNotification" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 58B511F01A9E6C8500147676 /* Debug */,
+ 58B511F11A9E6C8500147676 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 58B511D31A9E6C8500147676 /* Project object */;
+}
diff --git a/ReactKit/Modules/RCTPushNotificationManager.h b/Libraries/PushNotificationIOS/RCTPushNotificationManager.h
similarity index 52%
rename from ReactKit/Modules/RCTPushNotificationManager.h
rename to Libraries/PushNotificationIOS/RCTPushNotificationManager.h
index 69773c736c3a2d..b8ddd19d937e11 100644
--- a/ReactKit/Modules/RCTPushNotificationManager.h
+++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.h
@@ -7,13 +7,16 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
-#import
+#import
-extern NSString *const RKRemoteNotificationReceived;
-extern NSString *const RKOpenURLNotification;
+#import "RCTBridgeModule.h"
@interface RCTPushNotificationManager : NSObject
- (instancetype)initWithInitialNotification:(NSDictionary *)initialNotification NS_DESIGNATED_INITIALIZER;
++ (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;
++ (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification;
++ (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
+
@end
diff --git a/Libraries/PushNotificationIOS/RCTPushNotificationManager.m b/Libraries/PushNotificationIOS/RCTPushNotificationManager.m
new file mode 100644
index 00000000000000..19a0f90ee97ad9
--- /dev/null
+++ b/Libraries/PushNotificationIOS/RCTPushNotificationManager.m
@@ -0,0 +1,156 @@
+/**
+ * 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.
+ */
+
+#import "RCTPushNotificationManager.h"
+
+#import "RCTBridge.h"
+#import "RCTEventDispatcher.h"
+
+NSString *const RCTRemoteNotificationReceived = @"RemoteNotificationReceived";
+NSString *const RCTOpenURLNotification = @"RCTOpenURLNotification";
+
+@implementation RCTPushNotificationManager
+{
+ NSDictionary *_initialNotification;
+}
+
+@synthesize bridge = _bridge;
+
+- (instancetype)init
+{
+ return [self initWithInitialNotification:nil];
+}
+
+- (instancetype)initWithInitialNotification:(NSDictionary *)initialNotification
+{
+ if ((self = [super init])) {
+ _initialNotification = [initialNotification copy];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(handleRemoteNotificationReceived:)
+ name:RCTRemoteNotificationReceived
+ object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self
+ selector:@selector(handleOpenURLNotification:)
+ name:RCTOpenURLNotification
+ object:nil];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
++ (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
+{
+#ifdef __IPHONE_8_0
+ [application registerForRemoteNotifications];
+#endif
+}
+
++ (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)notification
+{
+ [[NSNotificationCenter defaultCenter] postNotificationName:RCTRemoteNotificationReceived
+ object:self
+ userInfo:notification];
+}
+
++ (BOOL)application:(UIApplication *)application
+ openURL:(NSURL *)url
+ sourceApplication:(NSString *)sourceApplication
+ annotation:(id)annotation
+{
+ NSDictionary *payload = @{@"url": [url absoluteString]};
+ [[NSNotificationCenter defaultCenter] postNotificationName:RCTOpenURLNotification
+ object:self
+ userInfo:payload];
+ return YES;
+}
+
+- (void)handleRemoteNotificationReceived:(NSNotification *)notification
+{
+ [_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationReceived"
+ body:[notification userInfo]];
+}
+
+- (void)handleOpenURLNotification:(NSNotification *)notification
+{
+ [_bridge.eventDispatcher sendDeviceEventWithName:@"openURL"
+ body:[notification userInfo]];
+}
+
+/**
+ * Update the application icon badge number on the home screen
+ */
++ (void)setApplicationIconBadgeNumber:(NSInteger)number
+{
+ RCT_EXPORT();
+
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ [self requestPermissions];
+ });
+
+ [UIApplication sharedApplication].applicationIconBadgeNumber = number;
+}
+
+/**
+ * Get the current application icon badge number on the home screen
+ */
++ (void)getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback
+{
+ RCT_EXPORT();
+
+ callback(@[
+ @([UIApplication sharedApplication].applicationIconBadgeNumber)
+ ]);
+}
+
++ (void)requestPermissions
+{
+ RCT_EXPORT();
+
+#ifdef __IPHONE_8_0
+ UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
+ UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
+ [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
+#else
+ [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
+#endif
+}
+
++ (void)checkPermissions:(RCTResponseSenderBlock)callback
+{
+ RCT_EXPORT();
+
+ NSMutableDictionary *permissions = [[NSMutableDictionary alloc] init];
+#ifdef __IPHONE_8_0
+ UIUserNotificationType types = [[[UIApplication sharedApplication] currentUserNotificationSettings] types];
+ permissions[@"alert"] = @((BOOL)(types & UIUserNotificationTypeAlert));
+ permissions[@"badge"] = @((BOOL)(types & UIUserNotificationTypeBadge));
+ permissions[@"sound"] = @((BOOL)(types & UIUserNotificationTypeSound));
+#else
+ UIRemoteNotificationType types = [[UIApplication sharedApplication] enabledRemoteNotificationTypes];
+ permissions[@"alert"] = @((BOOL)(types & UIRemoteNotificationTypeAlert));
+ permissions[@"badge"] = @((BOOL)(types & UIRemoteNotificationTypeBadge));
+ permissions[@"sound"] = @((BOOL)(types & UIRemoteNotificationTypeSound));
+#endif
+
+ callback(@[permissions]);
+}
+
+- (NSDictionary *)constantsToExport
+{
+ return @{
+ @"initialNotification": _initialNotification ?: [NSNull null]
+ };
+}
+
+@end
diff --git a/Libraries/Text/TextStylePropTypes.js b/Libraries/Text/TextStylePropTypes.js
index 8e28b131817fd4..8ed2c0f10c11b9 100644
--- a/Libraries/Text/TextStylePropTypes.js
+++ b/Libraries/Text/TextStylePropTypes.js
@@ -7,14 +7,15 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule TextStylePropTypes
+ * @flow
*/
'use strict';
var ReactPropTypes = require('ReactPropTypes');
var ViewStylePropTypes = require('ViewStylePropTypes');
-var TextStylePropTypes = {
- ...ViewStylePropTypes,
+// TODO: use spread instead of Object.assign/create after #6560135 is fixed
+var TextStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), {
fontFamily: ReactPropTypes.string,
fontSize: ReactPropTypes.number,
fontWeight: ReactPropTypes.oneOf(['normal' /*default*/, 'bold']),
@@ -28,7 +29,7 @@ var TextStylePropTypes = {
writingDirection: ReactPropTypes.oneOf(
['auto' /*default*/, 'ltr', 'rtl']
),
-};
+});
// Text doesn't support padding correctly (#4841912)
var unsupportedProps = Object.keys({
@@ -41,8 +42,8 @@ var unsupportedProps = Object.keys({
paddingHorizontal: null,
});
-for (var key in unsupportedProps) {
- delete TextStylePropTypes[key];
+for (var ii = 0; ii < unsupportedProps.length; ii++) {
+ delete TextStylePropTypes[unsupportedProps[ii]];
}
module.exports = TextStylePropTypes;
diff --git a/Libraries/Utilities/Dimensions.js b/Libraries/Utilities/Dimensions.js
index 3bfaf9c52f323f..80d564a2b5899f 100644
--- a/Libraries/Utilities/Dimensions.js
+++ b/Libraries/Utilities/Dimensions.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Dimensions
+ * @flow
*/
'use strict';
@@ -22,7 +23,7 @@ class Dimensions {
*
* @param {object} dims Simple string-keyed object of dimensions to set
*/
- static set(dims) {
+ static set(dims: {[key:string]: any}): bool {
Object.assign(dimensions, dims);
return true;
}
@@ -40,7 +41,7 @@ class Dimensions {
* @param {string} dim Name of dimension as defined when calling `set`.
* @returns {Object?} Value for the dimension.
*/
- static get(dim) {
+ static get(dim: string): Object {
invariant(dimensions[dim], 'No dimension set for key ' + dim);
return dimensions[dim];
}
diff --git a/Libraries/Utilities/MessageQueue.js b/Libraries/Utilities/MessageQueue.js
index 81091a54f81fd1..9d6eb867e471c2 100644
--- a/Libraries/Utilities/MessageQueue.js
+++ b/Libraries/Utilities/MessageQueue.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule MessageQueue
+ * @flow
*/
'use strict';
var ErrorUtils = require('ErrorUtils');
@@ -18,6 +19,18 @@ var JSTimersExecution = require('JSTimersExecution');
var INTERNAL_ERROR = 'Error in MessageQueue implementation';
+type ModulesConfig = {
+ [key:string]: {
+ moduleID: number;
+ methods: {[key:string]: {
+ methodID: number;
+ }};
+ }
+}
+
+type NameToID = {[key:string]: number}
+type IDToName = {[key:number]: string}
+
/**
* So as not to confuse static build system.
*/
@@ -45,7 +58,11 @@ var jsCall = function(module, methodName, params) {
* efficient numeric IDs.
* @class MessageQueue
*/
-var MessageQueue = function(remoteModulesConfig, localModulesConfig, customRequire) {
+var MessageQueue = function(
+ remoteModulesConfig: ModulesConfig,
+ localModulesConfig: ModulesConfig,
+ customRequire: (id: string) => any
+) {
this._requireFunc = customRequire || requireFunc;
this._initBookeeping();
this._initNamingMap(remoteModulesConfig, localModulesConfig);
@@ -128,7 +145,10 @@ var MessageQueueMixin = {
* @param {object} remoteModulesConfig Configuration of modules and their
* methods.
*/
- _initNamingMap: function(remoteModulesConfig, localModulesConfig) {
+ _initNamingMap: function(
+ remoteModulesConfig: ModulesConfig,
+ localModulesConfig: ModulesConfig
+ ) {
this._remoteModuleNameToModuleID = {};
this._remoteModuleIDToModuleName = {}; // Reverse
@@ -142,11 +162,11 @@ var MessageQueueMixin = {
this._localModuleNameToMethodIDToName = {}; // Reverse
function fillMappings(
- modulesConfig,
- moduleNameToModuleID,
- moduleIDToModuleName,
- moduleNameToMethodNameToID,
- moduleNameToMethodIDToName
+ modulesConfig: ModulesConfig,
+ moduleNameToModuleID: NameToID,
+ moduleIDToModuleName: IDToName,
+ moduleNameToMethodNameToID: {[key:string]: NameToID},
+ moduleNameToMethodIDToName: {[key:string]: IDToName}
) {
for (var moduleName in modulesConfig) {
var moduleConfig = modulesConfig[moduleName];
diff --git a/Libraries/Utilities/PixelRatio.js b/Libraries/Utilities/PixelRatio.js
index 4770937b1fed2f..f8e23398a9c802 100644
--- a/Libraries/Utilities/PixelRatio.js
+++ b/Libraries/Utilities/PixelRatio.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule PixelRatio
+ * @flow
*/
'use strict';
@@ -52,7 +53,7 @@ class PixelRatio {
* - PixelRatio.get() === 3
* - iPhone 6 plus
*/
- static get() {
+ static get(): number {
return Dimensions.get('window').scale;
}
}
diff --git a/Libraries/Utilities/Platform.ios.js b/Libraries/Utilities/Platform.ios.js
index 515e7d288168ef..d02e6fde2a66f3 100644
--- a/Libraries/Utilities/Platform.ios.js
+++ b/Libraries/Utilities/Platform.ios.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule Platform
+ * @flow
*/
'use strict';
diff --git a/Libraries/Utilities/RCTLog.js b/Libraries/Utilities/RCTLog.js
index 8955382e0dfb64..e5a8db49c4bd5f 100644
--- a/Libraries/Utilities/RCTLog.js
+++ b/Libraries/Utilities/RCTLog.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule RCTLog
+ * @flow
*/
/* globals nativeLoggingHook */
'use strict';
@@ -31,7 +32,7 @@ class RCTLog {
logFn,
'Level "' + level + '" not one of ' + Object.keys(levelsMap)
);
- if (typeof nativeLoggingHook === 'undefined') {
+ if (typeof global.nativeLoggingHook === 'undefined') {
// We already printed in xcode, so only log here if using a js debugger
console[logFn].apply(console, args);
}
diff --git a/Libraries/Utilities/RCTRenderingPerf.js b/Libraries/Utilities/RCTRenderingPerf.js
index 5662902f01b47c..c6466aa641afc3 100644
--- a/Libraries/Utilities/RCTRenderingPerf.js
+++ b/Libraries/Utilities/RCTRenderingPerf.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule RCTRenderingPerf
+ * @flow
*/
'use strict';
@@ -15,6 +16,11 @@ var ReactPerf = require('ReactPerf');
var invariant = require('invariant');
+type perfModule = {
+ start: () => void;
+ stop: () => void;
+}
+
var perfModules = [];
var enabled = false;
@@ -58,7 +64,7 @@ var RCTRenderingPerf = {
perfModules.forEach((module) => module.stop());
},
- register: function(module) {
+ register: function(module: perfModule) {
invariant(
typeof module.start === 'function',
'Perf module should have start() function'
diff --git a/Libraries/Utilities/TimerMixin.js b/Libraries/Utilities/TimerMixin.js
index 2c570660a4f8aa..0fc68457d67dac 100644
--- a/Libraries/Utilities/TimerMixin.js
+++ b/Libraries/Utilities/TimerMixin.js
@@ -7,9 +7,13 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule TimerMixin
+ * @flow
*/
'use strict';
+var setImmediate = require('setImmediate');
+var clearImmediate = require('clearImmediate');
+
/**
* Using bare setTimeout, setInterval, setImmediate and
* requestAnimationFrame calls is very dangerous because if you forget to cancel
@@ -35,7 +39,10 @@
*/
var setter = function(setter, clearer, array) {
- return function(callback, delta) {
+ return function(
+ callback: () => void,
+ delta: number
+ ): number {
var id = setter(() => {
clearer.call(this, id);
callback.apply(this, arguments);
@@ -51,7 +58,7 @@
};
var clearer = function(clearer, array) {
- return function(id) {
+ return function(id: number) {
if (this[array]) {
var index = this[array].indexOf(id);
if (index !== -1) {
@@ -75,8 +82,8 @@
var _setImmediate = setter(setImmediate, _clearImmediate, _immediates);
var _rafs = 'TimerMixin_rafs';
- var _cancelAnimationFrame = clearer(cancelAnimationFrame, _rafs);
- var _requestAnimationFrame = setter(requestAnimationFrame, _cancelAnimationFrame, _rafs);
+ var _cancelAnimationFrame = clearer(window.cancelAnimationFrame, _rafs);
+ var _requestAnimationFrame = setter(window.requestAnimationFrame, _cancelAnimationFrame, _rafs);
var TimerMixin = {
componentWillUnmount: function() {
diff --git a/Libraries/Utilities/createStrictShapeTypeChecker.js b/Libraries/Utilities/createStrictShapeTypeChecker.js
index 0812aa6f49a7a0..cd0d5757a96dcf 100644
--- a/Libraries/Utilities/createStrictShapeTypeChecker.js
+++ b/Libraries/Utilities/createStrictShapeTypeChecker.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule createStrictShapeTypeChecker
+ * @flow
*/
'use strict';
@@ -15,8 +16,10 @@ var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames');
var invariant = require('invariant');
var merge = require('merge');
-function createStrictShapeTypeChecker(shapeTypes) {
- function checkType(isRequired, props, propName, componentName, location) {
+function createStrictShapeTypeChecker(
+ shapeTypes: {[key: string]: ReactPropsCheckType}
+): ReactPropsChainableTypeChecker {
+ function checkType(isRequired, props, propName, componentName, location?) {
if (!props[propName]) {
if (isRequired) {
invariant(
@@ -29,7 +32,8 @@ function createStrictShapeTypeChecker(shapeTypes) {
}
var propValue = props[propName];
var propType = typeof propValue;
- var locationName = ReactPropTypeLocationNames[location];
+ var locationName =
+ location && ReactPropTypeLocationNames[location] || '(unknown)';
if (propType !== 'object') {
invariant(
false,
@@ -57,11 +61,17 @@ function createStrictShapeTypeChecker(shapeTypes) {
error.message +
`\nBad object: ` + JSON.stringify(props[propName], null, ' ')
);
- return error;
}
}
}
- var chainedCheckType = checkType.bind(null, false);
+ function chainedCheckType(
+ props: {[key: string]: any},
+ propName: string,
+ componentName: string,
+ location?: string
+ ): ?Error {
+ return checkType(false, props, propName, componentName, location);
+ }
chainedCheckType.isRequired = checkType.bind(null, true);
return chainedCheckType;
}
diff --git a/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js b/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js
index e5530204e3f773..9263116ed7075f 100644
--- a/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js
+++ b/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js
@@ -7,8 +7,11 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule deepFreezeAndThrowOnMutationInDev
+ * @flow
*/
+'use strict';
+
/**
* If your application is accepting different values for the same field over
* time and is doing a diff on them, you can either (1) create a copy or
@@ -26,7 +29,7 @@
* Freezing the object and adding the throw mechanism is expensive and will
* only be used in DEV.
*/
-function deepFreezeAndThrowOnMutationInDev(object) {
+function deepFreezeAndThrowOnMutationInDev(object: Object) {
if (__DEV__) {
if (typeof object !== 'object' ||
object === null ||
diff --git a/Libraries/Utilities/differ/insetsDiffer.js b/Libraries/Utilities/differ/insetsDiffer.js
index 887a482a1078dc..b0a40947037937 100644
--- a/Libraries/Utilities/differ/insetsDiffer.js
+++ b/Libraries/Utilities/differ/insetsDiffer.js
@@ -7,9 +7,17 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule insetsDiffer
+ * @flow
*/
'use strict';
+type Inset = {
+ top: ?number;
+ left: ?number;
+ right: ?number;
+ bottom: ?number;
+}
+
var dummyInsets = {
top: undefined,
left: undefined,
@@ -17,7 +25,10 @@ var dummyInsets = {
bottom: undefined,
};
-var insetsDiffer = function(one, two) {
+var insetsDiffer = function(
+ one: ?Inset,
+ two: ?Inset
+): bool {
one = one || dummyInsets;
two = two || dummyInsets;
return one !== two && (
diff --git a/Libraries/Utilities/differ/pointsDiffer.js b/Libraries/Utilities/differ/pointsDiffer.js
index cd2c558d293589..c4939199f06eb7 100644
--- a/Libraries/Utilities/differ/pointsDiffer.js
+++ b/Libraries/Utilities/differ/pointsDiffer.js
@@ -7,12 +7,18 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule pointsDiffer
+ * @flow
*/
'use strict';
+type Point = {
+ x: ?number;
+ y: ?number;
+}
+
var dummyPoint = {x: undefined, y: undefined};
-var pointsDiffer = function(one, two) {
+var pointsDiffer = function(one: ?Point, two: ?Point): bool {
one = one || dummyPoint;
two = two || dummyPoint;
return one !== two && (
diff --git a/Libraries/Utilities/groupByEveryN.js b/Libraries/Utilities/groupByEveryN.js
index d1127c1d153cdc..a8b353ad66dde6 100644
--- a/Libraries/Utilities/groupByEveryN.js
+++ b/Libraries/Utilities/groupByEveryN.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule groupByEveryN
+ * @flow
*/
/**
@@ -26,7 +27,7 @@
*/
'use strict';
-function groupByEveryN(array, n) {
+function groupByEveryN(array: Array, n: number): Array> {
var result = [];
var temp = [];
diff --git a/Libraries/Utilities/logError.js b/Libraries/Utilities/logError.js
index 1a0be1a136c989..aac41be0be8369 100644
--- a/Libraries/Utilities/logError.js
+++ b/Libraries/Utilities/logError.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule logError
+ * @flow
*/
'use strict';
diff --git a/Libraries/Utilities/mergeFast.js b/Libraries/Utilities/mergeFast.js
index 8923167e7e3138..e55ac76ed6a192 100644
--- a/Libraries/Utilities/mergeFast.js
+++ b/Libraries/Utilities/mergeFast.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule mergeFast
+ * @flow
*/
'use strict';
@@ -19,7 +20,7 @@
* @return {object} Merging of two objects, including prototype
* inherited properties.
*/
-var mergeFast = function(one, two) {
+var mergeFast = function(one: Object, two: Object): Object {
var ret = {};
for (var keyOne in one) {
ret[keyOne] = one[keyOne];
diff --git a/Libraries/Utilities/mergeIntoFast.js b/Libraries/Utilities/mergeIntoFast.js
index 666e7384ea5a85..1a97d07b7b17fd 100644
--- a/Libraries/Utilities/mergeIntoFast.js
+++ b/Libraries/Utilities/mergeIntoFast.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule mergeIntoFast
+ * @flow
*/
'use strict';
@@ -17,7 +18,7 @@
* @param {object} one Object to assign to.
* @param {object} two Object to assign from.
*/
-var mergeIntoFast = function(one, two) {
+var mergeIntoFast = function(one: Object, two: Object): void {
for (var keyTwo in two) {
one[keyTwo] = two[keyTwo];
}
diff --git a/Libraries/Utilities/nativeModulePrefixNormalizer.js b/Libraries/Utilities/nativeModulePrefixNormalizer.js
index 3c33fa5033b21c..151417bc5acf00 100644
--- a/Libraries/Utilities/nativeModulePrefixNormalizer.js
+++ b/Libraries/Utilities/nativeModulePrefixNormalizer.js
@@ -7,11 +7,14 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule nativeModulePrefixNormalizer
+ * @flow
*/
'use strict';
// Dirty hack to support old (RK) and new (RCT) native module name conventions
-function nativeModulePrefixNormalizer(modules) {
+function nativeModulePrefixNormalizer(
+ modules: {[key: string]: any}
+): void {
Object.keys(modules).forEach((moduleName) => {
var strippedName = moduleName.replace(/^(RCT|RK)/, '');
if (modules['RCT' + strippedName] && modules['RK' + strippedName]) {
diff --git a/Libraries/Utilities/truncate.js b/Libraries/Utilities/truncate.js
index b35c0658851ac4..1d318e8353d6b1 100644
--- a/Libraries/Utilities/truncate.js
+++ b/Libraries/Utilities/truncate.js
@@ -7,11 +7,18 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule truncate
+ * @flow
*/
'use strict';
var merge = require('merge');
+type truncateOptions = {
+ breakOnWords: boolean;
+ minDelta: number;
+ elipsis: string;
+}
+
var defaultOptions = {
breakOnWords: true,
minDelta: 10, // Prevents truncating a tiny bit off the end
@@ -19,7 +26,11 @@ var defaultOptions = {
};
// maxChars (including elipsis)
-var truncate = function(str, maxChars, options) {
+var truncate = function(
+ str: ?string,
+ maxChars: number,
+ options: truncateOptions
+): ?string {
options = merge(defaultOptions, options);
if (str && str.length &&
str.length - options.minDelta + options.elipsis.length >= maxChars) {
diff --git a/Libraries/Vibration/VibrationIOS.ios.js b/Libraries/Vibration/VibrationIOS.ios.js
index c24a50606c4b45..2a1dc701c17383 100644
--- a/Libraries/Vibration/VibrationIOS.ios.js
+++ b/Libraries/Vibration/VibrationIOS.ios.js
@@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule VibrationIOS
+ * @flow
*/
'use strict';
diff --git a/Libraries/react-native/react-native.js b/Libraries/react-native/react-native.js
index ea8a25b72fe21e..96080d09fa2067 100644
--- a/Libraries/react-native/react-native.js
+++ b/Libraries/react-native/react-native.js
@@ -42,7 +42,6 @@ var ReactNative = Object.assign(Object.create(require('React')), {
AlertIOS: require('AlertIOS'),
Animation: require('Animation'),
AppRegistry: require('AppRegistry'),
- AppState: require('AppState'),
AppStateIOS: require('AppStateIOS'),
AsyncStorage: require('AsyncStorage'),
CameraRoll: require('CameraRoll'),
@@ -50,6 +49,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
LayoutAnimation: require('LayoutAnimation'),
NetInfo: require('NetInfo'),
PixelRatio: require('PixelRatio'),
+ PushNotificationIOS: require('PushNotificationIOS'),
StatusBarIOS: require('StatusBarIOS'),
StyleSheet: require('StyleSheet'),
TimerMixin: require('TimerMixin'),
diff --git a/ReactKit/Base/RCTConvert.h b/ReactKit/Base/RCTConvert.h
index 4e4fee60013b36..66d77e41654efe 100644
--- a/ReactKit/Base/RCTConvert.h
+++ b/ReactKit/Base/RCTConvert.h
@@ -10,9 +10,9 @@
#import
#import
-#import "../Layout/Layout.h"
-#import "../Views/RCTAnimationType.h"
-#import "../Views/RCTPointerEvents.h"
+#import "Layout.h"
+#import "RCTAnimationType.h"
+#import "RCTPointerEvents.h"
/**
* This class provides a collection of conversion functions for mapping
diff --git a/ReactKit/Modules/RCTAppState.m b/ReactKit/Modules/RCTAppState.m
index 930d998eba633a..ab44a70a3055ec 100644
--- a/ReactKit/Modules/RCTAppState.m
+++ b/ReactKit/Modules/RCTAppState.m
@@ -87,26 +87,4 @@ - (void)getCurrentAppState:(RCTResponseSenderBlock)callback
callback(@[@{@"app_state": _lastKnownState}]);
}
-/**
- * Update the application icon badge number on the home screen
- */
-- (void)setApplicationIconBadgeNumber:(NSInteger)number
-{
- RCT_EXPORT();
-
- [UIApplication sharedApplication].applicationIconBadgeNumber = number;
-}
-
-/**
- * Get the current application icon badge number on the home screen
- */
-- (void)getApplicationIconBadgeNumber:(RCTResponseSenderBlock)callback
-{
- RCT_EXPORT();
-
- callback(@[
- @([UIApplication sharedApplication].applicationIconBadgeNumber)
- ]);
-}
-
@end
diff --git a/ReactKit/Modules/RCTPushNotificationManager.m b/ReactKit/Modules/RCTPushNotificationManager.m
deleted file mode 100644
index 324b8d8ec06312..00000000000000
--- a/ReactKit/Modules/RCTPushNotificationManager.m
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * 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.
- */
-
-#import "RCTPushNotificationManager.h"
-
-#import "RCTAssert.h"
-#import "RCTBridge.h"
-#import "RCTEventDispatcher.h"
-
-NSString *const RKRemoteNotificationReceived = @"RemoteNotificationReceived";
-NSString *const RKOpenURLNotification = @"RKOpenURLNotification";
-
-@implementation RCTPushNotificationManager
-{
- NSDictionary *_initialNotification;
-}
-
-@synthesize bridge = _bridge;
-
-- (instancetype)init
-{
- return [self initWithInitialNotification:nil];
-}
-
-- (instancetype)initWithInitialNotification:(NSDictionary *)initialNotification
-{
- if ((self = [super init])) {
- _initialNotification = [initialNotification copy];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(handleRemoteNotificationReceived:)
- name:RKRemoteNotificationReceived
- object:nil];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(handleOpenURLNotification:)
- name:RKOpenURLNotification
- object:nil];
- }
- return self;
-}
-
-- (void)handleRemoteNotificationReceived:(NSNotification *)notification
-{
- [_bridge.eventDispatcher sendDeviceEventWithName:@"remoteNotificationReceived"
- body:[notification userInfo]];
-}
-
-- (void)handleOpenURLNotification:(NSNotification *)notification
-{
- [_bridge.eventDispatcher sendDeviceEventWithName:@"openURL"
- body:[notification userInfo]];
-}
-
-- (NSDictionary *)constantsToExport
-{
- return @{
- @"initialNotification": _initialNotification ?: [NSNull null]
- };
-}
-
-- (void)dealloc
-{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-}
-
-@end
diff --git a/ReactKit/Views/RCTShadowView.h b/ReactKit/Views/RCTShadowView.h
index 858a6c80df7609..1a042ee1aaf42a 100644
--- a/ReactKit/Views/RCTShadowView.h
+++ b/ReactKit/Views/RCTShadowView.h
@@ -9,8 +9,7 @@
#import
-#import "../Layout/Layout.h"
-
+#import "Layout.h"
#import "RCTViewNodeProtocol.h"
@class RCTSparseArray;
diff --git a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js
index bbdb064175b522..8ebe9c5a630bfb 100644
--- a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js
+++ b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/__tests__/DependencyGraph-test.js
@@ -166,6 +166,69 @@ describe('DependencyGraph', function() {
});
});
+ pit('should default main package to index.js', function() {
+ var root = '/root';
+ fs.__setMockFilesystem({
+ 'root': {
+ 'index.js': 'require("aPackage")',
+ 'aPackage': {
+ 'package.json': JSON.stringify({
+ name: 'aPackage',
+ }),
+ 'index.js': 'lol',
+ }
+ }
+ });
+
+ var dgraph = new DependencyGraph({
+ roots: [root],
+ fileWatcher: fileWatcher
+ });
+ return dgraph.load().then(function() {
+ expect(dgraph.getOrderedDependencies('/root/index.js'))
+ .toEqual([
+ {id: '/root/index.js', path: '/root/index.js', dependencies: ['aPackage']},
+ { id: 'aPackage/index',
+ path: '/root/aPackage/index.js',
+ dependencies: []
+ },
+ ]);
+ });
+ });
+
+ pit('should default use index.js if main is a dir', function() {
+ var root = '/root';
+ fs.__setMockFilesystem({
+ 'root': {
+ 'index.js': 'require("aPackage")',
+ 'aPackage': {
+ 'package.json': JSON.stringify({
+ name: 'aPackage',
+ main: 'lib',
+ }),
+ lib: {
+ 'index.js': 'lol',
+ },
+ }
+ }
+ });
+
+ var dgraph = new DependencyGraph({
+ roots: [root],
+ fileWatcher: fileWatcher
+ });
+ return dgraph.load().then(function() {
+ expect(dgraph.getOrderedDependencies('/root/index.js'))
+ .toEqual([
+ {id: '/root/index.js', path: '/root/index.js', dependencies: ['aPackage']},
+ { id: 'aPackage/lib/index',
+ path: '/root/aPackage/lib/index.js',
+ dependencies: []
+ },
+ ]);
+ });
+ });
+
pit('should ignore malformed packages', function() {
var root = '/root';
fs.__setMockFilesystem({
diff --git a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js
index 14139159f66a4f..4622864d28045c 100644
--- a/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js
+++ b/packager/react-packager/src/DependencyResolver/haste/DependencyGraph/index.js
@@ -184,6 +184,12 @@ DependecyGraph.prototype.resolveDependency = function(
var main = packageJson.main || 'index';
modulePath = withExtJs(path.join(packageJson._root, main));
dep = this._graph[modulePath];
+
+ // Some packages use just a dir and rely on an index.js inside that dir.
+ if (dep == null) {
+ dep = this._graph[path.join(packageJson._root, main, 'index.js')];
+ }
+
if (dep == null) {
throw new Error(
'Cannot find package main file for package: ' + packageJson._root
diff --git a/packager/react-packager/src/DependencyResolver/haste/polyfills/require.js b/packager/react-packager/src/DependencyResolver/haste/polyfills/require.js
index e7fdde25023d5f..00955ba4a7e0c9 100644
--- a/packager/react-packager/src/DependencyResolver/haste/polyfills/require.js
+++ b/packager/react-packager/src/DependencyResolver/haste/polyfills/require.js
@@ -196,7 +196,7 @@
if (!module) {
msg = 'Requiring unknown module "' + id + '"';
if (__DEV__) {
- msg += '. It may not be loaded yet. Did you forget to run arc build?';
+ msg += '. If you are sure the module is there, try restarting the packager.';
}
throw new ModuleError(msg);
}
diff --git a/packager/react-packager/src/Server/__tests__/Server-test.js b/packager/react-packager/src/Server/__tests__/Server-test.js
index 8e638311aa82f3..aa7ca3493a8f81 100644
--- a/packager/react-packager/src/Server/__tests__/Server-test.js
+++ b/packager/react-packager/src/Server/__tests__/Server-test.js
@@ -186,6 +186,7 @@ describe('processRequest', function() {
expect(packageFunc.mock.calls.length).toBe(1);
triggerFileChange('all','path/file.js', options.projectRoots[0]);
jest.runAllTimers();
+ jest.runAllTimers();
})
.then(function() {
expect(packageFunc.mock.calls.length).toBe(2);
diff --git a/packager/react-packager/src/Server/index.js b/packager/react-packager/src/Server/index.js
index cc4f0bdf5d8e3c..19ec003954a01a 100644
--- a/packager/react-packager/src/Server/index.js
+++ b/packager/react-packager/src/Server/index.js
@@ -92,8 +92,10 @@ Server.prototype._rebuildPackages = function() {
Object.keys(packages).forEach(function(key) {
var options = getOptionsFromUrl(key);
// Wait for a previous build (if exists) to finish.
- packages[key] = (packages[key] || q()).then(function() {
- return buildPackage(options).then(function(p) {
+ packages[key] = (packages[key] || q()).finally(function() {
+ // With finally promise callback we can't change the state of the promise
+ // so we need to reassign the promise.
+ packages[key] = buildPackage(options).then(function(p) {
// Make a throwaway call to getSource to cache the source string.
p.getSource({
inlineSourceMap: options.dev,
@@ -102,6 +104,7 @@ Server.prototype._rebuildPackages = function() {
return p;
});
});
+ return packages[key];
});
};