diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..0a912dff1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,53 @@ +--- +name: '🐛 Bug Report' +about: Report a reproducible bug or regression in this library. +--- + +# Bug + + + +## Environment info + + + +`react-native info` output: + +```bash + // paste it here +``` + +Library version: x.x.x + +## Steps To Reproduce + + + +1. +2. +... + +Describe what you expected to happen: + +1. +2. + +## Reproducible sample code + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..18e53748a --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,28 @@ +--- +name: '💡 Feature Request' +about: Submit your idea for a change in the codebase. +--- + +# Feature Request + + + +## Why it is needed + + + +## Possible implementation + + + +### Code sample + + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 000000000..4a6267364 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,13 @@ +--- +name: '🤔 Questions and Help' +about: Use this if there is something not clear about the code or its docs. +--- + +# Question + + diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 000000000..a8b110a8c --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,17 @@ +name: "Close stale issues" +on: + schedule: + - cron: "0 0 * * *" + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: "This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 30 days if no further activity occurs. Thank you for your contributions." + stale-pr-message: "This pull request has been automatically marked as stale because it has not had recent activity. It will be closed in 30 days if no further activity occurs. Thank you for your contributions." + days-before-stale: 365 + days-before-close: 30 + operations-per-run: 30 diff --git a/.gitignore b/.gitignore index d06fcbb96..adec98609 100644 --- a/.gitignore +++ b/.gitignore @@ -34,9 +34,15 @@ local.properties node_modules/* npm-debug.log +yarn.lock +package-lock.json + android/android.iml android/gradle.properties android/gradle/ android/gradlew android/gradlew.bat android/src/main/gen + +#Debug only +google-services.json diff --git a/CHANGELOG.md b/CHANGELOG.md index bffe3a492..22a882392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,119 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Features + +### Fixed + +## [3.5.2] - 2020-05-25 + +### Fixed + +- (Android) Sounds are playing even in Do Not Disturb [#1432](https://github.com/zo0r/react-native-push-notification/issues/1432#issuecomment-633367111) +- (Android) onNotification fires every time when the app goes from background to foreground [#1455](https://github.com/zo0r/react-native-push-notification/issues/1455) +- (Android) Cannot send to notification centre because there is no 'message' field in: Bundle [#1452](https://github.com/zo0r/react-native-push-notification/issues/1452) + +## [3.5.1] - 2020-05-20 + +### Fixed + +- (Android) When updating 3.4 to 3.5, unable to compile Android [#1449](https://github.com/zo0r/react-native-push-notification/pull/1449) + +## [3.5.0] - 2020-05-20 + +### Features + +- (Android) Enables the ability to support multiple push providers [#1445](https://github.com/zo0r/react-native-push-notification/pull/1445) + +### Fixed + +- (Android) No sound on notifications [#1432](https://github.com/zo0r/react-native-push-notification/issues/1432) +- (Android) onNotification is not calling when app is in background [#1446](https://github.com/zo0r/react-native-push-notification/pull/1446) +- (Android) `number` and `id` do not crash if NaN is passed in Android. + +## [3.4.0] - 2020-05-08 + +### Features + +- (Android) Call `onRegister` when [Firebase renew token](). +- (Android) Added Abandon Permissions method to Android [#1425](https://github.com/zo0r/react-native-push-notification/pull/1425) +- (Android) Add a new key in `AndroidManifest.xml` to allow/remove notification in foreground. + +```xml + +``` + +### Fixed + +- (Android) `number` and `id` are now correctly handled as number in Android. +- (iOS) Update push-notification-ios to 1.2.0 [#1410](https://github.com/zo0r/react-native-push-notification/pull/1410) +- Make sure to import PushNotificationIOS from react-native first [#617](https://github.com/zo0r/react-native-push-notification/pull/617) + +## [3.3.1] - 2020-05-01 + +### Fixed + +- (Android) Fix regression with the importance of the notification. + +## [3.3.0] - 2020-04-29 + +### Features + +- (Android) Keep interface parity with PushNotificationIOS [#909](https://github.com/zo0r/react-native-push-notification/pull/909) +- (Android) Unsubscribe from topic [#917](https://github.com/zo0r/react-native-push-notification/pull/917) +- (Android) Add notification data in onNotification [#1212](https://github.com/zo0r/react-native-push-notification/pull/1212) + +### Fixed + +- (Android) Create default channel to receive notification when background / killed. +- (Android) Fix vibrate: false is ignored [#878](https://github.com/zo0r/react-native-push-notification/issues/1140) +- `package.json` fix suffic in main, `index` => `index.js` [#878](https://github.com/zo0r/react-native-push-notification/pull/878) + +### Breaking changes + +- (Android) Remove specific code for GCM [#1322](https://github.com/zo0r/react-native-push-notification/issues/1322) +- `` must be removed. + +## [3.2.1] - 2020-04-20 + +### Fixed + +- Invalid type `Strint` wrong typo +- Missing import + +## [3.2.0] - 2020-04-20 + +### Features + +- (Android) Allow to silence Android foreground notifications [#1183](https://github.com/zo0r/react-native-push-notification/pull/1183) +- (Android) Allow to set the notification to executes on idle [#959](https://github.com/zo0r/react-native-push-notification/pull/959) +- (iOS) Add missing "category" parameter when scheduling local notifications. [#457](https://github.com/zo0r/react-native-push-notification/pull/457) + +### Fixed + +- Fix: Breaking android x compatibility regression +- Fix: Use FirebaseInstanceId for deviceToken, not from Intent [#1355](https://github.com/zo0r/react-native-push-notification/pull/1355) +- Fix: security issue `limit the components that Intent will resolve to` [#687](https://github.com/zo0r/react-native-push-notification/pull/687) +- Fix: remove fishy reference from android project files [#1226](https://github.com/zo0r/react-native-push-notification/pull/1226) +- Fix: `JSON value '' of type NSNull cannot be converted to NSDictionary` [#1030](https://github.com/zo0r/react-native-push-notification/pull/1030) +- Fix: Fixed foreground FCM banner notifications and notification sound [#1042](https://github.com/zo0r/react-native-push-notification/pull/1042) +- Upgrade ShortCutBadger to 1.1.22 [#646](https://github.com/zo0r/react-native-push-notification/pull/646) +- Upgrade exemple to React-Native 0.62.2 +- Remove Types from the code use [@types/react-native-push-notification](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-native-push-notification) instead. +- Remove GCM and C2DM references in README.md + +### Possible Breaking change + +- Rename firebaseVersion to firebaseMessagingVersion [#1191](https://github.com/zo0r/react-native-push-notification/pull/1191) in gradle.build + +### Documentation + +- Abandon permissions unregisters remote only [#1282](https://github.com/zo0r/react-native-push-notification/pull/1282) +- Use full path for manifest [#567](https://github.com/zo0r/react-native-push-notification/pull/567) +- Update broken link to docs [#995](https://github.com/zo0r/react-native-push-notification/pull/995) +- Missing step for android manual installation [#1363](https://github.com/zo0r/react-native-push-notification/pull/1363) + ## [3.1.3] - 2019-05-25 ## Fixed diff --git a/README.md b/README.md index be310ff4b..f06bbfe6c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # React Native Push Notifications -[![npm version](https://badge.fury.io/js/react-native-push-notification.svg?update=8)](http://badge.fury.io/js/react-native-push-notification) -[![npm downloads](https://img.shields.io/npm/dm/react-native-push-notification.svg?update=8)](http://badge.fury.io/js/react-native-push-notification) + +[![npm version](https://badge.fury.io/js/react-native-push-notification.svg?update=9)](http://badge.fury.io/js/react-native-push-notification) +[![npm downloads](https://img.shields.io/npm/dm/react-native-push-notification.svg?update=9)](http://badge.fury.io/js/react-native-push-notification) React Native Local and Remote Notifications for iOS and Android @@ -20,9 +21,13 @@ Changelog is available from version 3.1.3 here: [Changelog](https://github.com/z ## Installation -`npm install --save react-native-push-notification` or `yarn add react-native-push-notification` +### NPM + +`npm install --save react-native-push-notification` -`react-native link react-native-push-notification` +### Yarn + +`yarn add react-native-push-notification` **NOTE: For Android, you will still have to manually update the AndroidManifest.xml (as below) in order to use Scheduled Notifications.** @@ -38,18 +43,18 @@ Having a problem? Read the [troubleshooting](./trouble-shooting.md) guide before The component uses PushNotificationIOS for the iOS part. -[Please see: PushNotificationIOS](https://facebook.github.io/react-native/docs/pushnotificationios.html#content) +[Please see: PushNotificationIOS](https://github.com/react-native-community/react-native-push-notification-ios) ## Android manual Installation -**NOTE: `play-service-gcm` and `firebase-messaging`, prior to version 15 requires to have the same version number in order to work correctly at build time and at run time. To use a specific version:** +**NOTE: `firebase-messaging`, prior to version 15 requires to have the same version number in order to work correctly at build time and at run time. To use a specific version:** In your `android/build.gradle` ```gradle ext { googlePlayServicesVersion = "" // default: "+" - firebaseVersion = "" // default: "+" + firebaseMessagingVersion = "" // default: "+" // Other settings compileSdkVersion = // default: 23 @@ -61,17 +66,11 @@ ext { **NOTE: localNotification() works without changes in the application part, while localNotificationSchedule() only works with these changes:** -In your `AndroidManifest.xml` +In your `android/app/src/main/AndroidManifest.xml` ```xml ..... - - - - @@ -81,21 +80,13 @@ In your `AndroidManifest.xml` android:value="YOUR NOTIFICATION CHANNEL NAME"/> + + + - - - - - - - - - + android:resource="@color/white"/> @@ -103,19 +94,7 @@ In your `AndroidManifest.xml` - - - - - - - - - - @@ -123,11 +102,59 @@ In your `AndroidManifest.xml` - ..... +``` +If not using a built in Android color (`@android:color/{name}`) for the `notification_color` `meta-data` item. +In `android/app/src/main/res/values/colors.xml` (Create the file if it doesn't exist). + +```xml + + #FFF + ``` +### If you use remote notifications + +Make sure you have installed setup Firebase correctly. + +In `android/build.gradle` + +```gradle + +buildscript { + ... + dependencies { + ... + classpath('com.google.gms:google-services:4.3.3') + ... + } +} +``` + +In `android/app/build.gradle` + +```gradle +dependencies { + ... + implementation 'com.google.firebase:firebase-analytics:17.3.0' + ... +} + +apply plugin: 'com.google.gms.google-services' + +``` + +Then put your `google-services.json` in `android/app/`. + +**Note: [firebase/release-notes](https://firebase.google.com/support/release-notes/android)** + +> The Firebase Android library `firebase-core` is no longer needed. This SDK included the Firebase SDK for Google Analytics. +> +> Now, to use Analytics or any Firebase product that recommends the use of Analytics (see table below), you need to explicitly add the Analytics dependency: `com.google.firebase:firebase-analytics:17.3.0`. + +### If you don't use autolink + In `android/settings.gradle` ```gradle @@ -136,12 +163,14 @@ include ':react-native-push-notification' project(':react-native-push-notification').projectDir = file('../node_modules/react-native-push-notification/android') ``` -In `android/app/src/res/values/colors.xml` (Create the file if it doesn't exist). +In your `android/app/build.gradle` -```xml - - #FFF - +```gradle + dependencies { + ... + implementation project(':react-native-push-notification') + ... + } ``` Manually register module in `MainApplication.java` (if you did not use `react-native link`): @@ -174,32 +203,30 @@ public class MainApplication extends Application implements ReactApplication { ## Usage ```javascript -var PushNotification = require('react-native-push-notification'); +import PushNotificationIOS from "@react-native-community/push-notification-ios"; +var PushNotification = require("react-native-push-notification"); PushNotification.configure({ // (optional) Called when Token is generated (iOS and Android) - onRegister: function(token) { - console.log('TOKEN:', token); + onRegister: function (token) { + console.log("TOKEN:", token); }, - // (required) Called when a remote or local notification is opened or received - onNotification: function(notification) { - console.log('NOTIFICATION:', notification); + // (required) Called when a remote is received or opened, or local notification is opened + onNotification: function (notification) { + console.log("NOTIFICATION:", notification); // process the notification - // required on iOS only (see fetchCompletionHandler docs: https://facebook.github.io/react-native/docs/pushnotificationios.html) + // (required) Called when a remote is received or opened, or local notification is opened notification.finish(PushNotificationIOS.FetchResult.NoData); }, - // ANDROID ONLY: GCM or FCM Sender ID (product_number) (optional - not required for local notifications, but is need to receive remote push notifications) - senderID: 'YOUR GCM (OR FCM) SENDER ID', - // IOS ONLY (optional): default: all - Permissions to register. permissions: { alert: true, badge: true, - sound: true + sound: true, }, // Should the initial notification be popped automatically @@ -210,15 +237,16 @@ PushNotification.configure({ * (optional) default: true * - Specified if permissions (ios) and token (android and ios) will requested or not, * - if not, you must call PushNotificationsHandler.requestPermissions() later + * - if you are not using remote notification or do not have Firebase installed, use this: + * requestPermissions: Platform.OS === 'ios' */ - requestPermissions: true + requestPermissions: true, }); ``` ## Example app -Example folder contains an example app to demonstrate how to use this package. The notification Handling is done in `NotifService.js`. For Remote notifications, configure your SenderId in `app.json`. You can also edit it directly in the app. -To send Push notifications, you can use the online tool [PushWatch](https://www.pushwatch.com/gcm/). +Example folder contains an example app to demonstrate how to use this package. The notification Handling is done in `NotifService.js`. Please test your PRs with this example app before submitting them. It'll help maintaining this repo. @@ -245,37 +273,39 @@ EXAMPLE: ```javascript PushNotification.localNotification({ - /* Android Only Properties */ - id: '0', // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID - ticker: "My Notification Ticker", // (optional) - autoCancel: true, // (optional) default: true - largeIcon: "ic_launcher", // (optional) default: "ic_launcher" - smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher" - bigText: "My big text that will be shown when notification is expanded", // (optional) default: "message" prop - subText: "This is a subText", // (optional) default: none - color: "red", // (optional) default: system default - vibrate: true, // (optional) default: true - vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000 - tag: 'some_tag', // (optional) add tag to message - group: "group", // (optional) add group to message - ongoing: false, // (optional) set whether this is an "ongoing" notification - priority: "high", // (optional) set notification priority, default: high - visibility: "private", // (optional) set notification visibility, default: private - importance: "high", // (optional) set notification importance, default: high - - /* iOS only properties */ - alertAction: // (optional) default: view - category: // (optional) default: null - userInfo: // (optional) default: null (object containing additional notification data) - - /* iOS and Android properties */ - title: "My Notification Title", // (optional) - message: "My Notification Message", // (required) - playSound: false, // (optional) default: true - soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) - number: '10', // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero) - repeatType: 'day', // (optional) Repeating interval. Check 'Repeating Notifications' section for more info. - actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more + /* Android Only Properties */ + id: 0, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID + ticker: "My Notification Ticker", // (optional) + autoCancel: true, // (optional) default: true + largeIcon: "ic_launcher", // (optional) default: "ic_launcher" + smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher" + bigText: "My big text that will be shown when notification is expanded", // (optional) default: "message" prop + subText: "This is a subText", // (optional) default: none + color: "red", // (optional) default: system default + vibrate: true, // (optional) default: true + vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000 + tag: "some_tag", // (optional) add tag to message + group: "group", // (optional) add group to message + ongoing: false, // (optional) set whether this is an "ongoing" notification + priority: "high", // (optional) set notification priority, default: high + visibility: "private", // (optional) set notification visibility, default: private + importance: "high", // (optional) set notification importance, default: high + allowWhileIdle: false, // (optional) set notification to work while on doze, default: false + ignoreInForeground: false, // (optional) if true, the notification will not be visible when the app is in the foreground (useful for parity with how iOS notifications appear) + + /* iOS only properties */ + alertAction: "view", // (optional) default: view + category: "", // (optional) default: empty string + userInfo: {}, // (optional) default: {} (using null throws a JSON value '' error) + + /* iOS and Android properties */ + title: "My Notification Title", // (optional) + message: "My Notification Message", // (required) + playSound: false, // (optional) default: true + soundName: "default", // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) + number: 10, // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero) + repeatType: "day", // (optional) Repeating interval. Check 'Repeating Notifications' section for more info. + actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more }); ``` @@ -288,8 +318,8 @@ EXAMPLE: ```javascript PushNotification.localNotificationSchedule({ //... You can use all the options from localNotifications - message: 'My Notification Message', // (required) - date: new Date(Date.now() + 60 * 1000) // in 60 secs + message: "My Notification Message", // (required) + date: new Date(Date.now() + 60 * 1000), // in 60 secs }); ``` @@ -321,16 +351,88 @@ PushNotification.localNotification({ PushNotification.cancelLocalNotifications({id: '123'}); ``` +#### IOS + +The `userInfo` parameter for `PushNotification.localNotification` is required for this operation and must contain an `id` parameter. The id supplied will then be used for the cancel operation. + +```javascript +// IOS +PushNotification.localNotification({ + ... + userInfo: { id: '123' } + ... +}); +PushNotification.cancelLocalNotifications({id: '123'}); +``` + +### 2) cancelAllLocalNotifications + +`PushNotification.cancelAllLocalNotifications()` + +Cancels all scheduled notifications AND clears the notifications alerts that are in the notification centre. + +_NOTE: there is currently no api for removing specific notification alerts from the notification centre._ + +### 3) removeAllDeliveredNotifications + +```javascript +PushNotificationIOS.removeAllDeliveredNotifications(); +``` + +Remove all delivered notifications from Notification Center + +### 4) getDeliveredNotifications + +```javascript +PushNotificationIOS.getDeliveredNotifications(callback); +``` + +Provides you with a list of the app’s notifications that are still displayed in Notification Center + +**Parameters:** + +| Name | Type | Required | Description | +| -------- | -------- | -------- | ----------------------------------------------------------- | +| callback | function | Yes | Function which receive an array of delivered notifications. | + +A delivered notification is an object containing: + +- `identifier` : The identifier of this notification. +- `title` : The title of this notification. +- `body` : The body of this notification. +- `category` : The category of this notification (optional). +- `userInfo` : An object containing additional notification data (optional). +- `thread-id` : The thread identifier of this notification, if has one. + +### 5) removeDeliveredNotifications + +```javascript +PushNotificationIOS.removeDeliveredNotifications(identifiers); +``` + +Removes the specified notifications from Notification Center + +**Parameters:** + +| Name | Type | Required | Description | +| ----------- | ----- | -------- | ---------------------------------- | +| identifiers | array | Yes | Array of notification identifiers. | + + +## Abandon Permissions + +`PushNotification.abandonPermissions()` Revokes the current token and unregister for all remote notifications received via APNS or FCM. + ## Notification priority (optional) Specify `priority` to set priority of notification. Default value: "high" Available options: -"max" = NotficationCompat.PRIORITY_MAX -"high" = NotficationCompat.PRIORITY_HIGH -"low" = NotficationCompat.PRIORITY_LOW -"min" = NotficationCompat.PRIORITY_MIN +"max" = NotficationCompat.PRIORITY_MAX +"high" = NotficationCompat.PRIORITY_HIGH +"low" = NotficationCompat.PRIORITY_LOW +"min" = NotficationCompat.PRIORITY_MIN "default" = NotficationCompat.PRIORITY_DEFAULT More information: https://developer.android.com/reference/android/app/Notification.html#PRIORITY_DEFAULT @@ -341,8 +443,8 @@ More information: https://developer.android.com/reference/android/app/Notificati Available options: -"private" = NotficationCompat.VISIBILITY_PRIVATE -"public" = NotficationCompat.VISIBILITY_PUBLIC +"private" = NotficationCompat.VISIBILITY_PRIVATE +"public" = NotficationCompat.VISIBILITY_PUBLIC "secret" = NotficationCompat.VISIBILITY_SECRET More information: https://developer.android.com/reference/android/app/Notification.html#VISIBILITY_PRIVATE @@ -353,41 +455,30 @@ More information: https://developer.android.com/reference/android/app/Notificati Available options: -"default" = NotificationManager.IMPORTANCE_DEFAULT -"max" = NotificationManager.IMPORTANCE_MAX -"high" = NotificationManager.IMPORTANCE_HIGH -"low" = NotificationManager.IMPORTANCE_LOW -"min" = NotificationManager.IMPORTANCE_MIN -"none" = NotificationManager.IMPORTANCE_NONE +"default" = NotificationManager.IMPORTANCE_DEFAULT +"max" = NotificationManager.IMPORTANCE_MAX +"high" = NotificationManager.IMPORTANCE_HIGH +"low" = NotificationManager.IMPORTANCE_LOW +"min" = NotificationManager.IMPORTANCE_MIN +"none" = NotificationManager.IMPORTANCE_NONE "unspecified" = NotificationManager.IMPORTANCE_UNSPECIFIED More information: https://developer.android.com/reference/android/app/NotificationManager#IMPORTANCE_DEFAULT -#### IOS - -The `userInfo` parameter for `PushNotification.localNotification` is required for this operation and must contain an `id` parameter. The id supplied will then be used for the cancel operation. - -```javascript -// IOS -PushNotification.localNotification({ - ... - userInfo: { id: '123' } - ... -}); -PushNotification.cancelLocalNotifications({id: '123'}); -``` +## Notification while idle -### 2) cancelAllLocalNotifications +(optional) Specify `allowWhileIdle` to set if the notification should be allowed to execute even when the system is on low-power idle modes. -`PushNotification.cancelAllLocalNotifications()` +On Android 6.0 (API level 23) and forward, the Doze was introduced to reduce battery consumption when the device is unused for long periods of time. But while on Doze the AlarmManager alarms (used to show scheduled notifications) are deferred to the next maintenance window. This may cause the notification to be delayed while on Doze. -Cancels all scheduled notifications AND clears the notifications alerts that are in the notification centre. +This can significantly impact the power use of the device when idle. So it must only be used when the notification is required to go off on a exact time, for example on a calendar notification. -_NOTE: there is currently no api for removing specific notification alerts from the notification centre._ +More information: +https://developer.android.com/training/monitoring-device-state/doze-standby ## Repeating Notifications -(optional) Specify `repeatType` and optionally `repeatTime` while scheduling the local notification. Check the local notification example above. +(optional) Specify `repeatType` and optionally `repeatTime` (Android-only) while scheduling the local notification. Check the local notification example above. Property `repeatType` could be one of `month`, `week`, `day`, `hour`, `minute`, `time`. If specified as time, it should be accompanied by one more parameter `repeatTime` which should the number of milliseconds between each interval. @@ -446,6 +537,8 @@ Same parameters as `PushNotification.localNotification()` `PushNotification.subscribeToTopic(topic: string)` Subscribe to a topic (works only with Firebase) +`PushNotification.unsubscribeFromTopic(topic: string)` Unsubscribe from a topic (works only with Firebase) + ## Checking Notification Permissions `PushNotification.checkPermissions(callback: Function)` Check permissions @@ -459,5 +552,3 @@ Same parameters as `PushNotification.localNotification()` ## iOS Only Methods `PushNotification.getApplicationIconBadgeNumber(callback: Function)` Get badge number - -`PushNotification.abandonPermissions()` Abandon permissions diff --git a/android/.project b/android/.project new file mode 100644 index 000000000..3964dd3f5 --- /dev/null +++ b/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000..c25633f0a --- /dev/null +++ b/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(6.3)) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/android/build.gradle b/android/build.gradle index 3ec4c0fd7..141fec0b2 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -43,15 +43,15 @@ android { } dependencies { - def supportLibVersion = project.hasProperty('supportLibVersion') ? project.supportLibVersion : DEFAULT_SUPPORT_LIB_VERSION - def googlePlayServicesVersion = project.hasProperty('googlePlayServicesVersion') ? project.googlePlayServicesVersion : DEFAULT_GOOGLE_PLAY_SERVICES_VERSION - def firebaseVersion = project.hasProperty('firebaseVersion') ? project.firebaseVersion : DEFAULT_FIREBASE_MESSAGING_VERSION + // Use either AndroidX library names or old/support library names based on major version of support lib + def supportLibVersion = safeExtGet('supportLibVersion', '27.1.1') + def supportLibMajorVersion = supportLibVersion.split('\\.')[0] as int + def appCompatLibName = (supportLibMajorVersion < 20) ? "androidx.appcompat:appcompat" : "com.android.support:appcompat-v7" implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation 'junit:junit:4.12' - implementation "com.android.support:appcompat-v7:$supportLibVersion" + implementation "$appCompatLibName:$supportLibVersion" implementation 'com.facebook.react:react-native:+' - implementation "com.google.android.gms:play-services-gcm:$googlePlayServicesVersion" - implementation 'me.leolin:ShortcutBadger:1.1.8@aar' - implementation "com.google.firebase:firebase-messaging:$firebaseVersion" + implementation 'me.leolin:ShortcutBadger:1.1.22@aar' + implementation "com.google.firebase:firebase-messaging:${safeExtGet('firebaseMessagingVersion', '+')}" } diff --git a/android/proguard-rules.pro b/android/proguard-rules.pro deleted file mode 100644 index f7e855c93..000000000 --- a/android/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /usr/local/Cellar/android-sdk/24.4.1/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/android/react-native-notifications.iml b/android/react-native-notifications.iml deleted file mode 100644 index 0851c6ed0..000000000 --- a/android/react-native-notifications.iml +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/react-native-push-notification.iml b/android/react-native-push-notification.iml deleted file mode 100644 index 4c1e6c240..000000000 --- a/android/react-native-push-notification.iml +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/helpers/ApplicationBadgeHelper.java b/android/src/main/java/com/dieam/reactnativepushnotification/helpers/ApplicationBadgeHelper.java index ad7538761..e97ebae5a 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/helpers/ApplicationBadgeHelper.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/helpers/ApplicationBadgeHelper.java @@ -10,26 +10,18 @@ import me.leolin.shortcutbadger.Badger; import me.leolin.shortcutbadger.ShortcutBadger; -import me.leolin.shortcutbadger.impl.SamsungHomeBadger; /** * Helper for setting application launcher icon badge counts. - *

- * This is a wrapper around {@link ShortcutBadger}, with a couple enhancements: - *

- * - If the first attempt fails, don't retry. This keeps logs clean, as failed attempts are noisy. - * - Test and apply a separate method for older Samsung devices, which ShortcutBadger has - * (perhaps over-aggressively) deprecated. ref: https://github.com/leolin310148/ShortcutBadger/issues/40 + * This is a wrapper around {@link ShortcutBadger}: */ public class ApplicationBadgeHelper { public static final ApplicationBadgeHelper INSTANCE = new ApplicationBadgeHelper(); private static final String LOG_TAG = "ApplicationBadgeHelper"; - private static final Badger LEGACY_SAMSUNG_BADGER = new SamsungHomeBadger(); private Boolean applyAutomaticBadger; - private Boolean applySamsungBadger; private ComponentName componentName; private ApplicationBadgeHelper() { @@ -40,7 +32,6 @@ public void setApplicationIconBadgeNumber(Context context, int number) { componentName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent(); } tryAutomaticBadge(context, number); - tryLegacySamsungBadge(context, number); } private void tryAutomaticBadge(Context context, int number) { @@ -57,43 +48,4 @@ private void tryAutomaticBadge(Context context, int number) { } ShortcutBadger.applyCount(context, number); } - - private void tryLegacySamsungBadge(Context context, int number) { - // First attempt to apply legacy samsung badge. Check if eligible, then attempt it. - if (null == applySamsungBadger) { - applySamsungBadger = isLegacySamsungLauncher(context) && applyLegacySamsungBadge(context, number); - if (applySamsungBadger) { - FLog.i(LOG_TAG, "First attempt to use legacy Samsung badger succeeded; permanently enabling method."); - } else { - FLog.w(LOG_TAG, "First attempt to use legacy Samsung badger failed; permanently disabling method."); - } - return; - } else if (!applySamsungBadger) { - return; - } - applyLegacySamsungBadge(context, number); - } - - private boolean isLegacySamsungLauncher(Context context) { - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_HOME); - ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); - - if (resolveInfo == null || resolveInfo.activityInfo.name.toLowerCase().contains("resolver")) { - return false; - } - - String currentHomePackage = resolveInfo.activityInfo.packageName; - return LEGACY_SAMSUNG_BADGER.getSupportLaunchers().contains(currentHomePackage); - } - - private boolean applyLegacySamsungBadge(Context context, int number) { - try { - LEGACY_SAMSUNG_BADGER.executeBadge(context, componentName, number); - return true; - } catch (Exception e) { - FLog.w(LOG_TAG, "Legacy Samsung badger failed", e); - return false; - } - } } diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotification.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotification.java index 2b38ef89a..4ceb65d5c 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotification.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotification.java @@ -8,11 +8,14 @@ import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; + +import androidx.annotation.NonNull; import androidx.core.app.NotificationManagerCompat; import com.dieam.reactnativepushnotification.helpers.ApplicationBadgeHelper; import com.facebook.react.bridge.ActivityEventListener; import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.Promise; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; @@ -22,12 +25,17 @@ import com.facebook.react.bridge.ReadableMap; import com.facebook.react.bridge.WritableMap; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Random; import android.util.Log; +import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.Task; +import com.google.firebase.iid.FirebaseInstanceId; +import com.google.firebase.iid.InstanceIdResult; import com.google.firebase.messaging.FirebaseMessaging; public class RNPushNotification extends ReactContextBaseJavaModule implements ActivityEventListener { @@ -49,7 +57,7 @@ public RNPushNotification(ReactApplicationContext reactContext) { // This is used to delivery callbacks to JS mJsDelivery = new RNPushNotificationJsDelivery(reactContext); - registerNotificationsRegistration(); + mRNPushNotificationHelper.checkOrCreateDefaultChannel(); } @Override @@ -73,6 +81,8 @@ private Bundle getBundleFromIntent(Intent intent) { } return bundle; } + + @Override public void onNewIntent(Intent intent) { Bundle bundle = this.getBundleFromIntent(intent); if (bundle != null) { @@ -82,21 +92,6 @@ public void onNewIntent(Intent intent) { } } - private void registerNotificationsRegistration() { - IntentFilter intentFilter = new IntentFilter(getReactApplicationContext().getPackageName() + ".RNPushNotificationRegisteredToken"); - - getReactApplicationContext().registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String token = intent.getStringExtra("token"); - WritableMap params = Arguments.createMap(); - params.putString("deviceToken", token); - - mJsDelivery.sendEvent("remoteNotificationsRegistered", params); - } - }, intentFilter); - } - private void registerNotificationsReceiveNotificationActions(ReadableArray actions) { IntentFilter intentFilter = new IntentFilter(); // Add filter for each actions. @@ -104,6 +99,7 @@ private void registerNotificationsReceiveNotificationActions(ReadableArray actio String action = actions.getString(i); intentFilter.addAction(getReactApplicationContext().getPackageName() + "." + action); } + getReactApplicationContext().registerReceiver(new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -128,23 +124,34 @@ public void checkPermissions(Promise promise) { } @ReactMethod - public void requestPermissions(String senderID) { - ReactContext reactContext = getReactApplicationContext(); - - Intent GCMService = new Intent(reactContext, RNPushNotificationRegistrationService.class); - - try { - GCMService.putExtra("senderID", senderID); - reactContext.startService(GCMService); - } catch (Exception e) { - Log.d("EXCEPTION SERVICE::::::", "requestPermissions: " + e); - } + public void requestPermissions() { + final RNPushNotificationJsDelivery fMjsDelivery = mJsDelivery; + + FirebaseInstanceId.getInstance().getInstanceId() + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + if (!task.isSuccessful()) { + Log.e(LOG_TAG, "exception", task.getException()); + return; + } + + WritableMap params = Arguments.createMap(); + params.putString("deviceToken", task.getResult().getToken()); + fMjsDelivery.sendEvent("remoteNotificationsRegistered", params); + } + }); } @ReactMethod public void subscribeToTopic(String topic) { FirebaseMessaging.getInstance().subscribeToTopic(topic); } + + @ReactMethod + public void unsubscribeFromTopic(String topic) { + FirebaseMessaging.getInstance().unsubscribeFromTopic(topic); + } @ReactMethod public void presentLocalNotification(ReadableMap details) { @@ -201,10 +208,6 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { * Cancels all scheduled local notifications, and removes all entries from the notification * centre. * - * We're attempting to keep feature parity with the RN iOS implementation in - * RCTPushNotificationManager. - * - * @see RN docs */ public void cancelAllLocalNotifications() { mRNPushNotificationHelper.cancelAllScheduledNotifications(); @@ -215,10 +218,6 @@ public void cancelAllLocalNotifications() { /** * Cancel scheduled notifications, and removes notifications from the notification centre. * - * Note - as we are trying to achieve feature parity with iOS, this method cannot be used - * to remove specific alerts from the notification centre. - * - * @see RN docs */ public void cancelLocalNotifications(ReadableMap userInfo) { mRNPushNotificationHelper.cancelScheduledNotification(userInfo); @@ -236,4 +235,48 @@ public void clearLocalNotification(int notificationID) { public void registerNotificationActions(ReadableArray actions) { registerNotificationsReceiveNotificationActions(actions); } + + @ReactMethod + /** + * Clears all notifications from the notification center + * + */ + public void removeAllDeliveredNotifications() { + mRNPushNotificationHelper.clearNotifications(); + } + + @ReactMethod + /** + * Returns a list of all notifications currently in the Notification Center + */ + public void getDeliveredNotifications(Callback callback) { + callback.invoke(mRNPushNotificationHelper.getDeliveredNotifications()); + } + + @ReactMethod + /** + * Removes notifications from the Notification Center, whose id matches + * an element in the provided array + */ + public void removeDeliveredNotifications(ReadableArray identifiers) { + mRNPushNotificationHelper.clearDeliveredNotifications(identifiers); + } + + @ReactMethod + /** + * Unregister for all remote notifications received + */ + public void abandonPermissions() { + new Thread(new Runnable() { + @Override + public void run() { + try { + FirebaseInstanceId.getInstance().deleteInstanceId(); + Log.i(LOG_TAG, "InstanceID deleted"); + } catch (IOException e) { + Log.e(LOG_TAG, "exception", e); + } + } + }).start(); + } } diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationAttributes.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationAttributes.java index a20e6d156..0d2099ab7 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationAttributes.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationAttributes.java @@ -126,7 +126,6 @@ public static RNPushNotificationAttributes fromJson(String notificationAttribute /** * User to find notifications: *

- * https://github.com/facebook/react-native/blob/master/Libraries/PushNotificationIOS/RCTPushNotificationManager.m#L294 * * @param userInfo map of fields to match * @return true all fields in userInfo object match, false otherwise diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationConfig.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationConfig.java index edba739ef..f65a8dfc5 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationConfig.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationConfig.java @@ -10,6 +10,7 @@ class RNPushNotificationConfig { private static final String KEY_CHANNEL_NAME = "com.dieam.reactnativepushnotification.notification_channel_name"; private static final String KEY_CHANNEL_DESCRIPTION = "com.dieam.reactnativepushnotification.notification_channel_description"; + private static final String KEY_NOTIFICATION_FOREGROUND = "com.dieam.reactnativepushnotification.notification_foreground"; private static final String KEY_NOTIFICATION_COLOR = "com.dieam.reactnativepushnotification.notification_color"; private static Bundle metadata; @@ -31,7 +32,10 @@ public RNPushNotificationConfig(Context context) { public String getChannelName() { try { - return metadata.getString(KEY_CHANNEL_NAME); + final String name = metadata.getString(KEY_CHANNEL_NAME); + if (name != null && name.length() > 0) { + return name; + } } catch (Exception e) { Log.w(RNPushNotification.LOG_TAG, "Unable to find " + KEY_CHANNEL_NAME + " in manifest. Falling back to default"); } @@ -40,13 +44,17 @@ public String getChannelName() { } public String getChannelDescription() { try { - return metadata.getString(KEY_CHANNEL_DESCRIPTION); + final String description = metadata.getString(KEY_CHANNEL_DESCRIPTION); + if (description != null) { + return description; + } } catch (Exception e) { Log.w(RNPushNotification.LOG_TAG, "Unable to find " + KEY_CHANNEL_DESCRIPTION + " in manifest. Falling back to default"); } // Default return ""; } + public int getNotificationColor() { try { int resourceId = metadata.getInt(KEY_NOTIFICATION_COLOR); @@ -57,4 +65,14 @@ public int getNotificationColor() { // Default return -1; } + + public boolean getNotificationForeground() { + try { + return metadata.getBoolean(KEY_NOTIFICATION_FOREGROUND, false); + } catch (Exception e) { + Log.w(RNPushNotification.LOG_TAG, "Unable to find " + KEY_NOTIFICATION_FOREGROUND + " in manifest. Falling back to default"); + } + // Default + return false; + } } diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java index be6e85046..84bb493ee 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java @@ -1,6 +1,8 @@ package com.dieam.reactnativepushnotification.modules; +import android.app.ActivityManager; +import android.app.ActivityManager.RunningAppProcessInfo; import android.app.AlarmManager; import android.app.Application; import android.app.Notification; @@ -15,14 +17,20 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; +import android.media.AudioAttributes; import android.media.RingtoneManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; -import androidx.core.app.NotificationCompat; +import android.service.notification.StatusBarNotification; import android.util.Log; +import androidx.core.app.NotificationCompat; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; import org.json.JSONArray; import org.json.JSONException; @@ -31,6 +39,8 @@ import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; +import java.util.List; +import java.util.Set; import static com.dieam.reactnativepushnotification.modules.RNPushNotification.LOG_TAG; import static com.dieam.reactnativepushnotification.modules.RNPushNotificationAttributes.fromJson; @@ -70,13 +80,19 @@ private AlarmManager getAlarmManager() { } private PendingIntent toScheduleNotificationIntent(Bundle bundle) { - int notificationID = Integer.parseInt(bundle.getString("id")); + try { + int notificationID = Integer.parseInt(bundle.getString("id")); + + Intent notificationIntent = new Intent(context, RNPushNotificationPublisher.class); + notificationIntent.putExtra(RNPushNotificationPublisher.NOTIFICATION_ID, notificationID); + notificationIntent.putExtras(bundle); - Intent notificationIntent = new Intent(context, RNPushNotificationPublisher.class); - notificationIntent.putExtra(RNPushNotificationPublisher.NOTIFICATION_ID, notificationID); - notificationIntent.putExtras(bundle); + return PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + } catch (Exception e) { + Log.e(LOG_TAG, "Unable to parse Notification ID", e); + } - return PendingIntent.getBroadcast(context, notificationID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); + return null; } public void sendNotificationScheduled(Bundle bundle) { @@ -121,15 +137,24 @@ public void sendNotificationScheduled(Bundle bundle) { public void sendNotificationScheduledCore(Bundle bundle) { long fireDate = (long) bundle.getDouble("fireDate"); + boolean allowWhileIdle = bundle.getBoolean("allowWhileIdle"); // If the fireDate is in past, this will fire immediately and show the // notification to the user PendingIntent pendingIntent = toScheduleNotificationIntent(bundle); + if(pendingIntent == null) { + return; + } + Log.d(LOG_TAG, String.format("Setting a notification with id %s at time %s", bundle.getString("id"), Long.toString(fireDate))); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - getAlarmManager().setExact(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); + if(allowWhileIdle && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + getAlarmManager().setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); + } else { + getAlarmManager().setExact(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); + } } else { getAlarmManager().set(AlarmManager.RTC_WAKEUP, fireDate, pendingIntent); } @@ -158,6 +183,8 @@ public void sendToNotificationCentre(Bundle bundle) { Resources res = context.getResources(); String packageName = context.getPackageName(); + String channel_id = NOTIFICATION_CHANNEL_ID; + String title = bundle.getString("title"); if (title == null) { ApplicationInfo appInfo = context.getApplicationInfo(); @@ -189,6 +216,39 @@ public void sendToNotificationCentre(Bundle bundle) { } } + int importance = NotificationManager.IMPORTANCE_HIGH; + final String importanceString = bundle.getString("importance"); + + if (importanceString != null) { + switch(importanceString.toLowerCase()) { + case "default": + importance = NotificationManager.IMPORTANCE_DEFAULT; + break; + case "max": + importance = NotificationManager.IMPORTANCE_MAX; + break; + case "high": + importance = NotificationManager.IMPORTANCE_HIGH; + break; + case "low": + importance = NotificationManager.IMPORTANCE_LOW; + break; + case "min": + importance = NotificationManager.IMPORTANCE_MIN; + break; + case "none": + importance = NotificationManager.IMPORTANCE_NONE; + break; + case "unspecified": + importance = NotificationManager.IMPORTANCE_UNSPECIFIED; + break; + default: + importance = NotificationManager.IMPORTANCE_HIGH; + } + } + + channel_id = channel_id + "-" + importance; + int visibility = NotificationCompat.VISIBILITY_PRIVATE; final String visibilityString = bundle.getString("visibility"); @@ -208,14 +268,20 @@ public void sendToNotificationCentre(Bundle bundle) { } } - NotificationCompat.Builder notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) + NotificationCompat.Builder notification = new NotificationCompat.Builder(context, channel_id) .setContentTitle(title) .setTicker(bundle.getString("ticker")) .setVisibility(visibility) .setPriority(priority) .setAutoCancel(bundle.getBoolean("autoCancel", true)); - + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher + // Changing Default mode of notification + notification.setDefaults(Notification.DEFAULT_LIGHTS); + } + String group = bundle.getString("group"); + if (group != null) { notification.setGroup(group); } @@ -280,9 +346,13 @@ public void sendToNotificationCentre(Bundle bundle) { bundle.putBoolean("userInteraction", true); intent.putExtra("notification", bundle); + Uri soundUri = null; + if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) { - Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + String soundName = bundle.getString("soundName"); + if (soundName != null) { if (!"default".equalsIgnoreCase(soundName)) { @@ -300,10 +370,21 @@ public void sendToNotificationCentre(Bundle bundle) { soundUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + resId); } + } else { + soundName = "default"; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher + channel_id = channel_id + "-" + soundName; } + notification.setSound(soundUri); } + if (soundUri == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + notification.setSound(null); + } + if (bundle.containsKey("ongoing") || bundle.getBoolean("ongoing")) { notification.setOngoing(bundle.getBoolean("ongoing")); } @@ -326,17 +407,26 @@ public void sendToNotificationCentre(Bundle bundle) { PendingIntent.FLAG_UPDATE_CURRENT); NotificationManager notificationManager = notificationManager(); - checkOrCreateChannel(notificationManager); - notification.setContentIntent(pendingIntent); + long[] vibratePattern = new long[]{0}; if (!bundle.containsKey("vibrate") || bundle.getBoolean("vibrate")) { long vibration = bundle.containsKey("vibration") ? (long) bundle.getDouble("vibration") : DEFAULT_VIBRATION; if (vibration == 0) vibration = DEFAULT_VIBRATION; - notification.setVibrate(new long[]{0, vibration}); + + channel_id = channel_id + "-" + vibration; + + vibratePattern = new long[]{0, vibration}; + + notification.setVibrate(vibratePattern); } + checkOrCreateChannel(notificationManager, channel_id, soundUri, importance, vibratePattern); + + notification.setChannelId(channel_id); + notification.setContentIntent(pendingIntent); + JSONArray actionsArray = null; try { actionsArray = bundle.getString("actions") != null ? new JSONArray(bundle.getString("actions")) : null; @@ -360,11 +450,12 @@ public void sendToNotificationCentre(Bundle bundle) { Intent actionIntent = new Intent(context, intentClass); actionIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - actionIntent.setAction(context.getPackageName() + "." + action); + actionIntent.setAction(packageName + "." + action); // Add "action" for later identifying which button gets pressed. bundle.putString("action", action); actionIntent.putExtra("notification", bundle); + actionIntent.setPackage(packageName); PendingIntent pendingActionIntent = PendingIntent.getActivity(context, notificationID, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT); @@ -386,14 +477,16 @@ public void sendToNotificationCentre(Bundle bundle) { commit(editor); } - Notification info = notification.build(); - info.defaults |= Notification.DEFAULT_LIGHTS; - - if (bundle.containsKey("tag")) { - String tag = bundle.getString("tag"); - notificationManager.notify(tag, notificationID, info); - } else { - notificationManager.notify(notificationID, info); + if (!(this.isApplicationInForeground(context) && bundle.getBoolean("ignoreInForeground"))) { + Notification info = notification.build(); + info.defaults |= Notification.DEFAULT_LIGHTS; + + if (bundle.containsKey("tag")) { + String tag = bundle.getString("tag"); + notificationManager.notify(tag, notificationID, info); + } else { + notificationManager.notify(notificationID, info); + } } // Can't use setRepeating for recurring notifications because setRepeating @@ -491,6 +584,40 @@ public void clearNotification(int notificationID) { notificationManager.cancel(notificationID); } + public void clearDeliveredNotifications(ReadableArray identifiers) { + NotificationManager notificationManager = notificationManager(); + for (int index = 0; index < identifiers.size(); index++) { + String id = identifiers.getString(index); + Log.i(LOG_TAG, "Removing notification with id " + id); + notificationManager.cancel(Integer.parseInt(id)); + } + } + + public WritableArray getDeliveredNotifications() { + NotificationManager notificationManager = notificationManager(); + StatusBarNotification delivered[] = notificationManager.getActiveNotifications(); + Log.i(LOG_TAG, "Found " + delivered.length + " delivered notifications"); + WritableArray result = Arguments.createArray(); + /* + * stay consistent to the return structure in + * https://facebook.github.io/react-native/docs/pushnotificationios.html#getdeliverednotifications + * but there is no such thing as a 'userInfo' + */ + for (StatusBarNotification notification : delivered) { + Notification original = notification.getNotification(); + Bundle extras = original.extras; + WritableMap notif = Arguments.createMap(); + notif.putString("identifier", "" + notification.getId()); + notif.putString("title", extras.getString(Notification.EXTRA_TITLE)); + notif.putString("body", extras.getString(Notification.EXTRA_TEXT)); + notif.putString("tag", notification.getTag()); + notif.putString("group", original.getGroup()); + result.pushMap(notif); + } + + return result; + + } public void cancelAllScheduledNotifications() { Log.i(LOG_TAG, "Cancelling all notifications"); @@ -521,7 +648,11 @@ private void cancelScheduledNotification(String notificationIDString) { // remove it from the alarm manger schedule Bundle b = new Bundle(); b.putString("id", notificationIDString); - getAlarmManager().cancel(toScheduleNotificationIntent(b)); + PendingIntent pendingIntent = toScheduleNotificationIntent(b); + + if(pendingIntent != null) { + getAlarmManager().cancel(pendingIntent); + } if (scheduledNotificationsPersistence.contains(notificationIDString)) { // remove it from local storage @@ -535,7 +666,11 @@ private void cancelScheduledNotification(String notificationIDString) { // removed it from the notification center NotificationManager notificationManager = notificationManager(); - notificationManager.cancel(Integer.parseInt(notificationIDString)); + try { + notificationManager.cancel(Integer.parseInt(notificationIDString)); + } catch (Exception e) { + Log.e(LOG_TAG, "Unable to parse Notification ID " + notificationIDString, e); + } } private NotificationManager notificationManager() { @@ -550,55 +685,65 @@ private static void commit(SharedPreferences.Editor editor) { } } - private static boolean channelCreated = false; - private void checkOrCreateChannel(NotificationManager manager) { + public void checkOrCreateDefaultChannel() { + NotificationManager manager = notificationManager(); + + int importance = NotificationManager.IMPORTANCE_HIGH; + Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); + + // Instanciate a default channel with default sound. + String channel_id_sound = NOTIFICATION_CHANNEL_ID + "-default-" + importance + "-" + DEFAULT_VIBRATION; + checkOrCreateChannel(manager, channel_id_sound, soundUri, importance, new long[] {0, DEFAULT_VIBRATION}); + + // Instanciate a default channel without sound defined for backward compatibility. + String channel_id_no_sound = NOTIFICATION_CHANNEL_ID + "-" + importance + "-" + DEFAULT_VIBRATION; + checkOrCreateChannel(manager, channel_id_no_sound, null, importance, new long[] {0, DEFAULT_VIBRATION}); + } + + private void checkOrCreateChannel(NotificationManager manager, String channel_id, Uri soundUri, int importance, long[] vibratePattern) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return; - if (channelCreated) - return; if (manager == null) return; - Bundle bundle = new Bundle(); + NotificationChannel channel = manager.getNotificationChannel(channel_id); - int importance = NotificationManager.IMPORTANCE_HIGH; - final String importanceString = bundle.getString("importance"); + if (channel == null) { + channel = new NotificationChannel(channel_id, this.config.getChannelName() != null ? this.config.getChannelName() : "rn-push-notification-channel", importance); - if (importanceString != null) { - switch(importanceString.toLowerCase()) { - case "default": - importance = NotificationManager.IMPORTANCE_DEFAULT; - break; - case "max": - importance = NotificationManager.IMPORTANCE_MAX; - break; - case "high": - importance = NotificationManager.IMPORTANCE_HIGH; - break; - case "low": - importance = NotificationManager.IMPORTANCE_LOW; - break; - case "min": - importance = NotificationManager.IMPORTANCE_MIN; - break; - case "none": - importance = NotificationManager.IMPORTANCE_NONE; - break; - case "unspecified": - importance = NotificationManager.IMPORTANCE_UNSPECIFIED; - break; - default: - importance = NotificationManager.IMPORTANCE_HIGH; - } - } + channel.setDescription(this.config.getChannelDescription()); + channel.enableLights(true); + channel.enableVibration(true); + channel.setVibrationPattern(vibratePattern); - NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, this.config.getChannelName() != null ? this.config.getChannelName() : "rn-push-notification-channel", importance); + if (soundUri != null) { + AudioAttributes audioAttributes = new AudioAttributes.Builder() + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .setUsage(AudioAttributes.USAGE_NOTIFICATION) + .build(); - channel.setDescription(this.config.getChannelDescription()); - channel.enableLights(true); - channel.enableVibration(true); + channel.setSound(soundUri, audioAttributes); + } else { + channel.setSound(null, null); + } - manager.createNotificationChannel(channel); - channelCreated = true; + manager.createNotificationChannel(channel); + } } + + private boolean isApplicationInForeground(Context context) { + ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + List processInfos = activityManager.getRunningAppProcesses(); + if (processInfos != null) { + for (RunningAppProcessInfo processInfo : processInfos) { + if (processInfo.processName.equals(context.getPackageName()) + && processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND + && processInfo.pkgList.length > 0) { + return true; + } + } + } + return false; + } + } diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerService.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerService.java index 36a1c5c3c..df0c52d02 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerService.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerService.java @@ -1,91 +1,31 @@ package com.dieam.reactnativepushnotification.modules; -import java.util.Map; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.app.Application; -import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.Log; -import com.dieam.reactnativepushnotification.helpers.ApplicationBadgeHelper; +import com.dieam.reactnativepushnotification.modules.RNReceivedMessageHandler; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; +import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; - -import org.json.JSONObject; - -import java.util.List; -import java.util.Random; +import com.facebook.react.bridge.WritableMap; import static com.dieam.reactnativepushnotification.modules.RNPushNotification.LOG_TAG; public class RNPushNotificationListenerService extends FirebaseMessagingService { - @Override - public void onMessageReceived(RemoteMessage message) { - String from = message.getFrom(); - RemoteMessage.Notification remoteNotification = message.getNotification(); - - final Bundle bundle = new Bundle(); - // Putting it from remoteNotification first so it can be overriden if message - // data has it - if (remoteNotification != null) { - // ^ It's null when message is from GCM - bundle.putString("title", remoteNotification.getTitle()); - bundle.putString("message", remoteNotification.getBody()); - } - - for(Map.Entry entry : message.getData().entrySet()) { - bundle.putString(entry.getKey(), entry.getValue()); - } - - /// [HSM-MINH] - make this compatible with IOS's push - // JSONObject data = getPushData(bundle.getString("data")); - JSONObject data = getPushData(bundle.getString("payload")); - // ...end - - // Copy `twi_body` to `message` to support Twilio - if (bundle.containsKey("twi_body")) { - bundle.putString("message", bundle.getString("twi_body")); - } - - /// [HSM-MINH] - make this compatible with IOS's push - // if (data != null) { - if (data != null && data.has("message")) { - if (!bundle.containsKey("message")) { - // bundle.putString("message", data.optString("alert", null)); - bundle.putString("message", data.optString("message", null)); - } - // if (!bundle.containsKey("title")) { - // bundle.putString("title", data.optString("title", null)); - // } - bundle.putString("title", "Daybreak"); - // ...end - - if (!bundle.containsKey("sound")) { - bundle.putString("soundName", data.optString("sound", null)); - } - if (!bundle.containsKey("color")) { - bundle.putString("color", data.optString("color", null)); - } - - final int badge = data.optInt("badge", -1); - if (badge >= 0) { - ApplicationBadgeHelper.INSTANCE.setApplicationIconBadgeNumber(this, badge); - } - } + private RNReceivedMessageHandler mMessageReceivedHandler = new RNReceivedMessageHandler(this); - Log.v(LOG_TAG, "onMessageReceived: " + bundle); + @Override + public void onNewToken(String token) { + final String deviceToken = token; + Log.d(LOG_TAG, "Refreshed token: " + deviceToken); - // We need to run this on the main thread, as the React code assumes that is true. - // Namely, DevServerHelper constructs a Handler() without a Looper, which triggers: - // "Can't create handler inside thread that has not called Looper.prepare()" Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { public void run() { @@ -94,12 +34,12 @@ public void run() { ReactContext context = mReactInstanceManager.getCurrentReactContext(); // If it's constructed, send a notification if (context != null) { - handleRemotePushNotification((ReactApplicationContext) context, bundle); + handleNewToken((ReactApplicationContext) context, deviceToken); } else { // Otherwise wait for construction, then send the notification mReactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() { public void onReactContextInitialized(ReactContext context) { - handleRemotePushNotification((ReactApplicationContext) context, bundle); + handleNewToken((ReactApplicationContext) context, deviceToken); } }); if (!mReactInstanceManager.hasStartedCreatingInitialContext()) { @@ -111,55 +51,16 @@ public void onReactContextInitialized(ReactContext context) { }); } - private JSONObject getPushData(String dataString) { - try { - return new JSONObject(dataString); - } catch (Exception e) { - return null; - } - } - - private void handleRemotePushNotification(ReactApplicationContext context, Bundle bundle) { - - // If notification ID is not provided by the user for push notification, generate one at random - if (bundle.getString("id") == null) { - Random randomNumberGenerator = new Random(System.currentTimeMillis()); - bundle.putString("id", String.valueOf(randomNumberGenerator.nextInt())); - } - - Boolean isForeground = isApplicationInForeground(); - + private void handleNewToken(ReactApplicationContext context, String token) { RNPushNotificationJsDelivery jsDelivery = new RNPushNotificationJsDelivery(context); - bundle.putBoolean("foreground", isForeground); - bundle.putBoolean("userInteraction", false); - jsDelivery.notifyNotification(bundle); - - // If contentAvailable is set to true, then send out a remote fetch event - if (bundle.getString("contentAvailable", "false").equalsIgnoreCase("true")) { - jsDelivery.notifyRemoteFetch(bundle); - } - Log.v(LOG_TAG, "sendNotification: " + bundle); - - Application applicationContext = (Application) context.getApplicationContext(); - RNPushNotificationHelper pushNotificationHelper = new RNPushNotificationHelper(applicationContext); - pushNotificationHelper.sendToNotificationCentre(bundle); + WritableMap params = Arguments.createMap(); + params.putString("deviceToken", token); + jsDelivery.sendEvent("remoteNotificationsRegistered", params); } - private boolean isApplicationInForeground() { - ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); - List processInfos = activityManager.getRunningAppProcesses(); - if (processInfos != null) { - for (RunningAppProcessInfo processInfo : processInfos) { - if (processInfo.processName.equals(getApplication().getPackageName())) { - if (processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { - for (String d : processInfo.pkgList) { - return true; - } - } - } - } - } - return false; + @Override + public void onMessageReceived(RemoteMessage message) { + mMessageReceivedHandler.handleReceivedMessage(message); } } diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationRegistrationService.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationRegistrationService.java index b962f5438..633ed9c8e 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationRegistrationService.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationRegistrationService.java @@ -4,35 +4,19 @@ import android.content.Intent; import android.util.Log; -import com.google.android.gms.gcm.GoogleCloudMessaging; -import com.google.android.gms.iid.InstanceID; - import static com.dieam.reactnativepushnotification.modules.RNPushNotification.LOG_TAG; public class RNPushNotificationRegistrationService extends IntentService { + private static final String TAG = "RNPushNotification"; - private static final String TAG = "RNPushNotification"; - - public RNPushNotificationRegistrationService() { - super(TAG); - } + public RNPushNotificationRegistrationService() { + super(TAG); - @Override - protected void onHandleIntent(Intent intent) { - try { - String SenderID = intent.getStringExtra("senderID"); - InstanceID instanceID = InstanceID.getInstance(this); - String token = instanceID.getToken(SenderID, - GoogleCloudMessaging.INSTANCE_ID_SCOPE, null); - sendRegistrationToken(token); - } catch (Exception e) { - Log.e(LOG_TAG, TAG + " failed to process intent " + intent, e); - } - } + Log.w(LOG_TAG, TAG + " RNPushNotificationRegistrationService is not needed anymore."); + } - private void sendRegistrationToken(String token) { - Intent intent = new Intent(this.getPackageName() + ".RNPushNotificationRegisteredToken"); - intent.putExtra("token", token); - sendBroadcast(intent); - } + @Override + protected void onHandleIntent(Intent intent) { + Log.w(LOG_TAG, TAG + " RNPushNotificationRegistrationService is not needed anymore."); + } } diff --git a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerServiceGcm.java b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNReceivedMessageHandler.java similarity index 65% rename from android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerServiceGcm.java rename to android/src/main/java/com/dieam/reactnativepushnotification/modules/RNReceivedMessageHandler.java index 37bb0f45f..04038bc07 100644 --- a/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationListenerServiceGcm.java +++ b/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNReceivedMessageHandler.java @@ -1,5 +1,8 @@ package com.dieam.reactnativepushnotification.modules; +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; + import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.app.Application; @@ -7,30 +10,53 @@ import android.os.Handler; import android.os.Looper; import android.util.Log; +import androidx.annotation.NonNull; import com.dieam.reactnativepushnotification.helpers.ApplicationBadgeHelper; import com.facebook.react.ReactApplication; import com.facebook.react.ReactInstanceManager; +import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContext; -import com.google.android.gms.gcm.GcmListenerService; +import com.facebook.react.bridge.WritableMap; import org.json.JSONObject; +import java.util.Map; import java.util.List; import java.util.Random; +import static android.content.Context.ACTIVITY_SERVICE; import static com.dieam.reactnativepushnotification.modules.RNPushNotification.LOG_TAG; -public class RNPushNotificationListenerServiceGcm extends GcmListenerService { +public class RNReceivedMessageHandler { + private FirebaseMessagingService mFirebaseMessagingService; + + public RNReceivedMessageHandler(@NonNull FirebaseMessagingService service) { + this.mFirebaseMessagingService = service; + } + + public void handleReceivedMessage(RemoteMessage message) { + String from = message.getFrom(); + RemoteMessage.Notification remoteNotification = message.getNotification(); + final Bundle bundle = new Bundle(); + // Putting it from remoteNotification first so it can be overriden if message + // data has it + if (remoteNotification != null) { + // ^ It's null when message is from GCM + bundle.putString("title", remoteNotification.getTitle()); + bundle.putString("message", remoteNotification.getBody()); + bundle.putString("sound", remoteNotification.getSound()); + bundle.putString("color", remoteNotification.getColor()); + } + + Map notificationData = message.getData(); - @Override - public void onMessageReceived(String from, final Bundle bundle) { - JSONObject data = getPushData(bundle.getString("data")); // Copy `twi_body` to `message` to support Twilio - if (bundle.containsKey("twi_body")) { - bundle.putString("message", bundle.getString("twi_body")); + if (notificationData.containsKey("twi_body")) { + bundle.putString("message", notificationData.get("twi_body")); } + JSONObject data = getPushData(notificationData.get("data")); if (data != null) { if (!bundle.containsKey("message")) { @@ -48,10 +74,16 @@ public void onMessageReceived(String from, final Bundle bundle) { final int badge = data.optInt("badge", -1); if (badge >= 0) { - ApplicationBadgeHelper.INSTANCE.setApplicationIconBadgeNumber(this, badge); + ApplicationBadgeHelper.INSTANCE.setApplicationIconBadgeNumber(mFirebaseMessagingService, badge); } } + Bundle dataBundle = new Bundle(); + for(Map.Entry entry : notificationData.entrySet()) { + dataBundle.putString(entry.getKey(), entry.getValue()); + } + bundle.putParcelable("data", dataBundle); + Log.v(LOG_TAG, "onMessageReceived: " + bundle); // We need to run this on the main thread, as the React code assumes that is true. @@ -61,9 +93,9 @@ public void onMessageReceived(String from, final Bundle bundle) { handler.post(new Runnable() { public void run() { // Construct and load our normal React JS code bundle - ReactInstanceManager mReactInstanceManager = ((ReactApplication) getApplication()).getReactNativeHost().getReactInstanceManager(); + ReactInstanceManager mReactInstanceManager = ((ReactApplication) mFirebaseMessagingService.getApplication()).getReactNativeHost().getReactInstanceManager(); ReactContext context = mReactInstanceManager.getCurrentReactContext(); - // If it's constructed, send a notification + // If it's constructed, send a notificationre if (context != null) { handleRemotePushNotification((ReactApplicationContext) context, bundle); } else { @@ -98,6 +130,8 @@ private void handleRemotePushNotification(ReactApplicationContext context, Bundl bundle.putString("id", String.valueOf(randomNumberGenerator.nextInt())); } + RNPushNotificationConfig config = new RNPushNotificationConfig(mFirebaseMessagingService.getApplication()); + Boolean isForeground = isApplicationInForeground(); RNPushNotificationJsDelivery jsDelivery = new RNPushNotificationJsDelivery(context); @@ -112,7 +146,7 @@ private void handleRemotePushNotification(ReactApplicationContext context, Bundl Log.v(LOG_TAG, "sendNotification: " + bundle); - if (!isForeground) { + if (config.getNotificationForeground() || !isForeground) { Application applicationContext = (Application) context.getApplicationContext(); RNPushNotificationHelper pushNotificationHelper = new RNPushNotificationHelper(applicationContext); pushNotificationHelper.sendToNotificationCentre(bundle); @@ -120,19 +154,18 @@ private void handleRemotePushNotification(ReactApplicationContext context, Bundl } private boolean isApplicationInForeground() { - ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); + ActivityManager activityManager = (ActivityManager) mFirebaseMessagingService.getSystemService(ACTIVITY_SERVICE); List processInfos = activityManager.getRunningAppProcesses(); if (processInfos != null) { for (RunningAppProcessInfo processInfo : processInfos) { - if (processInfo.processName.equals(getApplication().getPackageName())) { - if (processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { - for (String d : processInfo.pkgList) { - return true; - } - } + if (processInfo.processName.equals(mFirebaseMessagingService.getPackageName()) + && processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND + && processInfo.pkgList.length > 0) { + return true; } } } return false; } + } diff --git a/component/index.android.js b/component/index.android.js index d3d2758fc..13a442ead 100644 --- a/component/index.android.js +++ b/component/index.android.js @@ -26,19 +26,19 @@ NotificationsComponent.prototype.getInitialNotification = function () { }); }; -NotificationsComponent.prototype.requestPermissions = function(senderID: string) { - RNPushNotification.requestPermissions(senderID); +NotificationsComponent.prototype.requestPermissions = function() { + RNPushNotification.requestPermissions(); }; -NotificationsComponent.prototype.subscribeToTopic = function(topic: string) { +NotificationsComponent.prototype.subscribeToTopic = function(topic) { RNPushNotification.subscribeToTopic(topic); }; -NotificationsComponent.prototype.cancelLocalNotifications = function(details: Object) { +NotificationsComponent.prototype.cancelLocalNotifications = function(details) { RNPushNotification.cancelLocalNotifications(details); }; -NotificationsComponent.prototype.clearLocalNotification = function(details: Object) { +NotificationsComponent.prototype.clearLocalNotification = function(details) { RNPushNotification.clearLocalNotification(details); }; @@ -46,37 +46,35 @@ NotificationsComponent.prototype.cancelAllLocalNotifications = function() { RNPushNotification.cancelAllLocalNotifications(); }; -NotificationsComponent.prototype.presentLocalNotification = function(details: Object) { +NotificationsComponent.prototype.presentLocalNotification = function(details) { RNPushNotification.presentLocalNotification(details); }; -NotificationsComponent.prototype.scheduleLocalNotification = function(details: Object) { +NotificationsComponent.prototype.scheduleLocalNotification = function(details) { RNPushNotification.scheduleLocalNotification(details); }; -NotificationsComponent.prototype.setApplicationIconBadgeNumber = function(number: number) { +NotificationsComponent.prototype.setApplicationIconBadgeNumber = function(number) { if (!RNPushNotification.setApplicationIconBadgeNumber) { return; } RNPushNotification.setApplicationIconBadgeNumber(number); }; -NotificationsComponent.prototype.abandonPermissions = function() { - /* Void */ -}; - -NotificationsComponent.prototype.checkPermissions = function(callback: Function) { +NotificationsComponent.prototype.checkPermissions = function(callback) { RNPushNotification.checkPermissions().then(alert => callback({ alert })); }; -NotificationsComponent.prototype.addEventListener = function(type: string, handler: Function) { +NotificationsComponent.prototype.addEventListener = function(type, handler) { var listener; if (type === 'notification') { listener = DeviceEventEmitter.addListener( DEVICE_NOTIF_EVENT, function(notifData) { - var data = JSON.parse(notifData.dataJSON); - handler(data); + if (notifData && notifData.dataJSON) { + var data = JSON.parse(notifData.dataJSON); + handler(data); + } } ); } else if (type === 'register') { @@ -90,8 +88,10 @@ NotificationsComponent.prototype.addEventListener = function(type: string, handl listener = DeviceEventEmitter.addListener( REMOTE_FETCH_EVENT, function(notifData) { - var notificationData = JSON.parse(notifData.dataJSON) - handler(notificationData); + if (notifData && notifData.dataJSON) { + var notificationData = JSON.parse(notifData.dataJSON) + handler(notificationData); + } } ); } @@ -99,7 +99,7 @@ NotificationsComponent.prototype.addEventListener = function(type: string, handl _notifHandlers.set(type, listener); }; -NotificationsComponent.prototype.removeEventListener = function(type: string, handler: Function) { +NotificationsComponent.prototype.removeEventListener = function(type, handler) { var listener = _notifHandlers.get(type); if (!listener) { return; @@ -108,7 +108,7 @@ NotificationsComponent.prototype.removeEventListener = function(type: string, ha _notifHandlers.delete(type); } -NotificationsComponent.prototype.registerNotificationActions = function(details: Object) { +NotificationsComponent.prototype.registerNotificationActions = function(details) { RNPushNotification.registerNotificationActions(details); } @@ -116,6 +116,21 @@ NotificationsComponent.prototype.clearAllNotifications = function() { RNPushNotification.clearAllNotifications() } +NotificationsComponent.prototype.removeAllDeliveredNotifications = function() { + RNPushNotification.removeAllDeliveredNotifications(); +} + +NotificationsComponent.prototype.getDeliveredNotifications = function(callback) { + RNPushNotification.getDeliveredNotifications(callback); +} +NotificationsComponent.prototype.removeDeliveredNotifications = function(identifiers) { + RNPushNotification.removeDeliveredNotifications(identifiers); +} + +NotificationsComponent.prototype.abandonPermissions = function() { + RNPushNotification.abandonPermissions(); +} + module.exports = { state: false, component: new NotificationsComponent() diff --git a/component/index.ios.js b/component/index.ios.js index 38d2449ae..400214be0 100644 --- a/component/index.ios.js +++ b/component/index.ios.js @@ -1,12 +1,9 @@ -'use strict'; +"use strict"; -import { - AppState, - PushNotificationIOS -} from 'react-native'; +import { AppState } from "react-native"; +import PushNotificationIOS from "@react-native-community/push-notification-ios"; module.exports = { state: AppState, component: PushNotificationIOS }; - diff --git a/example/.babelrc b/example/.babelrc deleted file mode 100644 index 108657ce5..000000000 --- a/example/.babelrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "retainLines": true, - "compact": true, - "comments": false, - "presets": [ - "react-native" - ], - "sourceMaps": false -} \ No newline at end of file diff --git a/example/.eslintrc.js b/example/.eslintrc.js new file mode 100644 index 000000000..40c6dcd05 --- /dev/null +++ b/example/.eslintrc.js @@ -0,0 +1,4 @@ +module.exports = { + root: true, + extends: '@react-native-community', +}; diff --git a/example/.flowconfig b/example/.flowconfig index 3c0adb566..786366c4f 100644 --- a/example/.flowconfig +++ b/example/.flowconfig @@ -5,63 +5,70 @@ ; Ignore "BUCK" generated dirs /\.buckd/ -; Ignore unexpected extra "@providesModule" -.*/node_modules/.*/node_modules/fbjs/.* +; Ignore polyfills +node_modules/react-native/Libraries/polyfills/.* -; Ignore duplicate module providers -; For RN Apps installed via npm, "Libraries" folder is inside -; "node_modules/react-native" but in the source repo it is in the root -.*/Libraries/react-native/React.js +; These should not be required directly +; require from fbjs/lib instead: require('fbjs/lib/warning') +node_modules/warning/.* -; Ignore polyfills -.*/Libraries/polyfills/.* +; Flow doesn't support platforms +.*/Libraries/Utilities/LoadingView.js -; Ignore metro -.*/node_modules/metro/.* +[untyped] +.*/node_modules/@react-native-community/cli/.*/.* [include] [libs] -node_modules/react-native/Libraries/react-native/react-native-interface.js +node_modules/react-native/interface.js node_modules/react-native/flow/ -node_modules/react-native/flow-github/ [options] emoji=true -module.system=haste -module.system.haste.use_name_reducers=true -# get basename -module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1' -# strip .js or .js.flow suffix -module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1' -# strip .ios suffix -module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1' -module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1' -module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1' -module.system.haste.paths.blacklist=.*/__tests__/.* -module.system.haste.paths.blacklist=.*/__mocks__/.* -module.system.haste.paths.blacklist=/node_modules/react-native/Libraries/Animated/src/polyfills/.* -module.system.haste.paths.whitelist=/node_modules/react-native/Libraries/.* - -munge_underscores=true - -module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' +esproposal.optional_chaining=enable +esproposal.nullish_coalescing=enable module.file_ext=.js -module.file_ext=.jsx module.file_ext=.json -module.file_ext=.native.js +module.file_ext=.ios.js + +munge_underscores=true + +module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' +module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub' suppress_type=$FlowIssue suppress_type=$FlowFixMe suppress_type=$FlowFixMeProps suppress_type=$FlowFixMeState -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) -suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ -suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) +suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError +[lints] +sketchy-null-number=warn +sketchy-null-mixed=warn +sketchy-number=warn +untyped-type-import=warn +nonstrict-import=warn +deprecated-type=warn +unsafe-getters-setters=warn +inexact-spread=warn +unnecessary-invariant=warn +signature-verification-failure=warn +deprecated-utility=error + +[strict] +deprecated-type +nonstrict-import +sketchy-null +unclear-type +unsafe-getters-setters +untyped-import +untyped-type-import + [version] -^0.75.0 +^0.113.0 diff --git a/example/.gitignore b/example/.gitignore index 5d647565f..ad572e632 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -20,7 +20,6 @@ DerivedData *.hmap *.ipa *.xcuserstate -project.xcworkspace # Android/IntelliJ # @@ -40,6 +39,7 @@ yarn-error.log buck-out/ \.buckd/ *.keystore +!debug.keystore # fastlane # @@ -54,3 +54,6 @@ buck-out/ # Bundle artifact *.jsbundle + +# CocoaPods +/ios/Pods/ diff --git a/example/.prettierrc.js b/example/.prettierrc.js new file mode 100644 index 000000000..5c4de1a4f --- /dev/null +++ b/example/.prettierrc.js @@ -0,0 +1,6 @@ +module.exports = { + bracketSpacing: false, + jsxBracketSameLine: true, + singleQuote: true, + trailingComma: 'all', +}; diff --git a/example/App.js b/example/App.js index 75dc49998..05840d965 100644 --- a/example/App.js +++ b/example/App.js @@ -6,41 +6,109 @@ * @flow */ -import React, { Component } from 'react'; -import { TextInput, StyleSheet, Text, View, TouchableOpacity, Alert } from 'react-native'; +import React, {Component} from 'react'; +import { + TextInput, + StyleSheet, + Text, + View, + TouchableOpacity, + Alert, +} from 'react-native'; import NotifService from './NotifService'; -import appConfig from './app.json'; - -type Props = {}; -export default class App extends Component { +export default class App extends Component { constructor(props) { super(props); - this.state = { - senderId: appConfig.senderID - }; + this.state = {}; - this.notif = new NotifService(this.onRegister.bind(this), this.onNotif.bind(this)); + this.notif = new NotifService( + this.onRegister.bind(this), + this.onNotif.bind(this), + ); } render() { return ( - Example app react-native-push-notification + + Example app react-native-push-notification + - + - { this.notif.localNotif() }}>Local Notification (now) - { this.notif.scheduleNotif() }}>Schedule Notification in 30s - { this.notif.cancelNotif() }}>Cancel last notification (if any) - { this.notif.cancelAll() }}>Cancel all notifications - { this.notif.checkPermission(this.handlePerm.bind(this)) }}>Check Permission + { + this.notif.localNotif(); + }}> + Local Notification (now) + + { + this.notif.localNotif('sample.mp3'); + }}> + Local Notification with sound (now) + + { + this.notif.scheduleNotif(); + }}> + Schedule Notification in 30s + + { + this.notif.scheduleNotif('sample.mp3'); + }}> + Schedule Notification with sound in 30s + + { + this.notif.cancelNotif(); + }}> + Cancel last notification (if any) + + { + this.notif.cancelAll(); + }}> + Cancel all notifications + + { + this.notif.checkPermission(this.handlePerm.bind(this)); + }}> + Check Permission + + { + this.notif.requestPermissions(); + }}> + Request Permissions + + { + this.notif.abandonPermissions(); + }}> + Abandon Permissions + - {this.setState({ senderId: e })}} placeholder="GCM ID" /> - { this.notif.configure(this.onRegister.bind(this), this.onNotif.bind(this), this.state.senderId) }}>Configure Sender ID - {this.state.gcmRegistered && GCM Configured !} + + {this.state.fcmRegistered && FCM Configured !} @@ -48,22 +116,18 @@ export default class App extends Component { } onRegister(token) { - Alert.alert("Registered !", JSON.stringify(token)); - console.log(token); - this.setState({ registerToken: token.token, gcmRegistered: true }); + this.setState({registerToken: token.token, fcmRegistered: true}); } onNotif(notif) { - console.log(notif); Alert.alert(notif.title, notif.message); } handlePerm(perms) { - Alert.alert("Permissions", JSON.stringify(perms)); + Alert.alert('Permissions', JSON.stringify(perms)); } } - const styles = StyleSheet.create({ container: { flex: 1, @@ -78,26 +142,26 @@ const styles = StyleSheet.create({ }, button: { borderWidth: 1, - borderColor: "#000000", + borderColor: '#000000', margin: 5, padding: 5, - width: "70%", - backgroundColor: "#DDDDDD", + width: '70%', + backgroundColor: '#DDDDDD', borderRadius: 5, }, textField: { borderWidth: 1, - borderColor: "#AAAAAA", + borderColor: '#AAAAAA', margin: 5, padding: 5, - width: "70%" + width: '70%', }, spacer: { height: 10, }, title: { - fontWeight: "bold", + fontWeight: 'bold', fontSize: 20, - textAlign: "center", - } + textAlign: 'center', + }, }); diff --git a/example/NotifService.js b/example/NotifService.js index 086f59d80..de686b639 100644 --- a/example/NotifService.js +++ b/example/NotifService.js @@ -1,107 +1,85 @@ import PushNotification from 'react-native-push-notification'; +import NotificationHandler from './NotificationHandler'; export default class NotifService { - constructor(onRegister, onNotification) { - this.configure(onRegister, onNotification); - this.lastId = 0; - } - - configure(onRegister, onNotification, gcm = "") { - PushNotification.configure({ - // (optional) Called when Token is generated (iOS and Android) - onRegister: onRegister, //this._onRegister.bind(this), - - // (required) Called when a remote or local notification is opened or received - onNotification: onNotification, //this._onNotification, - - // ANDROID ONLY: GCM Sender ID (optional - not required for local notifications, but is need to receive remote push notifications) - senderID: gcm, - // IOS ONLY (optional): default: all - Permissions to register. - permissions: { - alert: true, - badge: true, - sound: true - }, + NotificationHandler.attachRegister(onRegister); + NotificationHandler.attachNotification(onNotification); - // Should the initial notification be popped automatically - // default: true - popInitialNotification: true, - - /** - * (optional) default: true - * - Specified if permissions (ios) and token (android and ios) will requested or not, - * - if not, you must call PushNotificationsHandler.requestPermissions() later - */ - requestPermissions: true, + // Clear badge number at start + PushNotification.getApplicationIconBadgeNumber(function(number) { + if(number > 0) { + PushNotification.setApplicationIconBadgeNumber(0); + } }); } - localNotif() { + localNotif(soundName) { this.lastId++; PushNotification.localNotification({ /* Android Only Properties */ - id: ''+this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID - ticker: "My Notification Ticker", // (optional) + id: this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID + ticker: 'My Notification Ticker', // (optional) autoCancel: true, // (optional) default: true - largeIcon: "ic_launcher", // (optional) default: "ic_launcher" - smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher" - bigText: "My big text that will be shown when notification is expanded", // (optional) default: "message" prop - subText: "This is a subText", // (optional) default: none - color: "red", // (optional) default: system default + largeIcon: 'ic_launcher', // (optional) default: "ic_launcher" + smallIcon: 'ic_notification', // (optional) default: "ic_notification" with fallback for "ic_launcher" + bigText: 'My big text that will be shown when notification is expanded', // (optional) default: "message" prop + subText: 'This is a subText', // (optional) default: none + color: 'red', // (optional) default: system default vibrate: true, // (optional) default: true vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000 tag: 'some_tag', // (optional) add tag to message - group: "group", // (optional) add group to message + group: 'group', // (optional) add group to message ongoing: false, // (optional) set whether this is an "ongoing" notification /* iOS only properties */ alertAction: 'view', // (optional) default: view - category: null, // (optional) default: null - userInfo: null, // (optional) default: null (object containing additional notification data) + category: '', // (optional) default: empty string + userInfo: {}, // (optional) default: {} (using null throws a JSON value '' error) /* iOS and Android properties */ - title: "Local Notification", // (optional) - message: "My Notification Message", // (required) - playSound: false, // (optional) default: true - soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) - number: '10', // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero) - actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more + title: 'Local Notification', // (optional) + message: 'My Notification Message', // (required) + playSound: !!soundName, // (optional) default: true + soundName: soundName ? soundName : 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) + number: 10, // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero) + actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more }); } - scheduleNotif() { + scheduleNotif(soundName) { this.lastId++; PushNotification.localNotificationSchedule({ - date: new Date(Date.now() + (30 * 1000)), // in 30 secs + date: new Date(Date.now() + 30 * 1000), // in 30 secs /* Android Only Properties */ - id: ''+this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID - ticker: "My Notification Ticker", // (optional) + id: this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID + ticker: 'My Notification Ticker', // (optional) autoCancel: true, // (optional) default: true - largeIcon: "ic_launcher", // (optional) default: "ic_launcher" - smallIcon: "ic_notification", // (optional) default: "ic_notification" with fallback for "ic_launcher" - bigText: "My big text that will be shown when notification is expanded", // (optional) default: "message" prop - subText: "This is a subText", // (optional) default: none - color: "blue", // (optional) default: system default + largeIcon: 'ic_launcher', // (optional) default: "ic_launcher" + smallIcon: 'ic_notification', // (optional) default: "ic_notification" with fallback for "ic_launcher" + bigText: 'My big text that will be shown when notification is expanded', // (optional) default: "message" prop + subText: 'This is a subText', // (optional) default: none + color: 'blue', // (optional) default: system default vibrate: true, // (optional) default: true vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000 tag: 'some_tag', // (optional) add tag to message - group: "group", // (optional) add group to message + group: 'group', // (optional) add group to message ongoing: false, // (optional) set whether this is an "ongoing" notification /* iOS only properties */ alertAction: 'view', // (optional) default: view - category: null, // (optional) default: null - userInfo: null, // (optional) default: null (object containing additional notification data) + category: '', // (optional) default: empty string + userInfo: {}, // (optional) default: {} (using null throws a JSON value '' error) /* iOS and Android properties */ - title: "Scheduled Notification", // (optional) - message: "My Notification Message", // (required) - playSound: true, // (optional) default: true - soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) + title: 'Scheduled Notification', // (optional) + message: 'My Notification Message', // (required) + playSound: !!soundName, // (optional) default: true + number: 10, // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero) + soundName: soundName ? soundName : 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played) }); } @@ -109,11 +87,19 @@ export default class NotifService { return PushNotification.checkPermissions(cbk); } + requestPermissions() { + return PushNotification.requestPermissions(); + } + cancelNotif() { - PushNotification.cancelLocalNotifications({id: ''+this.lastId}); + PushNotification.cancelLocalNotifications({id: '' + this.lastId}); } cancelAll() { PushNotification.cancelAllLocalNotifications(); } -} \ No newline at end of file + + abandonPermissions() { + PushNotification.abandonPermissions(); + } +} diff --git a/example/NotificationHandler.js b/example/NotificationHandler.js new file mode 100644 index 000000000..d21992416 --- /dev/null +++ b/example/NotificationHandler.js @@ -0,0 +1,57 @@ +import PushNotification from 'react-native-push-notification'; + +class NotificationHandler { + onNotification(notification) { + console.log('NotificationHandler:', notification); + + if (typeof this._onNotification === 'function') { + this._onNotification(notification); + } + } + + onRegister(token) { + console.log('NotificationHandler:', token); + + if (typeof this._onRegister === 'function') { + this._onRegister(token); + } + } + + attachRegister(handler) { + this._onRegister = handler; + } + + attachNotification(handler) { + this._onNotification = handler; + } +} + +const handler = new NotificationHandler(); + +PushNotification.configure({ + // (optional) Called when Token is generated (iOS and Android) + onRegister: handler.onRegister.bind(handler), + + // (required) Called when a remote or local notification is opened or received + onNotification: handler.onNotification.bind(handler), + + // IOS ONLY (optional): default: all - Permissions to register. + permissions: { + alert: true, + badge: true, + sound: true, + }, + + // Should the initial notification be popped automatically + // default: true + popInitialNotification: true, + + /** + * (optional) default: true + * - Specified if permissions (ios) and token (android and ios) will requested or not, + * - if not, you must call PushNotificationsHandler.requestPermissions() later + */ + requestPermissions: true, +}); + +export default handler; diff --git a/example/__tests__/App-test.js b/example/__tests__/App-test.js new file mode 100644 index 000000000..178476699 --- /dev/null +++ b/example/__tests__/App-test.js @@ -0,0 +1,14 @@ +/** + * @format + */ + +import 'react-native'; +import React from 'react'; +import App from '../App'; + +// Note: test renderer must be required after react-native. +import renderer from 'react-test-renderer'; + +it('renders correctly', () => { + renderer.create(); +}); diff --git a/example/android/.project b/example/android/.project new file mode 100644 index 000000000..0812d9e3f --- /dev/null +++ b/example/android/.project @@ -0,0 +1,17 @@ + + + example + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/example/android/.settings/org.eclipse.buildship.core.prefs b/example/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000..342e81ef5 --- /dev/null +++ b/example/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments= +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/example/android/app/.classpath b/example/android/app/.classpath new file mode 100644 index 000000000..eb19361b5 --- /dev/null +++ b/example/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/example/android/app/.project b/example/android/app/.project new file mode 100644 index 000000000..ac485d7c3 --- /dev/null +++ b/example/android/app/.project @@ -0,0 +1,23 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/example/android/app/.settings/org.eclipse.buildship.core.prefs b/example/android/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000..b1886adb4 --- /dev/null +++ b/example/android/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/example/android/app/BUCK b/example/android/app/BUCK index c8f560323..a4cb8a5b0 100644 --- a/example/android/app/BUCK +++ b/example/android/app/BUCK @@ -8,23 +8,13 @@ # - `buck install -r android/app` - compile, install and run application # +load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") + lib_deps = [] -for jarfile in glob(['libs/*.jar']): - name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')] - lib_deps.append(':' + name) - prebuilt_jar( - name = name, - binary_jar = jarfile, - ) +create_aar_targets(glob(["libs/*.aar"])) -for aarfile in glob(['libs/*.aar']): - name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')] - lib_deps.append(':' + name) - android_prebuilt_aar( - name = name, - aar = aarfile, - ) +create_jar_targets(glob(["libs/*.jar"])) android_library( name = "all-libs", diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 90e7199c1..3d2337f29 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -15,9 +15,14 @@ import com.android.build.OutputFile * // the name of the generated asset file containing your JS bundle * bundleAssetName: "index.android.bundle", * - * // the entry file for bundle generation + * // the entry file for bundle generation. If none specified and + * // "index.android.js" exists, it will be used. Otherwise "index.js" is + * // default. Can be overridden with ENTRY_FILE environment variable. * entryFile: "index.android.js", * + * // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format + * bundleCommand: "ram-bundle", + * * // whether to bundle JS and assets in debug mode * bundleInDebug: false, * @@ -73,7 +78,7 @@ import com.android.build.OutputFile */ project.ext.react = [ - entryFile: "index.js" + enableHermes: false, // clean and rebuild if changing ] apply from: "../../node_modules/react-native/react.gradle" @@ -93,9 +98,35 @@ def enableSeparateBuildPerCPUArchitecture = false */ def enableProguardInReleaseBuilds = false +/** + * The preferred build flavor of JavaScriptCore. + * + * For example, to use the international variant, you can use: + * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` + * + * The international variant includes ICU i18n library and necessary data + * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that + * give correct results when using with locales other than en-US. Note that + * this variant is about 6MiB larger per architecture than default. + */ +def jscFlavor = 'org.webkit:android-jsc:+' + +/** + * Whether to enable the Hermes VM. + * + * This should be set on project.ext.react and mirrored here. If it is not set + * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode + * and the benefits of using Hermes will therefore be sharply reduced. + */ +def enableHermes = project.ext.react.get("enableHermes", false); + android { compileSdkVersion rootProject.ext.compileSdkVersion - buildToolsVersion rootProject.ext.buildToolsVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } defaultConfig { applicationId "com.example" @@ -103,49 +134,94 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 versionName "1.0" - ndk { - abiFilters "armeabi-v7a", "x86" - } } splits { abi { reset() enable enableSeparateBuildPerCPUArchitecture universalApk false // If true, also generate a universal APK - include "armeabi-v7a", "x86" + include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" + } + } + signingConfigs { + debug { + storeFile file('debug.keystore') + storePassword 'android' + keyAlias 'androiddebugkey' + keyPassword 'android' } } buildTypes { + debug { + signingConfig signingConfigs.debug + } release { + // Caution! In production, you need to generate your own keystore file. + // see https://facebook.github.io/react-native/docs/signed-apk-android. + signingConfig signingConfigs.debug minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } } + + packagingOptions { + pickFirst "lib/armeabi-v7a/libc++_shared.so" + pickFirst "lib/arm64-v8a/libc++_shared.so" + pickFirst "lib/x86/libc++_shared.so" + pickFirst "lib/x86_64/libc++_shared.so" + } + // applicationVariants are e.g. debug, release applicationVariants.all { variant -> variant.outputs.each { output -> // For each separate APK per architecture, set a unique version code as described here: - // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits - def versionCodes = ["armeabi-v7a":1, "x86":2] + // https://developer.android.com/studio/build/configure-apk-splits.html + def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] def abi = output.getFilter(OutputFile.ABI) if (abi != null) { // null for the universal-debug, universal-release variants output.versionCodeOverride = versionCodes.get(abi) * 1048576 + defaultConfig.versionCode } + } } } dependencies { - compile project(':react-native-push-notification') - compile fileTree(dir: "libs", include: ["*.jar"]) - compile "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}" - compile "com.facebook.react:react-native:+" // From node_modules + implementation fileTree(dir: "libs", include: ["*.jar"]) + //noinspection GradleDynamicVersion + implementation "com.facebook.react:react-native:+" // From node_modules + + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" + + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { + exclude group:'com.facebook.fbjni' + } + + debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { + exclude group:'com.facebook.flipper' + } + + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { + exclude group:'com.facebook.flipper' + } + + if (enableHermes) { + def hermesPath = "../../node_modules/hermes-engine/android/"; + debugImplementation files(hermesPath + "hermes-debug.aar") + releaseImplementation files(hermesPath + "hermes-release.aar") + } else { + implementation jscFlavor + } } +apply plugin: 'com.google.gms.google-services' + // Run this once to be able to run the application with BUCK // puts all compile dependencies into folder libs for BUCK to use task copyDownloadableDepsToLibs(type: Copy) { from configurations.compile into 'libs' } + +apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) diff --git a/example/android/app/build_defs.bzl b/example/android/app/build_defs.bzl new file mode 100644 index 000000000..fff270f8d --- /dev/null +++ b/example/android/app/build_defs.bzl @@ -0,0 +1,19 @@ +"""Helper definitions to glob .aar and .jar targets""" + +def create_aar_targets(aarfiles): + for aarfile in aarfiles: + name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] + lib_deps.append(":" + name) + android_prebuilt_aar( + name = name, + aar = aarfile, + ) + +def create_jar_targets(jarfiles): + for jarfile in jarfiles: + name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] + lib_deps.append(":" + name) + prebuilt_jar( + name = name, + binary_jar = jarfile, + ) diff --git a/example/android/app/debug.keystore b/example/android/app/debug.keystore new file mode 100644 index 000000000..364e105ed Binary files /dev/null and b/example/android/app/debug.keystore differ diff --git a/example/android/app/proguard-rules.pro b/example/android/app/proguard-rules.pro index a92fa177e..11b025724 100644 --- a/example/android/app/proguard-rules.pro +++ b/example/android/app/proguard-rules.pro @@ -8,10 +8,3 @@ # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/example/android/app/src/debug/AndroidManifest.xml b/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000..fa26aa56e --- /dev/null +++ b/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/example/android/app/src/debug/java/com/example/ReactNativeFlipper.java b/example/android/app/src/debug/java/com/example/ReactNativeFlipper.java new file mode 100644 index 000000000..a1b70b8aa --- /dev/null +++ b/example/android/app/src/debug/java/com/example/ReactNativeFlipper.java @@ -0,0 +1,72 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + *

This source code is licensed under the MIT license found in the LICENSE file in the root + * directory of this source tree. + */ +package com.example; + +import android.content.Context; +import com.facebook.flipper.android.AndroidFlipperClient; +import com.facebook.flipper.android.utils.FlipperUtils; +import com.facebook.flipper.core.FlipperClient; +import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin; +import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin; +import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin; +import com.facebook.flipper.plugins.inspector.DescriptorMapping; +import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin; +import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; +import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; +import com.facebook.flipper.plugins.react.ReactFlipperPlugin; +import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.modules.network.NetworkingModule; +import okhttp3.OkHttpClient; + +public class ReactNativeFlipper { + public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) { + if (FlipperUtils.shouldEnableFlipper(context)) { + final FlipperClient client = AndroidFlipperClient.getInstance(context); + + client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults())); + client.addPlugin(new ReactFlipperPlugin()); + client.addPlugin(new DatabasesFlipperPlugin(context)); + client.addPlugin(new SharedPreferencesFlipperPlugin(context)); + client.addPlugin(CrashReporterPlugin.getInstance()); + + NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin(); + NetworkingModule.setCustomClientBuilder( + new NetworkingModule.CustomClientBuilder() { + @Override + public void apply(OkHttpClient.Builder builder) { + builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin)); + } + }); + client.addPlugin(networkFlipperPlugin); + client.start(); + + // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized + // Hence we run if after all native modules have been initialized + ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); + if (reactContext == null) { + reactInstanceManager.addReactInstanceEventListener( + new ReactInstanceManager.ReactInstanceEventListener() { + @Override + public void onReactContextInitialized(ReactContext reactContext) { + reactInstanceManager.removeReactInstanceEventListener(this); + reactContext.runOnNativeModulesQueueThread( + new Runnable() { + @Override + public void run() { + client.addPlugin(new FrescoFlipperPlugin()); + } + }); + } + }); + } else { + client.addPlugin(new FrescoFlipperPlugin()); + } + } + } +} diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 34a9de9e5..8f8efe768 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,19 +1,26 @@ + package="com.example"> + + + + + @@ -22,49 +29,29 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - diff --git a/example/android/app/src/main/java/com/example/MainActivity.java b/example/android/app/src/main/java/com/example/MainActivity.java index e84b72551..5e57fb914 100644 --- a/example/android/app/src/main/java/com/example/MainActivity.java +++ b/example/android/app/src/main/java/com/example/MainActivity.java @@ -4,12 +4,12 @@ public class MainActivity extends ReactActivity { - /** - * Returns the name of the main component registered from JavaScript. - * This is used to schedule rendering of the component. - */ - @Override - protected String getMainComponentName() { - return "example"; - } + /** + * Returns the name of the main component registered from JavaScript. This is + * used to schedule rendering of the component. + */ + @Override + protected String getMainComponentName() { + return "example"; + } } diff --git a/example/android/app/src/main/java/com/example/MainApplication.java b/example/android/app/src/main/java/com/example/MainApplication.java index d85de4d9a..fd8ec883d 100644 --- a/example/android/app/src/main/java/com/example/MainApplication.java +++ b/example/android/app/src/main/java/com/example/MainApplication.java @@ -1,38 +1,39 @@ package com.example; import android.app.Application; - +import android.content.Context; +import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; -import com.dieam.reactnativepushnotification.ReactNativePushNotificationPackage; +import com.facebook.react.ReactInstanceManager; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; -import com.facebook.react.shell.MainReactPackage; import com.facebook.soloader.SoLoader; - -import java.util.Arrays; +import java.lang.reflect.InvocationTargetException; import java.util.List; public class MainApplication extends Application implements ReactApplication { - private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { - @Override - public boolean getUseDeveloperSupport() { - return BuildConfig.DEBUG; - } + private final ReactNativeHost mReactNativeHost = + new ReactNativeHost(this) { + @Override + public boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } - @Override - protected List getPackages() { - return Arrays.asList( - new MainReactPackage(), - new ReactNativePushNotificationPackage() - ); - } + @Override + protected List getPackages() { + @SuppressWarnings("UnnecessaryLocalVariable") + List packages = new PackageList(this).getPackages(); + // Packages that cannot be autolinked yet can be added manually here, for example: + // packages.add(new MyReactNativePackage()); + return packages; + } - @Override - protected String getJSMainModuleName() { - return "index"; - } - }; + @Override + protected String getJSMainModuleName() { + return "index"; + } + }; @Override public ReactNativeHost getReactNativeHost() { @@ -43,5 +44,37 @@ public ReactNativeHost getReactNativeHost() { public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); + initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + } + + /** + * Loads Flipper in React Native templates. Call this in the onCreate method with something like + * initializeFlipper(this, getReactNativeHost().getReactInstanceManager()); + * + * @param context + * @param reactInstanceManager + */ + private static void initializeFlipper( + Context context, ReactInstanceManager reactInstanceManager) { + if (BuildConfig.DEBUG) { + try { + /* + We use reflection here to pick up the class that initializes Flipper, + since Flipper library is not available in release mode + */ + Class aClass = Class.forName("com.example.ReactNativeFlipper"); + aClass + .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class) + .invoke(null, context, reactInstanceManager); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } } } diff --git a/example/android/app/src/main/res/raw/sample.mp3 b/example/android/app/src/main/res/raw/sample.mp3 new file mode 100644 index 000000000..4569ff11f Binary files /dev/null and b/example/android/app/src/main/res/raw/sample.mp3 differ diff --git a/example/android/app/src/main/res/values/styles.xml b/example/android/app/src/main/res/values/styles.xml index 319eb0ca1..62fe59fa4 100644 --- a/example/android/app/src/main/res/values/styles.xml +++ b/example/android/app/src/main/res/values/styles.xml @@ -3,6 +3,7 @@ diff --git a/example/android/build.gradle b/example/android/build.gradle index 49569e4db..32a599bd5 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -1,16 +1,20 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext { + buildToolsVersion = "28.0.3" + minSdkVersion = 16 + compileSdkVersion = 28 + targetSdkVersion = 28 + } repositories { + google() jcenter() - maven { - url 'https://maven.google.com/' - name 'Google' - } } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath("com.android.tools.build:gradle:3.5.2") + classpath('com.google.gms:google-services:4.3.3') // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -19,22 +23,17 @@ buildscript { allprojects { repositories { mavenLocal() - jcenter() maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm - url "$rootDir/../node_modules/react-native/android" + url("$rootDir/../node_modules/react-native/android") } maven { - url 'https://maven.google.com/' - name 'Google' + // Android JSC is installed from npm + url("$rootDir/../node_modules/jsc-android/dist") } - } -} -ext { - buildToolsVersion = "26.0.3" - minSdkVersion = 16 - compileSdkVersion = 26 - targetSdkVersion = 26 - supportLibVersion = "26.1.0" + google() + jcenter() + maven { url 'https://www.jitpack.io' } + } } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 1fd964e90..1bbc8cc20 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -17,4 +17,12 @@ # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true -android.useDeprecatedNdk=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Automatically convert third-party libraries to use AndroidX +android.enableJetifier=true + +# Version of flipper SDK to use with React Native +FLIPPER_VERSION=0.33.1 diff --git a/example/android/gradle/wrapper/gradle-wrapper.jar b/example/android/gradle/wrapper/gradle-wrapper.jar index b5166dad4..5c2d1cf01 100644 Binary files a/example/android/gradle/wrapper/gradle-wrapper.jar and b/example/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index 81a86e213..1ba7206f8 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.5.1-all.zip diff --git a/example/android/gradlew b/example/android/gradlew index 91a7e269e..83f2acfdc 100755 --- a/example/android/gradlew +++ b/example/android/gradlew @@ -1,4 +1,20 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## ## @@ -6,20 +22,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +64,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,31 +75,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -90,7 +105,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -110,10 +125,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` @@ -154,11 +170,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/example/android/gradlew.bat b/example/android/gradlew.bat index 8a0b282aa..9618d8d96 100644 --- a/example/android/gradlew.bat +++ b/example/android/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -8,14 +24,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +62,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +75,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/example/android/keystores/BUCK b/example/android/keystores/BUCK deleted file mode 100644 index 88e4c31b2..000000000 --- a/example/android/keystores/BUCK +++ /dev/null @@ -1,8 +0,0 @@ -keystore( - name = "debug", - properties = "debug.keystore.properties", - store = "debug.keystore", - visibility = [ - "PUBLIC", - ], -) diff --git a/example/android/keystores/debug.keystore.properties b/example/android/keystores/debug.keystore.properties deleted file mode 100644 index 121bfb49f..000000000 --- a/example/android/keystores/debug.keystore.properties +++ /dev/null @@ -1,4 +0,0 @@ -key.store=debug.keystore -key.alias=androiddebugkey -key.store.password=android -key.alias.password=android diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 819c58ab6..263c9e8ca 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -1,5 +1,3 @@ rootProject.name = 'example' -include ':react-native-push-notification' -project(':react-native-push-notification').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-push-notification/android') - +apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) include ':app' diff --git a/example/app.json b/example/app.json index ea94bc4c6..2f89ceb8b 100644 --- a/example/app.json +++ b/example/app.json @@ -1,5 +1,4 @@ { "name": "example", - "displayName": "React Native Push Notification Example", - "senderID": "YOUR-GCM-ID" -} \ No newline at end of file + "displayName": "React Native Push Notification Example" +} diff --git a/example/babel.config.js b/example/babel.config.js new file mode 100644 index 000000000..f842b77fc --- /dev/null +++ b/example/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: ['module:metro-react-native-babel-preset'], +}; diff --git a/example/index.js b/example/index.js index 802b4350d..a850d031d 100644 --- a/example/index.js +++ b/example/index.js @@ -1,4 +1,6 @@ -/** @format */ +/** + * @format + */ import {AppRegistry} from 'react-native'; import App from './App'; diff --git a/example/ios/Podfile b/example/ios/Podfile new file mode 100644 index 000000000..faf88bd5e --- /dev/null +++ b/example/ios/Podfile @@ -0,0 +1,104 @@ +platform :ios, '9.0' +require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' + +def add_flipper_pods!(versions = {}) + versions['Flipper'] ||= '~> 0.33.1' + versions['DoubleConversion'] ||= '1.1.7' + versions['Flipper-Folly'] ||= '~> 2.1' + versions['Flipper-Glog'] ||= '0.3.6' + versions['Flipper-PeerTalk'] ||= '~> 0.0.4' + versions['Flipper-RSocket'] ||= '~> 1.0' + + pod 'FlipperKit', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FlipperKitLayoutPlugin', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/SKIOSNetworkPlugin', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FlipperKitUserDefaultsPlugin', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FlipperKitReactPlugin', versions['Flipper'], :configuration => 'Debug' + + # List all transitive dependencies for FlipperKit pods + # to avoid them being linked in Release builds + pod 'Flipper', versions['Flipper'], :configuration => 'Debug' + pod 'Flipper-DoubleConversion', versions['DoubleConversion'], :configuration => 'Debug' + pod 'Flipper-Folly', versions['Flipper-Folly'], :configuration => 'Debug' + pod 'Flipper-Glog', versions['Flipper-Glog'], :configuration => 'Debug' + pod 'Flipper-PeerTalk', versions['Flipper-PeerTalk'], :configuration => 'Debug' + pod 'Flipper-RSocket', versions['Flipper-RSocket'], :configuration => 'Debug' + pod 'FlipperKit/Core', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/CppBridge', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FBCxxFollyDynamicConvert', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FBDefines', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FKPortForwarding', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FlipperKitHighlightOverlay', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FlipperKitLayoutTextSearchable', versions['Flipper'], :configuration => 'Debug' + pod 'FlipperKit/FlipperKitNetworkPlugin', versions['Flipper'], :configuration => 'Debug' +end + +# Post Install processing for Flipper +def flipper_post_install(installer) + installer.pods_project.targets.each do |target| + if target.name == 'YogaKit' + target.build_configurations.each do |config| + config.build_settings['SWIFT_VERSION'] = '4.1' + end + end + end +end + +target 'example' do + # Pods for example + pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" + pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" + pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" + pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" + pod 'React', :path => '../node_modules/react-native/' + pod 'React-Core', :path => '../node_modules/react-native/' + pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' + pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' + pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' + pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' + pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' + pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' + pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' + pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' + pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' + pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' + pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' + pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' + + pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' + pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' + pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' + pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' + pod 'ReactCommon/callinvoker', :path => "../node_modules/react-native/ReactCommon" + pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" + pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga', :modular_headers => true + + pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' + pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' + pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' + + target 'exampleTests' do + inherit! :complete + # Pods for testing + end + + use_native_modules! + + # Enables Flipper. + # + # Note that if you have use_frameworks! enabled, Flipper will not work and + # you should disable these next few lines. + add_flipper_pods! + post_install do |installer| + flipper_post_install(installer) + end +end + +target 'example-tvOS' do + # Pods for example-tvOS + + target 'example-tvOSTests' do + inherit! :search_paths + # Pods for testing + end +end diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock new file mode 100644 index 000000000..cc1639da9 --- /dev/null +++ b/example/ios/Podfile.lock @@ -0,0 +1,462 @@ +PODS: + - boost-for-react-native (1.63.0) + - CocoaAsyncSocket (7.6.4) + - CocoaLibEvent (1.0.0) + - DoubleConversion (1.1.6) + - FBLazyVector (0.62.2) + - FBReactNativeSpec (0.62.2): + - Folly (= 2018.10.22.00) + - RCTRequired (= 0.62.2) + - RCTTypeSafety (= 0.62.2) + - React-Core (= 0.62.2) + - React-jsi (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - Flipper (0.33.1): + - Flipper-Folly (~> 2.1) + - Flipper-RSocket (~> 1.0) + - Flipper-DoubleConversion (1.1.7) + - Flipper-Folly (2.1.1): + - boost-for-react-native + - CocoaLibEvent (~> 1.0) + - Flipper-DoubleConversion + - Flipper-Glog + - OpenSSL-Universal (= 1.0.2.19) + - Flipper-Glog (0.3.6) + - Flipper-PeerTalk (0.0.4) + - Flipper-RSocket (1.0.0): + - Flipper-Folly (~> 2.0) + - FlipperKit (0.33.1): + - FlipperKit/Core (= 0.33.1) + - FlipperKit/Core (0.33.1): + - Flipper (~> 0.33.1) + - FlipperKit/CppBridge + - FlipperKit/FBCxxFollyDynamicConvert + - FlipperKit/FBDefines + - FlipperKit/FKPortForwarding + - FlipperKit/CppBridge (0.33.1): + - Flipper (~> 0.33.1) + - FlipperKit/FBCxxFollyDynamicConvert (0.33.1): + - Flipper-Folly (~> 2.1) + - FlipperKit/FBDefines (0.33.1) + - FlipperKit/FKPortForwarding (0.33.1): + - CocoaAsyncSocket (~> 7.6) + - Flipper-PeerTalk (~> 0.0.4) + - FlipperKit/FlipperKitHighlightOverlay (0.33.1) + - FlipperKit/FlipperKitLayoutPlugin (0.33.1): + - FlipperKit/Core + - FlipperKit/FlipperKitHighlightOverlay + - FlipperKit/FlipperKitLayoutTextSearchable + - YogaKit (~> 1.18) + - FlipperKit/FlipperKitLayoutTextSearchable (0.33.1) + - FlipperKit/FlipperKitNetworkPlugin (0.33.1): + - FlipperKit/Core + - FlipperKit/FlipperKitReactPlugin (0.33.1): + - FlipperKit/Core + - FlipperKit/FlipperKitUserDefaultsPlugin (0.33.1): + - FlipperKit/Core + - FlipperKit/SKIOSNetworkPlugin (0.33.1): + - FlipperKit/Core + - FlipperKit/FlipperKitNetworkPlugin + - Folly (2018.10.22.00): + - boost-for-react-native + - DoubleConversion + - Folly/Default (= 2018.10.22.00) + - glog + - Folly/Default (2018.10.22.00): + - boost-for-react-native + - DoubleConversion + - glog + - glog (0.3.5) + - OpenSSL-Universal (1.0.2.19): + - OpenSSL-Universal/Static (= 1.0.2.19) + - OpenSSL-Universal/Static (1.0.2.19) + - RCTRequired (0.62.2) + - RCTTypeSafety (0.62.2): + - FBLazyVector (= 0.62.2) + - Folly (= 2018.10.22.00) + - RCTRequired (= 0.62.2) + - React-Core (= 0.62.2) + - React (0.62.2): + - React-Core (= 0.62.2) + - React-Core/DevSupport (= 0.62.2) + - React-Core/RCTWebSocket (= 0.62.2) + - React-RCTActionSheet (= 0.62.2) + - React-RCTAnimation (= 0.62.2) + - React-RCTBlob (= 0.62.2) + - React-RCTImage (= 0.62.2) + - React-RCTLinking (= 0.62.2) + - React-RCTNetwork (= 0.62.2) + - React-RCTSettings (= 0.62.2) + - React-RCTText (= 0.62.2) + - React-RCTVibration (= 0.62.2) + - React-Core (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.62.2) + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/CoreModulesHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/Default (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/DevSupport (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.62.2) + - React-Core/RCTWebSocket (= 0.62.2) + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - React-jsinspector (= 0.62.2) + - Yoga + - React-Core/RCTActionSheetHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTAnimationHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTBlobHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTImageHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTLinkingHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTNetworkHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTSettingsHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTTextHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTVibrationHeaders (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-Core/RCTWebSocket (0.62.2): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.62.2) + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsiexecutor (= 0.62.2) + - Yoga + - React-CoreModules (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 0.62.2) + - React-Core/CoreModulesHeaders (= 0.62.2) + - React-RCTImage (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - React-cxxreact (0.62.2): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsinspector (= 0.62.2) + - React-jsi (0.62.2): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsi/Default (= 0.62.2) + - React-jsi/Default (0.62.2): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsiexecutor (0.62.2): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - React-jsinspector (0.62.2) + - React-RCTActionSheet (0.62.2): + - React-Core/RCTActionSheetHeaders (= 0.62.2) + - React-RCTAnimation (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 0.62.2) + - React-Core/RCTAnimationHeaders (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - React-RCTBlob (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - Folly (= 2018.10.22.00) + - React-Core/RCTBlobHeaders (= 0.62.2) + - React-Core/RCTWebSocket (= 0.62.2) + - React-jsi (= 0.62.2) + - React-RCTNetwork (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - React-RCTImage (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 0.62.2) + - React-Core/RCTImageHeaders (= 0.62.2) + - React-RCTNetwork (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - React-RCTLinking (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - React-Core/RCTLinkingHeaders (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - React-RCTNetwork (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 0.62.2) + - React-Core/RCTNetworkHeaders (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - React-RCTSettings (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 0.62.2) + - React-Core/RCTSettingsHeaders (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - React-RCTText (0.62.2): + - React-Core/RCTTextHeaders (= 0.62.2) + - React-RCTVibration (0.62.2): + - FBReactNativeSpec (= 0.62.2) + - Folly (= 2018.10.22.00) + - React-Core/RCTVibrationHeaders (= 0.62.2) + - ReactCommon/turbomodule/core (= 0.62.2) + - ReactCommon/callinvoker (0.62.2): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.62.2) + - ReactCommon/turbomodule/core (0.62.2): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-Core (= 0.62.2) + - React-cxxreact (= 0.62.2) + - React-jsi (= 0.62.2) + - ReactCommon/callinvoker (= 0.62.2) + - RNCPushNotificationIOS (1.1.1): + - React + - Yoga (1.14.0) + - YogaKit (1.18.1): + - Yoga (~> 1.14) + +DEPENDENCIES: + - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) + - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) + - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) + - Flipper (~> 0.33.1) + - Flipper-DoubleConversion (= 1.1.7) + - Flipper-Folly (~> 2.1) + - Flipper-Glog (= 0.3.6) + - Flipper-PeerTalk (~> 0.0.4) + - Flipper-RSocket (~> 1.0) + - FlipperKit (~> 0.33.1) + - FlipperKit/Core (~> 0.33.1) + - FlipperKit/CppBridge (~> 0.33.1) + - FlipperKit/FBCxxFollyDynamicConvert (~> 0.33.1) + - FlipperKit/FBDefines (~> 0.33.1) + - FlipperKit/FKPortForwarding (~> 0.33.1) + - FlipperKit/FlipperKitHighlightOverlay (~> 0.33.1) + - FlipperKit/FlipperKitLayoutPlugin (~> 0.33.1) + - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.33.1) + - FlipperKit/FlipperKitNetworkPlugin (~> 0.33.1) + - FlipperKit/FlipperKitReactPlugin (~> 0.33.1) + - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.33.1) + - FlipperKit/SKIOSNetworkPlugin (~> 0.33.1) + - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) + - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) + - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) + - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) + - React (from `../node_modules/react-native/`) + - React-Core (from `../node_modules/react-native/`) + - React-Core/DevSupport (from `../node_modules/react-native/`) + - React-Core/RCTWebSocket (from `../node_modules/react-native/`) + - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) + - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) + - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) + - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) + - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) + - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) + - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) + - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) + - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) + - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) + - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) + - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) + - React-RCTText (from `../node_modules/react-native/Libraries/Text`) + - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) + - ReactCommon/callinvoker (from `../node_modules/react-native/ReactCommon`) + - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)" + - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) + +SPEC REPOS: + trunk: + - boost-for-react-native + - CocoaAsyncSocket + - CocoaLibEvent + - Flipper + - Flipper-DoubleConversion + - Flipper-Folly + - Flipper-Glog + - Flipper-PeerTalk + - Flipper-RSocket + - FlipperKit + - OpenSSL-Universal + - YogaKit + +EXTERNAL SOURCES: + DoubleConversion: + :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" + FBLazyVector: + :path: "../node_modules/react-native/Libraries/FBLazyVector" + FBReactNativeSpec: + :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" + Folly: + :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" + glog: + :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" + RCTRequired: + :path: "../node_modules/react-native/Libraries/RCTRequired" + RCTTypeSafety: + :path: "../node_modules/react-native/Libraries/TypeSafety" + React: + :path: "../node_modules/react-native/" + React-Core: + :path: "../node_modules/react-native/" + React-CoreModules: + :path: "../node_modules/react-native/React/CoreModules" + React-cxxreact: + :path: "../node_modules/react-native/ReactCommon/cxxreact" + React-jsi: + :path: "../node_modules/react-native/ReactCommon/jsi" + React-jsiexecutor: + :path: "../node_modules/react-native/ReactCommon/jsiexecutor" + React-jsinspector: + :path: "../node_modules/react-native/ReactCommon/jsinspector" + React-RCTActionSheet: + :path: "../node_modules/react-native/Libraries/ActionSheetIOS" + React-RCTAnimation: + :path: "../node_modules/react-native/Libraries/NativeAnimation" + React-RCTBlob: + :path: "../node_modules/react-native/Libraries/Blob" + React-RCTImage: + :path: "../node_modules/react-native/Libraries/Image" + React-RCTLinking: + :path: "../node_modules/react-native/Libraries/LinkingIOS" + React-RCTNetwork: + :path: "../node_modules/react-native/Libraries/Network" + React-RCTSettings: + :path: "../node_modules/react-native/Libraries/Settings" + React-RCTText: + :path: "../node_modules/react-native/Libraries/Text" + React-RCTVibration: + :path: "../node_modules/react-native/Libraries/Vibration" + ReactCommon: + :path: "../node_modules/react-native/ReactCommon" + RNCPushNotificationIOS: + :path: "../node_modules/@react-native-community/push-notification-ios" + Yoga: + :path: "../node_modules/react-native/ReactCommon/yoga" + +SPEC CHECKSUMS: + boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c + CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845 + CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f + DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 + FBLazyVector: 4aab18c93cd9546e4bfed752b4084585eca8b245 + FBReactNativeSpec: 5465d51ccfeecb7faa12f9ae0024f2044ce4044e + Flipper: 6c1f484f9a88d30ab3e272800d53688439e50f69 + Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 + Flipper-Folly: 2de3d03e0acc7064d5e4ed9f730e2f217486f162 + Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6 + Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 + Flipper-RSocket: 1260a31c05c238eabfa9bb8a64e3983049048371 + FlipperKit: 6dc9b8f4ef60d9e5ded7f0264db299c91f18832e + Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 + glog: 1f3da668190260b06b429bb211bfbee5cd790c28 + OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355 + RCTRequired: cec6a34b3ac8a9915c37e7e4ad3aa74726ce4035 + RCTTypeSafety: 93006131180074cffa227a1075802c89a49dd4ce + React: 29a8b1a02bd764fb7644ef04019270849b9a7ac3 + React-Core: b12bffb3f567fdf99510acb716ef1abd426e0e05 + React-CoreModules: 4a9b87bbe669d6c3173c0132c3328e3b000783d0 + React-cxxreact: e65f9c2ba0ac5be946f53548c1aaaee5873a8103 + React-jsi: b6dc94a6a12ff98e8877287a0b7620d365201161 + React-jsiexecutor: 1540d1c01bb493ae3124ed83351b1b6a155db7da + React-jsinspector: 512e560d0e985d0e8c479a54a4e5c147a9c83493 + React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c + React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0 + React-RCTBlob: a332773f0ebc413a0ce85942a55b064471587a71 + React-RCTImage: e70be9b9c74fe4e42d0005f42cace7981c994ac3 + React-RCTLinking: c1b9739a88d56ecbec23b7f63650e44672ab2ad2 + React-RCTNetwork: 73138b6f45e5a2768ad93f3d57873c2a18d14b44 + React-RCTSettings: 6e3738a87e21b39a8cb08d627e68c44acf1e325a + React-RCTText: fae545b10cfdb3d247c36c56f61a94cfd6dba41d + React-RCTVibration: 4356114dbcba4ce66991096e51a66e61eda51256 + ReactCommon: ed4e11d27609d571e7eee8b65548efc191116eb3 + RNCPushNotificationIOS: a0b6894f4ad9b93d9dac467fdf4d055660ac8a0d + Yoga: 3ebccbdd559724312790e7742142d062476b698e + YogaKit: f782866e155069a2cca2517aafea43200b01fd5a + +PODFILE CHECKSUM: 56c2537f71f3f02200d6918c542a8e89a0b422fa + +COCOAPODS: 1.9.1 diff --git a/example/ios/example-tvOS/Info.plist b/example/ios/example-tvOS/Info.plist index 2fb6a11c2..ecbd496be 100644 --- a/example/ios/example-tvOS/Info.plist +++ b/example/ios/example-tvOS/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -22,6 +22,19 @@ 1 LSRequiresIPhoneOS + NSAppTransportSecurity + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + NSLocationWhenInUseUsageDescription + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities @@ -36,19 +49,5 @@ UIViewControllerBasedStatusBarAppearance - NSLocationWhenInUseUsageDescription - - NSAppTransportSecurity - - - NSExceptionDomains - - localhost - - NSExceptionAllowsInsecureHTTPLoads - - - - diff --git a/example/ios/example.xcodeproj/project.pbxproj b/example/ios/example.xcodeproj/project.pbxproj index 777fdb18f..268d7cc50 100644 --- a/example/ios/example.xcodeproj/project.pbxproj +++ b/example/ios/example.xcodeproj/project.pbxproj @@ -7,75 +7,23 @@ objects = { /* Begin PBXBuildFile section */ - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 00E356F31AD99517003FC87E /* exampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* exampleTests.m */; }; - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; - 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; - 2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */; }; - 2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */; }; - 2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */; }; - 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */; }; - 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */; }; - 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */; }; - 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D16E6891FA4F8E400B85C8A /* libReact.a */; }; 2DCD954D1E0B4F2C00145EB5 /* exampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* exampleTests.m */; }; - 2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3DAD3EA31DF850E9000B6D8A /* libReact.a */; }; - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */; }; - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; - ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */; }; + 3997B5ABB1D8AA3BF2205130 /* libPods-example-tvOSTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ACCB69D76B81B3D29BE3BB2B /* libPods-example-tvOSTests.a */; }; + 4303B027D05E61B36AF2D9DA /* libPods-example-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D89C42625470FE853701396C /* libPods-example-tvOS.a */; }; + 4BF20923B09DA7D7C7D74054 /* libPods-example-exampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F3EFF15EA907A6500887787 /* libPods-example-exampleTests.a */; }; + 66172E2B135131DB9C88C137 /* libPods-example.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 67C595176EF92CCFA00C1943 /* libPods-example.a */; }; + AECB905824658DC600ED1B83 /* sample.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = AECB905724658DC600ED1B83 /* sample.mp3 */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTActionSheet; - }; - 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTGeolocation; - }; - 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5115D1A9E6B3D00147676; - remoteInfo = RCTImage; - }; - 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B511DB1A9E6C8500147676; - remoteInfo = RCTNetwork; - }; - 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; - remoteInfo = RCTVibration; - }; 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -83,27 +31,6 @@ remoteGlobalIDString = 13B07F861A680F5B00A75B9A; remoteInfo = example; }; - 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTSettings; - }; - 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3C86DF461ADF2C930047B81A; - remoteInfo = RCTWebSocket; - }; - 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; - remoteInfo = React; - }; 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; @@ -111,223 +38,13 @@ remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7; remoteInfo = "example-tvOS"; }; - 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = ADD01A681E09402E00F6D226; - remoteInfo = "RCTBlob-tvOS"; - }; - 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3DBE0D001F3B181A0099AA32; - remoteInfo = fishhook; - }; - 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3DBE0D0D1F3B181C0099AA32; - remoteInfo = "fishhook-tvOS"; - }; - 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EBF21BDC1FC498900052F4D5; - remoteInfo = jsinspector; - }; - 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = EBF21BFA1FC4989A0052F4D5; - remoteInfo = "jsinspector-tvOS"; - }; - 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 139D7ECE1E25DB7D00323FB7; - remoteInfo = "third-party"; - }; - 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D383D3C1EBD27B6005632C8; - remoteInfo = "third-party-tvOS"; - }; - 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 139D7E881E25C6D100323FB7; - remoteInfo = "double-conversion"; - }; - 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D383D621EBD27B9005632C8; - remoteInfo = "double-conversion-tvOS"; - }; - 2DF0FFEA2056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 9936F3131F5F2E4B0010BF04; - remoteInfo = privatedata; - }; - 2DF0FFEC2056DD460020B375 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 9936F32F1F5F2E5B0010BF04; - remoteInfo = "privatedata-tvOS"; - }; - 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A283A1D9B042B00D4039D; - remoteInfo = "RCTImage-tvOS"; - }; - 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28471D9B043800D4039D; - remoteInfo = "RCTLinking-tvOS"; - }; - 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28541D9B044C00D4039D; - remoteInfo = "RCTNetwork-tvOS"; - }; - 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28611D9B046600D4039D; - remoteInfo = "RCTSettings-tvOS"; - }; - 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A287B1D9B048500D4039D; - remoteInfo = "RCTText-tvOS"; - }; - 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28881D9B049200D4039D; - remoteInfo = "RCTWebSocket-tvOS"; - }; - 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28131D9B038B00D4039D; - remoteInfo = "React-tvOS"; - }; - 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3C059A1DE3340900C268FA; - remoteInfo = yoga; - }; - 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3C06751DE3340C00C268FA; - remoteInfo = "yoga-tvOS"; - }; - 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9251DE5FBEC00167DC4; - remoteInfo = cxxreact; - }; - 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9321DE5FBEE00167DC4; - remoteInfo = "cxxreact-tvOS"; - }; - 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD90B1DE5FBD600167DC4; - remoteInfo = jschelpers; - }; - 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 3D3CD9181DE5FBD800167DC4; - remoteInfo = "jschelpers-tvOS"; - }; - 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTAnimation; - }; - 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 2D2A28201D9B03D100D4039D; - remoteInfo = "RCTAnimation-tvOS"; - }; - 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 134814201AA4EA6300B7C361; - remoteInfo = RCTLinking; - }; - 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 58B5119B1A9E6C1200147676; - remoteInfo = RCTText; - }; - ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 358F4ED71D1E81A9004DF814; - remoteInfo = RCTBlob; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 00E356EE1AD99517003FC87E /* exampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = exampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* exampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = exampleTests.m; sourceTree = ""; }; - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = example/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = example/AppDelegate.m; sourceTree = ""; }; @@ -335,14 +52,24 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = example/main.m; sourceTree = ""; }; - 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; + 15BD6A0C81A3E52CBA666C17 /* Pods-example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.debug.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.debug.xcconfig"; sourceTree = ""; }; 2D02E47B1E0B4A5D006451C7 /* example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "example-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 2D02E4901E0B4A5D006451C7 /* example-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "example-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = "../node_modules/react-native/Libraries/NativeAnimation/RCTAnimation.xcodeproj"; sourceTree = ""; }; - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; - ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTBlob.xcodeproj; path = "../node_modules/react-native/Libraries/Blob/RCTBlob.xcodeproj"; sourceTree = ""; }; + 2F3EFF15EA907A6500887787 /* libPods-example-exampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example-exampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 37D30ECBCC5696F54DDBDB07 /* Pods-example-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example-tvOS.release.xcconfig"; path = "Target Support Files/Pods-example-tvOS/Pods-example-tvOS.release.xcconfig"; sourceTree = ""; }; + 454237A3C32EB61EE42721D8 /* Pods-example-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-example-tvOSTests/Pods-example-tvOSTests.debug.xcconfig"; sourceTree = ""; }; + 52FCA686CB54A0F6E8129E44 /* Pods-example-exampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example-exampleTests.debug.xcconfig"; path = "Target Support Files/Pods-example-exampleTests/Pods-example-exampleTests.debug.xcconfig"; sourceTree = ""; }; + 566FF18746355BDCE5A6333B /* Pods-example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example.release.xcconfig"; path = "Target Support Files/Pods-example/Pods-example.release.xcconfig"; sourceTree = ""; }; + 67C595176EF92CCFA00C1943 /* libPods-example.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + 68FB3463CAEF28E88730ADEE /* Pods-example-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-example-tvOSTests/Pods-example-tvOSTests.release.xcconfig"; sourceTree = ""; }; + ACCB69D76B81B3D29BE3BB2B /* libPods-example-tvOSTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example-tvOSTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AECB905724658DC600ED1B83 /* sample.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = sample.mp3; sourceTree = ""; }; + AED90B1C243E6D21006F11F7 /* example.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = example.entitlements; path = example/example.entitlements; sourceTree = ""; }; + B43E6CF3919EF7ACAF9CC8B7 /* Pods-example-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-example-tvOS/Pods-example-tvOS.debug.xcconfig"; sourceTree = ""; }; + C528DBA88EA5CBFA010ECC73 /* Pods-example-exampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-example-exampleTests.release.xcconfig"; path = "Target Support Files/Pods-example-exampleTests/Pods-example-exampleTests.release.xcconfig"; sourceTree = ""; }; + D89C42625470FE853701396C /* libPods-example-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-example-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -350,7 +77,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 140ED2AC1D01E1AD002B40FF /* libReact.a in Frameworks */, + 4BF20923B09DA7D7C7D74054 /* libPods-example-exampleTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -358,19 +85,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - ADBDB9381DFEBF1600ED6528 /* libRCTBlob.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 146834051AC3E58100842450 /* libReact.a in Frameworks */, - 5E9157361DD0AC6A00FF2AA8 /* libRCTAnimation.a in Frameworks */, - 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, - 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, - 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, - 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, - 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, - 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, - 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, - 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, - 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, + 66172E2B135131DB9C88C137 /* libPods-example.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -378,14 +93,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */, - 2D02E4C21E0B4AEC006451C7 /* libRCTAnimation.a in Frameworks */, - 2D02E4C31E0B4AEC006451C7 /* libRCTImage-tvOS.a in Frameworks */, - 2D02E4C41E0B4AEC006451C7 /* libRCTLinking-tvOS.a in Frameworks */, - 2D02E4C51E0B4AEC006451C7 /* libRCTNetwork-tvOS.a in Frameworks */, - 2D02E4C61E0B4AEC006451C7 /* libRCTSettings-tvOS.a in Frameworks */, - 2D02E4C71E0B4AEC006451C7 /* libRCTText-tvOS.a in Frameworks */, - 2D02E4C81E0B4AEC006451C7 /* libRCTWebSocket-tvOS.a in Frameworks */, + 4303B027D05E61B36AF2D9DA /* libPods-example-tvOS.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -393,55 +101,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2DF0FFEE2056DD460020B375 /* libReact.a in Frameworks */, + 3997B5ABB1D8AA3BF2205130 /* libPods-example-tvOSTests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 00C302A81ABCB8CE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302B61ABCB90400DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302BC1ABCB91800DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, - 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302D41ABCB9D200DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, - 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 00C302E01ABCB9EE00DB3ED1 /* Products */ = { - isa = PBXGroup; - children = ( - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, - ); - name = Products; - sourceTree = ""; - }; 00E356EF1AD99517003FC87E /* exampleTests */ = { isa = PBXGroup; children = ( @@ -459,29 +125,11 @@ name = "Supporting Files"; sourceTree = ""; }; - 139105B71AF99BAD00B5F7CC /* Products */ = { - isa = PBXGroup; - children = ( - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, - 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; - 139FDEE71B06529A00C62182 /* Products */ = { - isa = PBXGroup; - children = ( - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, - 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */, - 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */, - 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 13B07FAE1A68108700A75B9A /* example */ = { isa = PBXGroup; children = ( + AECB905724658DC600ED1B83 /* sample.mp3 */, + AED90B1C243E6D21006F11F7 /* example.entitlements */, 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 13B07FB01A68108700A75B9A /* AppDelegate.m */, @@ -493,83 +141,26 @@ name = example; sourceTree = ""; }; - 146834001AC3E56700842450 /* Products */ = { - isa = PBXGroup; - children = ( - 146834041AC3E56700842450 /* libReact.a */, - 3DAD3EA31DF850E9000B6D8A /* libReact.a */, - 3DAD3EA51DF850E9000B6D8A /* libyoga.a */, - 3DAD3EA71DF850E9000B6D8A /* libyoga.a */, - 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */, - 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */, - 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */, - 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */, - 2DF0FFDF2056DD460020B375 /* libjsinspector.a */, - 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */, - 2DF0FFE32056DD460020B375 /* libthird-party.a */, - 2DF0FFE52056DD460020B375 /* libthird-party.a */, - 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */, - 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */, - 2DF0FFEB2056DD460020B375 /* libprivatedata.a */, - 2DF0FFED2056DD460020B375 /* libprivatedata-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { isa = PBXGroup; children = ( - 2D16E6891FA4F8E400B85C8A /* libReact.a */, + ED297162215061F000B7C4FE /* JavaScriptCore.framework */, + ED2971642150620600B7C4FE /* JavaScriptCore.framework */, + 67C595176EF92CCFA00C1943 /* libPods-example.a */, + 2F3EFF15EA907A6500887787 /* libPods-example-exampleTests.a */, + D89C42625470FE853701396C /* libPods-example-tvOS.a */, + ACCB69D76B81B3D29BE3BB2B /* libPods-example-tvOSTests.a */, ); name = Frameworks; sourceTree = ""; }; - 5E91572E1DD0AC6500FF2AA8 /* Products */ = { - isa = PBXGroup; - children = ( - 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */, - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */, - ); - name = Products; - sourceTree = ""; - }; - 78C398B11ACF4ADC00677621 /* Products */ = { - isa = PBXGroup; - children = ( - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, - 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */, - 146833FF1AC3E56700842450 /* React.xcodeproj */, - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, - ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */, - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, ); name = Libraries; sourceTree = ""; }; - 832341B11AAA6A8300B99B32 /* Products */ = { - isa = PBXGroup; - children = ( - 832341B51AAA6A8300B99B32 /* libRCTText.a */, - 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */, - ); - name = Products; - sourceTree = ""; - }; 83CBB9F61A601CBA00E9B192 = { isa = PBXGroup; children = ( @@ -578,6 +169,7 @@ 00E356EF1AD99517003FC87E /* exampleTests */, 83CBBA001A601CBA00E9B192 /* Products */, 2D16E6871FA4F8E400B85C8A /* Frameworks */, + AD372BDC7243AEAD7BA39FD9 /* Pods */, ); indentWidth = 2; sourceTree = ""; @@ -595,13 +187,19 @@ name = Products; sourceTree = ""; }; - ADBDB9201DFEBF0600ED6528 /* Products */ = { + AD372BDC7243AEAD7BA39FD9 /* Pods */ = { isa = PBXGroup; children = ( - ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */, - 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */, - ); - name = Products; + 15BD6A0C81A3E52CBA666C17 /* Pods-example.debug.xcconfig */, + 566FF18746355BDCE5A6333B /* Pods-example.release.xcconfig */, + 52FCA686CB54A0F6E8129E44 /* Pods-example-exampleTests.debug.xcconfig */, + C528DBA88EA5CBFA010ECC73 /* Pods-example-exampleTests.release.xcconfig */, + B43E6CF3919EF7ACAF9CC8B7 /* Pods-example-tvOS.debug.xcconfig */, + 37D30ECBCC5696F54DDBDB07 /* Pods-example-tvOS.release.xcconfig */, + 454237A3C32EB61EE42721D8 /* Pods-example-tvOSTests.debug.xcconfig */, + 68FB3463CAEF28E88730ADEE /* Pods-example-tvOSTests.release.xcconfig */, + ); + path = Pods; sourceTree = ""; }; /* End PBXGroup section */ @@ -611,6 +209,7 @@ isa = PBXNativeTarget; buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "exampleTests" */; buildPhases = ( + B0ED5983C06627818B5DC217 /* [CP] Check Pods Manifest.lock */, 00E356EA1AD99517003FC87E /* Sources */, 00E356EB1AD99517003FC87E /* Frameworks */, 00E356EC1AD99517003FC87E /* Resources */, @@ -629,6 +228,8 @@ isa = PBXNativeTarget; buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */; buildPhases = ( + 2DCA07023D4AA069A0C9D6BE /* [CP] Check Pods Manifest.lock */, + FD10A7F022414F080027D42C /* Start Packager */, 13B07F871A680F5B00A75B9A /* Sources */, 13B07F8C1A680F5B00A75B9A /* Frameworks */, 13B07F8E1A680F5B00A75B9A /* Resources */, @@ -639,7 +240,7 @@ dependencies = ( ); name = example; - productName = "Hello World"; + productName = example; productReference = 13B07F961A680F5B00A75B9A /* example.app */; productType = "com.apple.product-type.application"; }; @@ -647,6 +248,8 @@ isa = PBXNativeTarget; buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "example-tvOS" */; buildPhases = ( + 8F6D0FED697FE82D2DF59178 /* [CP] Check Pods Manifest.lock */, + FD10A7F122414F3F0027D42C /* Start Packager */, 2D02E4771E0B4A5D006451C7 /* Sources */, 2D02E4781E0B4A5D006451C7 /* Frameworks */, 2D02E4791E0B4A5D006451C7 /* Resources */, @@ -665,6 +268,7 @@ isa = PBXNativeTarget; buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "example-tvOSTests" */; buildPhases = ( + 5313D15A4BFFB977CEC741B2 /* [CP] Check Pods Manifest.lock */, 2D02E48C1E0B4A5D006451C7 /* Sources */, 2D02E48D1E0B4A5D006451C7 /* Frameworks */, 2D02E48E1E0B4A5D006451C7 /* Resources */, @@ -685,13 +289,15 @@ 83CBB9F71A601CBA00E9B192 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0610; - ORGANIZATIONNAME = Facebook; + LastUpgradeCheck = 1130; TargetAttributes = { 00E356ED1AD99517003FC87E = { CreatedOnToolsVersion = 6.2; TestTargetID = 13B07F861A680F5B00A75B9A; }; + 13B07F861A680F5B00A75B9A = { + LastSwiftMigration = 1120; + }; 2D02E47A1E0B4A5D006451C7 = { CreatedOnToolsVersion = 8.2.1; ProvisioningStyle = Automatic; @@ -705,7 +311,7 @@ }; buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, @@ -714,56 +320,6 @@ mainGroup = 83CBB9F61A601CBA00E9B192; productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; projectDirPath = ""; - projectReferences = ( - { - ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; - ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; - }, - { - ProductGroup = 5E91572E1DD0AC6500FF2AA8 /* Products */; - ProjectRef = 5E91572D1DD0AC6500FF2AA8 /* RCTAnimation.xcodeproj */; - }, - { - ProductGroup = ADBDB9201DFEBF0600ED6528 /* Products */; - ProjectRef = ADBDB91F1DFEBF0600ED6528 /* RCTBlob.xcodeproj */; - }, - { - ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; - ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; - }, - { - ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; - ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; - }, - { - ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; - ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; - }, - { - ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; - ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; - }, - { - ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; - ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; - }, - { - ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; - ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; - }, - { - ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; - ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; - }, - { - ProductGroup = 139FDEE71B06529A00C62182 /* Products */; - ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; - }, - { - ProductGroup = 146834001AC3E56700842450 /* Products */; - ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; - }, - ); projectRoot = ""; targets = ( 13B07F861A680F5B00A75B9A /* example */, @@ -774,268 +330,6 @@ }; /* End PBXProject section */ -/* Begin PBXReferenceProxy section */ - 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTActionSheet.a; - remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTGeolocation.a; - remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTImage.a; - remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTNetwork.a; - remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTVibration.a; - remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTSettings.a; - remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTWebSocket.a; - remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 146834041AC3E56700842450 /* libReact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReact.a; - remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2D16E6721FA4F8DC00B85C8A /* libRCTBlob-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTBlob-tvOS.a"; - remoteRef = 2D16E6711FA4F8DC00B85C8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2D16E6841FA4F8DC00B85C8A /* libfishhook.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libfishhook.a; - remoteRef = 2D16E6831FA4F8DC00B85C8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2D16E6861FA4F8DC00B85C8A /* libfishhook-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libfishhook-tvOS.a"; - remoteRef = 2D16E6851FA4F8DC00B85C8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFDF2056DD460020B375 /* libjsinspector.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjsinspector.a; - remoteRef = 2DF0FFDE2056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE12056DD460020B375 /* libjsinspector-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libjsinspector-tvOS.a"; - remoteRef = 2DF0FFE02056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE32056DD460020B375 /* libthird-party.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libthird-party.a"; - remoteRef = 2DF0FFE22056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE52056DD460020B375 /* libthird-party.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libthird-party.a"; - remoteRef = 2DF0FFE42056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE72056DD460020B375 /* libdouble-conversion.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libdouble-conversion.a"; - remoteRef = 2DF0FFE62056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFE92056DD460020B375 /* libdouble-conversion.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libdouble-conversion.a"; - remoteRef = 2DF0FFE82056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFEB2056DD460020B375 /* libprivatedata.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libprivatedata.a; - remoteRef = 2DF0FFEA2056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 2DF0FFED2056DD460020B375 /* libprivatedata-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libprivatedata-tvOS.a"; - remoteRef = 2DF0FFEC2056DD460020B375 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E841DF850E9000B6D8A /* libRCTImage-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTImage-tvOS.a"; - remoteRef = 3DAD3E831DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E881DF850E9000B6D8A /* libRCTLinking-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTLinking-tvOS.a"; - remoteRef = 3DAD3E871DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E8C1DF850E9000B6D8A /* libRCTNetwork-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTNetwork-tvOS.a"; - remoteRef = 3DAD3E8B1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E901DF850E9000B6D8A /* libRCTSettings-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTSettings-tvOS.a"; - remoteRef = 3DAD3E8F1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E941DF850E9000B6D8A /* libRCTText-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTText-tvOS.a"; - remoteRef = 3DAD3E931DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3E991DF850E9000B6D8A /* libRCTWebSocket-tvOS.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = "libRCTWebSocket-tvOS.a"; - remoteRef = 3DAD3E981DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA31DF850E9000B6D8A /* libReact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libReact.a; - remoteRef = 3DAD3EA21DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA51DF850E9000B6D8A /* libyoga.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libyoga.a; - remoteRef = 3DAD3EA41DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA71DF850E9000B6D8A /* libyoga.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libyoga.a; - remoteRef = 3DAD3EA61DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EA91DF850E9000B6D8A /* libcxxreact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libcxxreact.a; - remoteRef = 3DAD3EA81DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EAB1DF850E9000B6D8A /* libcxxreact.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libcxxreact.a; - remoteRef = 3DAD3EAA1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EAD1DF850E9000B6D8A /* libjschelpers.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjschelpers.a; - remoteRef = 3DAD3EAC1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 3DAD3EAF1DF850E9000B6D8A /* libjschelpers.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libjschelpers.a; - remoteRef = 3DAD3EAE1DF850E9000B6D8A /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 5E9157331DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTAnimation.a; - remoteRef = 5E9157321DD0AC6500FF2AA8 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 5E9157351DD0AC6500FF2AA8 /* libRCTAnimation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTAnimation.a; - remoteRef = 5E9157341DD0AC6500FF2AA8 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTLinking.a; - remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTText.a; - remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; - ADBDB9271DFEBF0700ED6528 /* libRCTBlob.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libRCTBlob.a; - remoteRef = ADBDB9261DFEBF0700ED6528 /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - /* Begin PBXResourcesBuildPhase section */ 00E356EC1AD99517003FC87E /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -1050,6 +344,7 @@ files = ( 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, + AECB905824658DC600ED1B83 /* sample.mp3 in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1099,6 +394,132 @@ shellPath = /bin/sh; shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; }; + 2DCA07023D4AA069A0C9D6BE /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-example-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 5313D15A4BFFB977CEC741B2 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-example-tvOSTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 8F6D0FED697FE82D2DF59178 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-example-tvOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + B0ED5983C06627818B5DC217 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-example-exampleTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + FD10A7F022414F080027D42C /* Start Packager */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Start Packager"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + showEnvVarsInLog = 0; + }; + FD10A7F122414F3F0027D42C /* Start Packager */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Start Packager"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1166,6 +587,7 @@ /* Begin XCBuildConfiguration section */ 00E356F61AD99517003FC87E /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 52FCA686CB54A0F6E8129E44 /* Pods-example-exampleTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -1178,7 +600,9 @@ OTHER_LDFLAGS = ( "-ObjC", "-lc++", + "$(inherited)", ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/example"; }; @@ -1186,6 +610,7 @@ }; 00E356F71AD99517003FC87E /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C528DBA88EA5CBFA010ECC73 /* Pods-example-exampleTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; COPY_PHASE_STRIP = NO; @@ -1195,7 +620,9 @@ OTHER_LDFLAGS = ( "-ObjC", "-lc++", + "$(inherited)", ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/example"; }; @@ -1203,10 +630,17 @@ }; 13B07F941A680F5B00A75B9A /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 15BD6A0C81A3E52CBA666C17 /* Pods-example.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = example/example.entitlements; CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = NO; + ENABLE_BITCODE = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "FB_SONARKIT_ENABLED=1", + ); INFOPLIST_FILE = example/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = ( @@ -1214,15 +648,21 @@ "-ObjC", "-lc++", ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = example; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; }; 13B07F951A680F5B00A75B9A /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 566FF18746355BDCE5A6333B /* Pods-example.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = example/example.entitlements; CURRENT_PROJECT_VERSION = 1; INFOPLIST_FILE = example/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1231,13 +671,16 @@ "-ObjC", "-lc++", ); + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = example; + SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; }; 2D02E4971E0B4A5E006451C7 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = B43E6CF3919EF7ACAF9CC8B7 /* Pods-example-tvOS.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; @@ -1251,10 +694,11 @@ INFOPLIST_FILE = "example-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = ( + "$(inherited)", "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.example-tvOS"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.example-tvOS"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; TARGETED_DEVICE_FAMILY = 3; @@ -1264,6 +708,7 @@ }; 2D02E4981E0B4A5E006451C7 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 37D30ECBCC5696F54DDBDB07 /* Pods-example-tvOS.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; @@ -1277,10 +722,11 @@ INFOPLIST_FILE = "example-tvOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; OTHER_LDFLAGS = ( + "$(inherited)", "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.example-tvOS"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.example-tvOS"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; TARGETED_DEVICE_FAMILY = 3; @@ -1290,6 +736,7 @@ }; 2D02E4991E0B4A5E006451C7 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 454237A3C32EB61EE42721D8 /* Pods-example-tvOSTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; @@ -1302,10 +749,11 @@ INFOPLIST_FILE = "example-tvOSTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; OTHER_LDFLAGS = ( + "$(inherited)", "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.example-tvOSTests"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.example-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example-tvOS.app/example-tvOS"; @@ -1315,6 +763,7 @@ }; 2D02E49A1E0B4A5E006451C7 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 68FB3463CAEF28E88730ADEE /* Pods-example-tvOSTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NONNULL = YES; @@ -1327,10 +776,11 @@ INFOPLIST_FILE = "example-tvOSTests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; OTHER_LDFLAGS = ( + "$(inherited)", "-ObjC", "-lc++", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.example-tvOSTests"; + PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.example-tvOSTests"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example-tvOS.app/example-tvOS"; @@ -1342,24 +792,37 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -1373,6 +836,12 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", + "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", + "\"$(inherited)\"", + ); MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -1383,17 +852,28 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -1401,6 +881,7 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -1408,6 +889,12 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)"; + LIBRARY_SEARCH_PATHS = ( + "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", + "\"$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)\"", + "\"$(inherited)\"", + ); MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; diff --git a/example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme b/example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme index a36391c90..9570230db 100644 --- a/example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme +++ b/example/ios/example.xcodeproj/xcshareddata/xcschemes/example-tvOS.xcscheme @@ -1,25 +1,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + diff --git a/example/ios/example/AppDelegate.h b/example/ios/example/AppDelegate.h index d4f2580b1..3c1381ce7 100644 --- a/example/ios/example/AppDelegate.h +++ b/example/ios/example/AppDelegate.h @@ -1,14 +1,8 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - +#import #import +#import -@interface AppDelegate : UIResponder - +@interface AppDelegate : UIResponder @property (nonatomic, strong) UIWindow *window; @end diff --git a/example/ios/example/AppDelegate.m b/example/ios/example/AppDelegate.m index eba94f353..0e513c62e 100644 --- a/example/ios/example/AppDelegate.m +++ b/example/ios/example/AppDelegate.m @@ -1,27 +1,47 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - #import "AppDelegate.h" +#import #import #import +#import +#import + +#if DEBUG +#import +#import +#import +#import +#import +#import + +static void InitializeFlipper(UIApplication *application) { + FlipperClient *client = [FlipperClient sharedClient]; + SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; + [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; + [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; + [client addPlugin:[FlipperKitReactPlugin new]]; + [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; + [client start]; +} +#endif @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - NSURL *jsCodeLocation; +#if DEBUG + InitializeFlipper(application); +#endif - jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; + RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; + RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge + moduleName:@"example" + initialProperties:nil]; - RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation - moduleName:@"example" - initialProperties:nil - launchOptions:launchOptions]; + // Define UNUserNotificationCenter + UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; + center.delegate = self; + rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; @@ -32,4 +52,45 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( return YES; } +// Required to register for notifications +- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings +{ + [RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings]; +} +// Required for the register event. +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken +{ + [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; +} +// Required for the notification event. You must call the completion handler after handling the remote notification. +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo +fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler +{ + [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; +} +// Required for the registrationError event. +- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error +{ + [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; +} +// Required for the localNotification event. +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification +{ + [RNCPushNotificationIOS didReceiveLocalNotification:notification]; +} + +//Called when a notification is delivered to a foreground app. +-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler +{ + completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge); +} +- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge +{ +#if DEBUG + return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; +#else + return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; +#endif +} + @end diff --git a/example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json b/example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json index 118c98f74..81213230d 100644 --- a/example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json @@ -2,37 +2,52 @@ "images" : [ { "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" + "scale" : "2x", + "size" : "20x20" }, { "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" + "scale" : "3x", + "size" : "20x20" }, { "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" + "scale" : "2x", + "size" : "29x29" }, { "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" + "scale" : "3x", + "size" : "29x29" }, { "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" + "scale" : "2x", + "size" : "40x40" }, { "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/example/ios/example/Info.plist b/example/ios/example/Info.plist index 44e178a6f..20fb35c96 100644 --- a/example/ios/example/Info.plist +++ b/example/ios/example/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName @@ -24,6 +24,21 @@ 1 LSRequiresIPhoneOS + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + NSLocationWhenInUseUsageDescription + UILaunchStoryboardName LaunchScreen UIRequiredDeviceCapabilities @@ -38,19 +53,5 @@ UIViewControllerBasedStatusBarAppearance - NSLocationWhenInUseUsageDescription - - NSAppTransportSecurity - - - NSExceptionDomains - - localhost - - NSExceptionAllowsInsecureHTTPLoads - - - - diff --git a/example/ios/example/example.entitlements b/example/ios/example/example.entitlements new file mode 100644 index 000000000..903def2af --- /dev/null +++ b/example/ios/example/example.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/example/ios/example/main.m b/example/ios/example/main.m index c73e00625..b1df44b95 100644 --- a/example/ios/example/main.m +++ b/example/ios/example/main.m @@ -1,10 +1,3 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - #import #import "AppDelegate.h" diff --git a/example/ios/exampleTests/Info.plist b/example/ios/exampleTests/Info.plist index 886825ccc..ba72822e8 100644 --- a/example/ios/exampleTests/Info.plist +++ b/example/ios/exampleTests/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/example/ios/exampleTests/exampleTests.m b/example/ios/exampleTests/exampleTests.m index 8c594de06..9809b80c3 100644 --- a/example/ios/exampleTests/exampleTests.m +++ b/example/ios/exampleTests/exampleTests.m @@ -1,10 +1,3 @@ -/** - * Copyright (c) 2015-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - #import #import @@ -12,7 +5,7 @@ #import #define TIMEOUT_SECONDS 600 -#define TEXT_TO_LOOK_FOR @"Welcome to React Native!" +#define TEXT_TO_LOOK_FOR @"Welcome to React" @interface exampleTests : XCTestCase @@ -40,11 +33,13 @@ - (void)testRendersWelcomeScreen BOOL foundElement = NO; __block NSString *redboxError = nil; +#ifdef DEBUG RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { if (level >= RCTLogLevelError) { redboxError = message; } }); +#endif while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; @@ -58,7 +53,9 @@ - (void)testRendersWelcomeScreen }]; } +#ifdef DEBUG RCTSetLogFunction(RCTDefaultLogFunction); +#endif XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); diff --git a/example/ios/sample.mp3 b/example/ios/sample.mp3 new file mode 100644 index 000000000..4569ff11f Binary files /dev/null and b/example/ios/sample.mp3 differ diff --git a/example/metro.config.js b/example/metro.config.js new file mode 100644 index 000000000..13a964217 --- /dev/null +++ b/example/metro.config.js @@ -0,0 +1,17 @@ +/** + * Metro configuration for React Native + * https://github.com/facebook/react-native + * + * @format + */ + +module.exports = { + transformer: { + getTransformOptions: async () => ({ + transform: { + experimentalImportSupport: false, + inlineRequires: false, + }, + }), + }, +}; diff --git a/example/package.json b/example/package.json index 4e90e315d..b01e827fe 100644 --- a/example/package.json +++ b/example/package.json @@ -3,19 +3,27 @@ "version": "0.0.1", "private": true, "scripts": { - "start": "node node_modules/react-native/local-cli/cli.js start", - "test": "jest" + "android": "react-native run-android", + "ios": "react-native run-ios", + "start": "react-native start", + "test": "jest", + "lint": "eslint ." }, "dependencies": { - "react": "16.4.1", - "react-native": "0.56.0", + "@react-native-community/push-notification-ios": "^1.1.1", + "react": "16.11.0", + "react-native": "0.62.2", "react-native-push-notification": "git+https://git@github.com/zo0r/react-native-push-notification.git" }, "devDependencies": { - "babel-jest": "23.4.0", - "babel-preset-react-native": "^5", - "jest": "23.4.1", - "react-test-renderer": "16.4.1" + "@babel/core": "^7.9.0", + "@babel/runtime": "^7.9.2", + "@react-native-community/eslint-config": "^1.0.0", + "babel-jest": "^25.3.0", + "eslint": "^6.8.0", + "jest": "^25.3.0", + "metro-react-native-babel-preset": "^0.59.0", + "react-test-renderer": "16.11.0" }, "jest": { "preset": "react-native" diff --git a/index.js b/index.js index e43141fdb..3dd36a8f9 100644 --- a/index.js +++ b/index.js @@ -18,7 +18,7 @@ var Notifications = { onNotification: false, onRemoteFetch: false, isLoaded: false, - hasPoppedInitialNotification: false, + idInitialNotification: null, isPermissionsRequestPending: false, @@ -29,7 +29,7 @@ var Notifications = { } }; -Notifications.callNative = function(name: String, params: Array) { +Notifications.callNative = function(name, params) { if ( typeof this.handler[name] === 'function' ) { if ( typeof params !== 'array' && typeof params !== 'object' ) { @@ -51,7 +51,7 @@ Notifications.callNative = function(name: String, params: Array) { * @param {Object} options.permissions - Permissions list * @param {Boolean} options.requestPermissions - Check permissions when register */ -Notifications.configure = function(options: Object) { +Notifications.configure = function(options) { if ( typeof options.onRegister !== 'undefined' ) { this.onRegister = options.onRegister; } @@ -68,10 +68,6 @@ Notifications.configure = function(options: Object) { this.permissions = options.permissions; } - if ( typeof options.senderID !== 'undefined' ) { - this.senderID = options.senderID; - } - if ( typeof options.onRemoteFetch !== 'undefined' ) { this.onRemoteFetch = options.onRemoteFetch; } @@ -88,14 +84,17 @@ Notifications.configure = function(options: Object) { this.isLoaded = true; } - if ( this.hasPoppedInitialNotification === false && - ( options.popInitialNotification === undefined || options.popInitialNotification === true ) ) { + if (options.popInitialNotification === undefined || options.popInitialNotification === true) { this.popInitialNotification(function(firstNotification) { if ( firstNotification !== null ) { - this._onNotification(firstNotification, true); + if(this.idInitialNotification === firstNotification.id) { + return; + } + + this.idInitialNotification = firstNotification.id; + this._onNotification(firstNotification, true); } - }.bind(this)); - this.hasPoppedInitialNotification = true; + }.bind(this)); } if ( options.requestPermissions !== false ) { @@ -121,7 +120,7 @@ Notifications.unregister = function() { * @param {String} details.ticker - ANDROID ONLY: The ticker displayed in the status bar. * @param {Object} details.userInfo - iOS ONLY: The userInfo used in the notification alert. */ -Notifications.localNotification = function(details: Object) { +Notifications.localNotification = function(details) { if ( Platform.OS === 'ios' ) { // https://developer.apple.com/reference/uikit/uilocalnotification @@ -131,7 +130,7 @@ Notifications.localNotification = function(details: Object) { soundName = ''; // empty string results in no sound (and no vibration) } - // for valid fields see: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/IPhoneOSClientImp.html + // for valid fields see: https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html // alertTitle only valid for apple watch: https://developer.apple.com/library/ios/documentation/iPhone/Reference/UILocalNotification_Class/#//apple_ref/occ/instp/UILocalNotification/alertTitle this.handler.presentLocalNotification({ @@ -144,6 +143,27 @@ Notifications.localNotification = function(details: Object) { userInfo: details.userInfo }); } else { + if(details && typeof details.id === 'number') { + if(isNaN(details.id)) { + console.warn('NaN value has been passed as id'); + delete details.id; + } + else { + details.id = '' + details.id; + } + } + + if(details && typeof details.number === 'number') { + if(isNaN(details.number)) { + console.warn('NaN value has been passed as number'); + delete details.number; + } + else { + details.number = '' + details.number; + } + } + + this.handler.presentLocalNotification(details); } }; @@ -153,7 +173,7 @@ Notifications.localNotification = function(details: Object) { * @param {Object} details (same as localNotification) * @param {Date} details.date - The date and time when the system should deliver the notification */ -Notifications.localNotificationSchedule = function(details: Object) { +Notifications.localNotificationSchedule = function(details) { if ( Platform.OS === 'ios' ) { let soundName = details.soundName ? details.soundName : 'default'; // play sound (and vibrate) as default behaviour @@ -168,7 +188,8 @@ Notifications.localNotificationSchedule = function(details: Object) { category: details.category, soundName: soundName, userInfo: details.userInfo, - repeatInterval: details.repeatType + repeatInterval: details.repeatType, + category: details.category, }; if(details.number) { @@ -181,6 +202,26 @@ Notifications.localNotificationSchedule = function(details: Object) { } this.handler.scheduleLocalNotification(iosDetails); } else { + if(details && typeof details.id === 'number') { + if(isNaN(details.id)) { + console.warn('NaN value has been passed as id'); + delete details.id; + } + else { + details.id = '' + details.id; + } + } + + if(details && typeof details.number === 'number') { + if(isNaN(details.number)) { + console.warn('NaN value has been passed as number'); + delete details.number; + } + else { + details.number = '' + details.number; + } + } + details.fireDate = details.date.getTime(); delete details.date; // ignore iOS only repeatType @@ -192,7 +233,7 @@ Notifications.localNotificationSchedule = function(details: Object) { }; /* Internal Functions */ -Notifications._onRegister = function(token: String) { +Notifications._onRegister = function(token) { if ( this.onRegister !== false ) { this.onRegister({ token: token, @@ -201,7 +242,7 @@ Notifications._onRegister = function(token: String) { } }; -Notifications._onRemoteFetch = function(notificationData: Object) { +Notifications._onRemoteFetch = function(notificationData) { if ( this.onRemoteFetch !== false ) { this.onRemoteFetch(notificationData) } @@ -261,8 +302,8 @@ Notifications._requestPermissions = function() { .then(this._onPermissionResult.bind(this)) .catch(this._onPermissionResult.bind(this)); } - } else if ( typeof this.senderID !== 'undefined' ) { - return this.callNative( 'requestPermissions', [ this.senderID ]); + } else if (Platform.OS === 'android') { + return this.callNative( 'requestPermissions', []); } }; @@ -270,8 +311,8 @@ Notifications._requestPermissions = function() { Notifications.requestPermissions = function() { if ( Platform.OS === 'ios' ) { return this.callNative( 'requestPermissions', [ this.permissions ]); - } else if ( typeof this.senderID !== 'undefined' ) { - return this.callNative( 'requestPermissions', [ this.senderID ]); + } else if (Platform.OS === 'android') { + return this.callNative( 'requestPermissions', []); } }; @@ -280,6 +321,10 @@ Notifications.subscribeToTopic = function() { return this.callNative('subscribeToTopic', arguments); }; +Notifications.unsubscribeFromTopic = function () { + return this.callNative('unsubscribeFromTopic', arguments); +}; + Notifications.presentLocalNotification = function() { return this.callNative('presentLocalNotification', arguments); }; @@ -314,14 +359,15 @@ Notifications.popInitialNotification = function(handler) { }); }; -Notifications.abandonPermissions = function() { - return this.callNative('abandonPermissions', arguments); -}; - Notifications.checkPermissions = function() { return this.callNative('checkPermissions', arguments); }; +/* Abandon Permissions */ +Notifications.abandonPermissions = function() { + return this.callNative('abandonPermissions', arguments); +} + Notifications.registerNotificationActions = function() { return this.callNative('registerNotificationActions', arguments) } @@ -331,4 +377,16 @@ Notifications.clearAllNotifications = function() { return this.callNative('clearAllNotifications', arguments) } +Notifications.removeAllDeliveredNotifications = function() { + return this.callNative('removeAllDeliveredNotifications', arguments); +} + +Notifications.getDeliveredNotifications = function() { + return this.callNative('getDeliveredNotifications', arguments); +} + +Notifications.removeDeliveredNotifications = function() { + return this.callNative('removeDeliveredNotifications', arguments); +} + module.exports = Notifications; diff --git a/package.json b/package.json index d01be95fd..cc11f1c34 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "react-native-push-notification", - "version": "3.1.7", + "version": "3.5.2", "description": "React Native Local and Remote Notifications", - "main": "index", + "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, @@ -14,7 +14,7 @@ "notifications", "push", "apns", - "gcm" + "firebase" ], "bugs": { "url": "https://github.com/zo0r/react-native-push-notification/issues" @@ -23,6 +23,9 @@ "type": "git", "url": "git+ssh://git@github.com:zo0r/react-native-push-notification.git" }, + "dependencies": { + "@react-native-community/push-notification-ios": "^1.2.0" + }, "peerDependencies": { "react-native": ">=0.33" }, diff --git a/react-native.config.js b/react-native.config.js index 0bf4aa83b..e6ef33c99 100644 --- a/react-native.config.js +++ b/react-native.config.js @@ -1,7 +1,9 @@ module.exports = { - project: { - android: { - "packageInstance": "new ReactNativePushNotificationPackage()" - } + dependency: { + platforms: { + android: { + "packageInstance": "new ReactNativePushNotificationPackage()" + } + } } };