├── .eslintignore ├── examples └── backgroundExample │ ├── .watchmanconfig │ ├── .gitattributes │ ├── app.json │ ├── .eslintrc.js │ ├── babel.config.js │ ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ │ └── mipmap-xxxhdpi │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── backgroundexample │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ └── AndroidManifest.xml │ │ │ └── debug │ │ │ │ └── AndroidManifest.xml │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ ├── build_defs.bzl │ │ ├── BUCK │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ ├── build.gradle │ ├── gradle.properties │ ├── gradlew.bat │ └── gradlew │ ├── ios │ ├── backgroundExample │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── AppDelegate.h │ │ ├── main.m │ │ ├── AppDelegate.m │ │ ├── Info.plist │ │ └── Base.lproj │ │ │ └── LaunchScreen.xib │ ├── backgroundExampleTests │ │ ├── Info.plist │ │ └── backgroundExampleTests.m │ ├── backgroundExample-tvOSTests │ │ └── Info.plist │ ├── backgroundExample-tvOS │ │ └── Info.plist │ ├── Podfile │ ├── backgroundExample.xcodeproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── backgroundExample.xcscheme │ │ │ └── backgroundExample-tvOS.xcscheme │ └── Podfile.lock │ ├── .buckconfig │ ├── .prettierrc.js │ ├── index.js │ ├── .prettierrc │ ├── package.json │ ├── .gitignore │ ├── metro.config.js │ ├── .flowconfig │ └── App.tsx ├── .github ├── FUNDING.yml └── workflows │ ├── main.yml │ └── release.yml ├── babel.config.js ├── lib └── types │ ├── RNBackgroundActionsModule.d.ts │ └── index.d.ts ├── ios ├── RNBackgroundActions.h ├── RNBackgroundActions.m ├── Podfile ├── Podfile.lock └── RNBackgroundActions.xcodeproj │ └── project.pbxproj ├── jest.setup.js ├── .prettierrc ├── src ├── RNBackgroundActionsModule.js └── index.js ├── declaration.tsconfig.json ├── tsconfig.json ├── android ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── asterinet │ │ └── react │ │ └── bgactions │ │ ├── BackgroundActionsPackage.java │ │ ├── BackgroundActionsModule.java │ │ ├── BackgroundTaskOptions.java │ │ └── RNBackgroundActionsTask.java └── build.gradle ├── jest.config.js ├── react-native-background-actions.podspec ├── .releaserc ├── .gitignore ├── .eslintrc.json ├── LICENSE ├── package.json ├── __tests__ └── index.test.js ├── CODE_OF_CONDUCT.md ├── INSTALL.md ├── CHANGELOG.md └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | examples/ 2 | ios/ 3 | android/ -------------------------------------------------------------------------------- /examples/backgroundExample/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /examples/backgroundExample/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [Rapsssito] 4 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /examples/backgroundExample/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backgroundExample", 3 | "displayName": "backgroundExample" 4 | } -------------------------------------------------------------------------------- /examples/backgroundExample/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native-community', 4 | }; 5 | -------------------------------------------------------------------------------- /examples/backgroundExample/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /lib/types/RNBackgroundActionsModule.d.ts: -------------------------------------------------------------------------------- 1 | export const RNBackgroundActions: any; 2 | export const nativeEventEmitter: import("react-native").EventEmitter; 3 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | backgroundExample 3 | 4 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/backgroundExample/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/debug.keystore -------------------------------------------------------------------------------- /examples/backgroundExample/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | bracketSpacing: false, 3 | jsxBracketSameLine: true, 4 | singleQuote: true, 5 | trailingComma: 'all', 6 | }; 7 | -------------------------------------------------------------------------------- /ios/RNBackgroundActions.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface RNBackgroundActions : RCTEventEmitter 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | jest.mock('./src/RNBackgroundActionsModule.js', () => ({ 2 | RNBackgroundActions: { start: jest.fn(), stop: jest.fn(), updateNotification: jest.fn() }, 3 | nativeEventEmitter: { addListener: jest.fn() }, 4 | })); 5 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rapsssito/react-native-background-actions/HEAD/examples/backgroundExample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "semi": true, 4 | "trailingComma": "es5", 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "printWidth": 100, 8 | "jsxBracketSameLine": true, 9 | "arrowParens": "always" 10 | } -------------------------------------------------------------------------------- /examples/backgroundExample/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'backgroundExample' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | -------------------------------------------------------------------------------- /examples/backgroundExample/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /examples/backgroundExample/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 4, 3 | "semi": true, 4 | "trailingComma": "es5", 5 | "singleQuote": true, 6 | "bracketSpacing": true, 7 | "printWidth": 100, 8 | "jsxBracketSameLine": true, 9 | "arrowParens": "always" 10 | } -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build: 10 | name: CI 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - uses: actions/checkout@v1 14 | - name: CI 15 | run: yarn ci 16 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /src/RNBackgroundActionsModule.js: -------------------------------------------------------------------------------- 1 | import { NativeEventEmitter, NativeModules } from 'react-native'; 2 | 3 | const { RNBackgroundActions } = NativeModules; 4 | 5 | const nativeEventEmitter = new NativeEventEmitter(RNBackgroundActions); 6 | 7 | export { RNBackgroundActions, nativeEventEmitter }; 8 | -------------------------------------------------------------------------------- /declaration.tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "noEmit": false, 6 | "emitDeclarationOnly": true, 7 | "outDir": "./lib/types" 8 | }, 9 | "exclude": ["__tests__", "__mocks__"] 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowJs": true, 4 | "checkJs": true, 5 | "noEmit": true, 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "esModuleInterop": true 9 | }, 10 | "include": ["src/index.js", "__tests__/", "__mocks__/"], 11 | } 12 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | collectCoverage: true, 4 | setupFilesAfterEnv: ['jest.setup.js'], 5 | transformIgnorePatterns: [ 6 | 'node_modules/(?!(react-native|react-navigation|@react-navigation|@react-native-community))', 7 | ], 8 | modulePathIgnorePatterns: ['examples/'], 9 | collectCoverageFrom: ['src/index.js'], 10 | globals: { 11 | __DEV__: true, 12 | }, 13 | timers: 'fake', 14 | }; 15 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (nonatomic, strong) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/java/com/backgroundexample/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.backgroundexample; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. This is used to schedule 9 | * rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "backgroundExample"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | workflow_dispatch: 5 | push: 6 | branches: 7 | - master 8 | 9 | jobs: 10 | release: 11 | name: Release 12 | runs-on: ubuntu-22.04 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v1 16 | - name: Setup Node.js 17 | uses: actions/setup-node@v1 18 | with: 19 | node-version: 12 20 | - name: CI 21 | run: yarn ci 22 | - name: Release 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 26 | run: npx semantic-release 27 | -------------------------------------------------------------------------------- /react-native-background-actions.podspec: -------------------------------------------------------------------------------- 1 | require "json" 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, "package.json"))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = package['name'] 7 | s.version = package['version'] 8 | s.summary = package['description'] 9 | s.homepage = package['repository']['url'] 10 | s.license = package['license'] 11 | s.authors = package['author'] 12 | s.platforms = { :ios => "9.0", :tvos => "10.0" } 13 | s.source = { :git => s.homepage, :tag => "#v{s.version}" } 14 | 15 | s.source_files = "ios/*.{h,m,swift}" 16 | s.requires_arc = true 17 | 18 | s.dependency "React-Core" 19 | end 20 | -------------------------------------------------------------------------------- /.releaserc: -------------------------------------------------------------------------------- 1 | { 2 | "branches": ["master"], 3 | "plugins": [ 4 | ["@semantic-release/commit-analyzer", { 5 | "preset": "angular", 6 | "parserOpts": { 7 | "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"] 8 | } 9 | }], 10 | "@semantic-release/release-notes-generator", 11 | "@semantic-release/github", 12 | ["@semantic-release/changelog", { 13 | "changelogFile": "CHANGELOG.md", 14 | }], 15 | "@semantic-release/npm", 16 | ["@semantic-release/git", { 17 | "assets": ["CHANGELOG.md", "package.json", "lib/**/*.{js,d.ts}"], 18 | "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" 19 | }] 20 | ] 21 | } -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | *.xcworkspace 24 | /ios/Pods/ 25 | 26 | # Android/IntelliJ 27 | # 28 | build/ 29 | .idea 30 | .gradle 31 | local.properties 32 | *.iml 33 | android/gradle/ 34 | android/gradlew 35 | android/gradlew.bat 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # BUCK 44 | buck-out/ 45 | \.buckd/ 46 | *.keystore 47 | 48 | # Editor config 49 | .vscode 50 | 51 | # Tests 52 | coverage 53 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | def safeExtGet(prop, fallback) { 4 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 5 | } 6 | 7 | android { 8 | compileSdkVersion safeExtGet('compileSdkVersion', 34) 9 | 10 | defaultConfig { 11 | minSdkVersion safeExtGet('minSdkVersion', 16) 12 | targetSdkVersion safeExtGet('targetSdkVersion', 34) 13 | } 14 | 15 | // Conditional for compatibility with AGP <4.2. 16 | if (project.android.hasProperty("namespace")) { 17 | namespace = "com.asterinet.react.bgactions" 18 | } 19 | } 20 | 21 | dependencies { 22 | //noinspection GradleDynamicVersion 23 | implementation 'com.facebook.react:react-native:+' // From node_modules 24 | } 25 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "prettier", 4 | "jest" 5 | ], 6 | "env": { 7 | "es6": true, 8 | "node": true 9 | }, 10 | "parserOptions": { 11 | "ecmaVersion": 2018, 12 | "sourceType": "module" 13 | }, 14 | "extends": [ 15 | "eslint:recommended", 16 | "prettier", 17 | "plugin:jest/recommended", 18 | "plugin:jest/style" 19 | ], 20 | "rules": { 21 | "prefer-const": ["error", { 22 | "destructuring": "any", 23 | "ignoreReadBeforeAssign": false 24 | }], 25 | "curly": ["error", "multi", "consistent"], 26 | "no-var": "error", 27 | "prefer-template": 2, 28 | "require-atomic-updates": "off", 29 | "prettier/prettier": ["error"] 30 | } 31 | } -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample-tvOSTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/backgroundExample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backgroundExample", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint .", 11 | "pods": "cd ios && pod install" 12 | }, 13 | "dependencies": { 14 | "react": "16.9.0", 15 | "react-native": "0.61.5", 16 | "react-native-background-actions": "link:../../" 17 | }, 18 | "devDependencies": { 19 | "@babel/core": "^7.8.3", 20 | "@babel/runtime": "^7.8.3", 21 | "@react-native-community/eslint-config": "^0.0.6", 22 | "babel-jest": "^24.9.0", 23 | "escape-string-regexp": "^4.0.0", 24 | "eslint": "^6.8.0", 25 | "jest": "^24.9.0", 26 | "metro-react-native-babel-preset": "^0.56.4", 27 | "react-test-renderer": "16.9.0", 28 | "typescript": "^4.2.3" 29 | }, 30 | "jest": { 31 | "preset": "react-native" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /android/src/main/java/com/asterinet/react/bgactions/BackgroundActionsPackage.java: -------------------------------------------------------------------------------- 1 | package com.asterinet.react.bgactions; 2 | 3 | import java.util.Arrays; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | import com.facebook.react.ReactPackage; 8 | import com.facebook.react.bridge.NativeModule; 9 | import com.facebook.react.bridge.ReactApplicationContext; 10 | import com.facebook.react.uimanager.ViewManager; 11 | 12 | import androidx.annotation.NonNull; 13 | 14 | @SuppressWarnings("unused") 15 | public class BackgroundActionsPackage implements ReactPackage { 16 | @Override 17 | public @NonNull List createNativeModules(@NonNull ReactApplicationContext reactContext) { 18 | //noinspection ArraysAsListWithZeroOrOneArgument 19 | return Arrays.asList(new BackgroundActionsModule(reactContext)); 20 | } 21 | 22 | @Override 23 | public @NonNull List createViewManagers(@NonNull ReactApplicationContext reactContext) { 24 | return Collections.emptyList(); 25 | } 26 | } -------------------------------------------------------------------------------- /examples/backgroundExample/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | 24 | # Android/IntelliJ 25 | # 26 | build/ 27 | .idea 28 | .gradle 29 | local.properties 30 | *.iml 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | yarn-error.log 37 | 38 | # BUCK 39 | buck-out/ 40 | \.buckd/ 41 | *.keystore 42 | !debug.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # CocoaPods 59 | /ios/Pods/ 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Rapsssito 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /examples/backgroundExample/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | buildToolsVersion = "28.0.3" 6 | minSdkVersion = 16 7 | compileSdkVersion = 31 8 | targetSdkVersion = 31 9 | } 10 | repositories { 11 | google() 12 | jcenter() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:3.5.3") 16 | // NOTE: Do not place your application dependencies here; they belong 17 | // in the individual module build.gradle files 18 | } 19 | } 20 | 21 | allprojects { 22 | repositories { 23 | mavenLocal() 24 | maven { 25 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 26 | url("$rootDir/../node_modules/react-native/android") 27 | } 28 | maven { 29 | // Android JSC is installed from npm 30 | url("$rootDir/../node_modules/jsc-android/dist") 31 | } 32 | 33 | google() 34 | jcenter() 35 | maven { url 'https://jitpack.io' } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /examples/backgroundExample/metro.config.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const blacklist = require('metro-config/src/defaults/blacklist'); 4 | const escape = require('escape-string-regexp'); 5 | 6 | const root = path.resolve(__dirname, '../..'); 7 | const pak = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8')); 8 | 9 | const modules = [ 10 | '@babel/runtime', 11 | ...Object.keys({ 12 | ...pak.dependencies, 13 | ...pak.peerDependencies, 14 | }), 15 | ]; 16 | 17 | module.exports = { 18 | projectRoot: __dirname, 19 | watchFolders: [root], 20 | resolver: { 21 | blacklistRE: blacklist([new RegExp(`^${escape(path.join(root, 'node_modules'))}\\/.*$`)]), 22 | extraNodeModules: modules.reduce((acc, name) => { 23 | acc[name] = path.join(__dirname, 'node_modules', name); 24 | return acc; 25 | }, {}), 26 | }, 27 | transformer: { 28 | getTransformOptions: async () => ({ 29 | transform: { 30 | experimentalImportSupport: false, 31 | inlineRequires: false, 32 | }, 33 | }), 34 | }, 35 | }; 36 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.37.0 29 | -------------------------------------------------------------------------------- /ios/RNBackgroundActions.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "RNBackgroundActions.h" 3 | 4 | @implementation RNBackgroundActions { 5 | UIBackgroundTaskIdentifier bgTask; 6 | } 7 | 8 | RCT_EXPORT_MODULE() 9 | - (NSArray *)supportedEvents 10 | { 11 | return @[@"expiration"]; 12 | } 13 | 14 | - (void) _start 15 | { 16 | [self _stop]; 17 | bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"RNBackgroundActions" expirationHandler:^{ 18 | [self onExpiration]; 19 | [[UIApplication sharedApplication] endBackgroundTask: self->bgTask]; 20 | self->bgTask = UIBackgroundTaskInvalid; 21 | }]; 22 | } 23 | 24 | - (void) _stop 25 | { 26 | if (bgTask != UIBackgroundTaskInvalid) { 27 | [[UIApplication sharedApplication] endBackgroundTask:bgTask]; 28 | bgTask = UIBackgroundTaskInvalid; 29 | } 30 | } 31 | 32 | - (void)onExpiration 33 | { 34 | [self sendEventWithName:@"expiration" 35 | body:@{}]; 36 | } 37 | 38 | RCT_EXPORT_METHOD(start:(NSDictionary *)options 39 | resolver:(RCTPromiseResolveBlock)resolve 40 | rejecter:(RCTPromiseRejectBlock)reject) 41 | { 42 | [self _start]; 43 | resolve(nil); 44 | } 45 | 46 | RCT_EXPORT_METHOD(stop:(RCTPromiseResolveBlock)resolve 47 | rejecter:(RCTPromiseRejectBlock)reject) 48 | { 49 | [self _stop]; 50 | resolve(nil); 51 | } 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.backgroundexample", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.backgroundexample", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import "AppDelegate.h" 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; 19 | RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge 20 | moduleName:@"backgroundExample" 21 | initialProperties:nil]; 22 | 23 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 24 | 25 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 26 | UIViewController *rootViewController = [UIViewController new]; 27 | rootViewController.view = rootView; 28 | self.window.rootViewController = rootViewController; 29 | [self.window makeKeyAndVisible]; 30 | return YES; 31 | } 32 | 33 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 34 | { 35 | #if DEBUG 36 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; 37 | #else 38 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 39 | #endif 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample-tvOS/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSExceptionDomains 28 | 29 | localhost 30 | 31 | NSExceptionAllowsInsecureHTTPLoads 32 | 33 | 34 | 35 | 36 | NSLocationWhenInUseUsageDescription 37 | 38 | UILaunchStoryboardName 39 | LaunchScreen 40 | UIRequiredDeviceCapabilities 41 | 42 | armv7 43 | 44 | UISupportedInterfaceOrientations 45 | 46 | UIInterfaceOrientationPortrait 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | UIViewControllerBasedStatusBarAppearance 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | backgroundExample 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSAllowsArbitraryLoads 30 | 31 | NSExceptionDomains 32 | 33 | localhost 34 | 35 | NSExceptionAllowsInsecureHTTPLoads 36 | 37 | 38 | 39 | 40 | NSLocationWhenInUseUsageDescription 41 | 42 | UIBackgroundModes 43 | 44 | processing 45 | 46 | UILaunchStoryboardName 47 | LaunchScreen 48 | UIRequiredDeviceCapabilities 49 | 50 | armv7 51 | 52 | UISupportedInterfaceOrientations 53 | 54 | UIInterfaceOrientationPortrait 55 | UIInterfaceOrientationLandscapeLeft 56 | UIInterfaceOrientationLandscapeRight 57 | 58 | UIViewControllerBasedStatusBarAppearance 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExampleTests/backgroundExampleTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #import 9 | #import 10 | 11 | #import 12 | #import 13 | 14 | #define TIMEOUT_SECONDS 600 15 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 16 | 17 | @interface backgroundExampleTests : XCTestCase 18 | 19 | @end 20 | 21 | @implementation backgroundExampleTests 22 | 23 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 24 | { 25 | if (test(view)) { 26 | return YES; 27 | } 28 | for (UIView *subview in [view subviews]) { 29 | if ([self findSubviewInView:subview matching:test]) { 30 | return YES; 31 | } 32 | } 33 | return NO; 34 | } 35 | 36 | - (void)testRendersWelcomeScreen 37 | { 38 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 39 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 40 | BOOL foundElement = NO; 41 | 42 | __block NSString *redboxError = nil; 43 | #ifdef DEBUG 44 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 45 | if (level >= RCTLogLevelError) { 46 | redboxError = message; 47 | } 48 | }); 49 | #endif 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | #ifdef DEBUG 64 | RCTSetLogFunction(RCTDefaultLogFunction); 65 | #endif 66 | 67 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 68 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 69 | } 70 | 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-background-actions", 3 | "version": "4.0.1", 4 | "description": "React Native background service library for running background tasks forever in Android & iOS", 5 | "keywords": [ 6 | "react-native", 7 | "background", 8 | "service", 9 | "task", 10 | "android", 11 | "ios" 12 | ], 13 | "files": [ 14 | "/android/src/", 15 | "/android/build.gradle", 16 | "/ios", 17 | "!Podfile*", 18 | "/windows", 19 | "/src", 20 | "/lib", 21 | "/*.podspec", 22 | "/jest" 23 | ], 24 | "types": "lib/types/index.d.ts", 25 | "main": "src/index.js", 26 | "scripts": { 27 | "ci": "yarn install --frozen-lockfile && yarn lint && yarn declaration:build && yarn checkjs && yarn test", 28 | "lint": "eslint .", 29 | "checkjs": "tsc", 30 | "eslint:fix": "yarn eslint --fix", 31 | "test": "jest ./__tests__/", 32 | "declaration:build": "tsc -p ./declaration.tsconfig.json", 33 | "prepublishOnly": "yarn declaration:build && yarn checkjs", 34 | "pods": "cd ios && pod install" 35 | }, 36 | "repository": { 37 | "type": "git", 38 | "url": "https://github.com/Rapsssito/react-native-background-actions.git" 39 | }, 40 | "funding": { 41 | "type": "individual", 42 | "url": "https://github.com/sponsors/Rapsssito" 43 | }, 44 | "author": { 45 | "name": "Rapsssito", 46 | "email": "contact@rodrigomartin.dev" 47 | }, 48 | "license": "MIT", 49 | "licenseFilename": "LICENSE", 50 | "peerDependencies": { 51 | "react-native": ">=0.47.0" 52 | }, 53 | "devDependencies": { 54 | "@babel/core": "^7.8.3", 55 | "@semantic-release/changelog": "^5.0.0", 56 | "@semantic-release/git": "^9.0.0", 57 | "@semantic-release/github": "^7.0.0", 58 | "@semantic-release/npm": "^7.0.0", 59 | "@types/jest": "^25.1.3", 60 | "@types/react-native": "^0.61.17", 61 | "babel-jest": "^24.9.0", 62 | "eslint": "^6.6.0", 63 | "eslint-config-prettier": "^6.5.0", 64 | "eslint-plugin-jest": "^23.6.0", 65 | "eslint-plugin-prettier": "^3.1.1", 66 | "jest": "^24.9.0", 67 | "metro-react-native-babel-preset": "^0.56.4", 68 | "prettier": "^1.18.2", 69 | "react": "16.9.0", 70 | "react-native": "^0.61.4", 71 | "semantic-release": "^17.0.1", 72 | "typescript": "4.0.3" 73 | }, 74 | "dependencies": { 75 | "eventemitter3": "^4.0.7" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /examples/backgroundExample/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore polyfills 9 | node_modules/react-native/Libraries/polyfills/.* 10 | 11 | ; These should not be required directly 12 | ; require from fbjs/lib instead: require('fbjs/lib/warning') 13 | node_modules/warning/.* 14 | 15 | ; Flow doesn't support platforms 16 | .*/Libraries/Utilities/LoadingView.js 17 | 18 | [untyped] 19 | .*/node_modules/@react-native-community/cli/.*/.* 20 | 21 | [include] 22 | 23 | [libs] 24 | node_modules/react-native/Libraries/react-native/react-native-interface.js 25 | node_modules/react-native/flow/ 26 | 27 | [options] 28 | emoji=true 29 | 30 | esproposal.optional_chaining=enable 31 | esproposal.nullish_coalescing=enable 32 | 33 | module.file_ext=.js 34 | module.file_ext=.json 35 | module.file_ext=.ios.js 36 | 37 | munge_underscores=true 38 | 39 | module.name_mapper='^react-native$' -> '/node_modules/react-native/Libraries/react-native/react-native-implementation' 40 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1' 41 | 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' 42 | 43 | suppress_type=$FlowIssue 44 | suppress_type=$FlowFixMe 45 | suppress_type=$FlowFixMeProps 46 | suppress_type=$FlowFixMeState 47 | 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\) 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+ 50 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 51 | 52 | [lints] 53 | sketchy-null-number=warn 54 | sketchy-null-mixed=warn 55 | sketchy-number=warn 56 | untyped-type-import=warn 57 | nonstrict-import=warn 58 | deprecated-type=warn 59 | unsafe-getters-setters=warn 60 | inexact-spread=warn 61 | unnecessary-invariant=warn 62 | signature-verification-failure=warn 63 | deprecated-utility=error 64 | 65 | [strict] 66 | deprecated-type 67 | nonstrict-import 68 | sketchy-null 69 | unclear-type 70 | unsafe-getters-setters 71 | untyped-import 72 | untyped-type-import 73 | 74 | [version] 75 | ^0.105.0 76 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/src/main/java/com/backgroundexample/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.backgroundexample; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | import com.facebook.react.PackageList; 6 | import com.facebook.react.ReactApplication; 7 | import com.facebook.react.ReactNativeHost; 8 | import com.facebook.react.ReactPackage; 9 | import com.facebook.soloader.SoLoader; 10 | import java.lang.reflect.InvocationTargetException; 11 | import java.util.List; 12 | 13 | public class MainApplication extends Application implements ReactApplication { 14 | 15 | private final ReactNativeHost mReactNativeHost = 16 | new ReactNativeHost(this) { 17 | @Override 18 | public boolean getUseDeveloperSupport() { 19 | return BuildConfig.DEBUG; 20 | } 21 | 22 | @Override 23 | protected List getPackages() { 24 | @SuppressWarnings("UnnecessaryLocalVariable") 25 | List packages = new PackageList(this).getPackages(); 26 | // Packages that cannot be autolinked yet can be added manually here, for example: 27 | // packages.add(new MyReactNativePackage()); 28 | return packages; 29 | } 30 | 31 | @Override 32 | protected String getJSMainModuleName() { 33 | return "index"; 34 | } 35 | }; 36 | 37 | @Override 38 | public ReactNativeHost getReactNativeHost() { 39 | return mReactNativeHost; 40 | } 41 | 42 | @Override 43 | public void onCreate() { 44 | super.onCreate(); 45 | SoLoader.init(this, /* native exopackage */ false); 46 | initializeFlipper(this); // Remove this line if you don't want Flipper enabled 47 | } 48 | 49 | /** 50 | * Loads Flipper in React Native templates. 51 | * 52 | * @param context 53 | */ 54 | private static void initializeFlipper(Context context) { 55 | if (BuildConfig.DEBUG) { 56 | try { 57 | /* 58 | We use reflection here to pick up the class that initializes Flipper, 59 | since Flipper library is not available in release mode 60 | */ 61 | Class aClass = Class.forName("com.facebook.flipper.ReactNativeFlipper"); 62 | aClass.getMethod("initializeFlipper", Context.class).invoke(null, context); 63 | } catch (ClassNotFoundException e) { 64 | e.printStackTrace(); 65 | } catch (NoSuchMethodException e) { 66 | e.printStackTrace(); 67 | } catch (IllegalAccessException e) { 68 | e.printStackTrace(); 69 | } catch (InvocationTargetException e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '9.0' 3 | 4 | target 'RNBackgroundActions' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Necessary for react-native 9 | pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" 10 | pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" 11 | pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" 12 | pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" 13 | pod 'React', :path => '../node_modules/react-native/' 14 | pod 'React-Core', :path => '../node_modules/react-native/' 15 | pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' 16 | pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' 17 | pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' 18 | pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' 19 | pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' 20 | pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' 21 | pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' 22 | pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' 23 | pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' 24 | pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' 25 | pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' 26 | pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' 27 | 28 | pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' 29 | pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' 30 | pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' 31 | pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' 32 | pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" 33 | pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" 34 | pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' 35 | 36 | pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' 37 | pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' 38 | pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' 39 | end 40 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '9.0' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | target 'backgroundExample' do 5 | # Pods for backgroundExample 6 | pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" 7 | pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" 8 | pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" 9 | pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" 10 | pod 'React', :path => '../node_modules/react-native/' 11 | pod 'React-Core', :path => '../node_modules/react-native/' 12 | pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' 13 | pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' 14 | pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' 15 | pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' 16 | pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' 17 | pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' 18 | pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' 19 | pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' 20 | pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' 21 | pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' 22 | pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' 23 | pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' 24 | 25 | pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' 26 | pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' 27 | pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' 28 | pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' 29 | pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" 30 | pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" 31 | pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' 32 | 33 | pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' 34 | pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' 35 | pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' 36 | 37 | target 'backgroundExampleTests' do 38 | inherit! :search_paths 39 | # Pods for testing 40 | end 41 | 42 | use_native_modules! 43 | end 44 | 45 | target 'backgroundExample-tvOS' do 46 | # Pods for backgroundExample-tvOS 47 | 48 | target 'backgroundExample-tvOSTests' do 49 | inherit! :search_paths 50 | # Pods for testing 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | @rem Execute Gradle 88 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 89 | 90 | :end 91 | @rem End local scope for the variables with windows NT shell 92 | if "%ERRORLEVEL%"=="0" goto mainEnd 93 | 94 | :fail 95 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 96 | rem the _cmd.exe /c_ return code! 97 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 98 | exit /b 1 99 | 100 | :mainEnd 101 | if "%OS%"=="Windows_NT" endlocal 102 | 103 | :omega 104 | -------------------------------------------------------------------------------- /android/src/main/java/com/asterinet/react/bgactions/BackgroundActionsModule.java: -------------------------------------------------------------------------------- 1 | package com.asterinet.react.bgactions; 2 | 3 | import android.app.Notification; 4 | import android.app.NotificationManager; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | 8 | import androidx.annotation.NonNull; 9 | 10 | import com.facebook.react.bridge.Promise; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.bridge.ReactContext; 13 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 14 | import com.facebook.react.bridge.ReactMethod; 15 | import com.facebook.react.bridge.ReadableMap; 16 | 17 | @SuppressWarnings("WeakerAccess") 18 | public class BackgroundActionsModule extends ReactContextBaseJavaModule { 19 | 20 | private static final String TAG = "RNBackgroundActions"; 21 | 22 | private final ReactContext reactContext; 23 | 24 | private Intent currentServiceIntent; 25 | 26 | public BackgroundActionsModule(ReactApplicationContext reactContext) { 27 | super(reactContext); 28 | this.reactContext = reactContext; 29 | } 30 | 31 | @NonNull 32 | @Override 33 | public String getName() { 34 | return TAG; 35 | } 36 | 37 | @SuppressWarnings("unused") 38 | @ReactMethod 39 | public void start(@NonNull final ReadableMap options, @NonNull final Promise promise) { 40 | try { 41 | // Stop any other intent 42 | if (currentServiceIntent != null) reactContext.stopService(currentServiceIntent); 43 | // Create the service 44 | currentServiceIntent = new Intent(reactContext, RNBackgroundActionsTask.class); 45 | // Get the task info from the options 46 | final BackgroundTaskOptions bgOptions = new BackgroundTaskOptions(reactContext, options); 47 | currentServiceIntent.putExtras(bgOptions.getExtras()); 48 | // Start the task 49 | reactContext.startService(currentServiceIntent); 50 | promise.resolve(null); 51 | } catch (Exception e) { 52 | promise.reject(e); 53 | } 54 | } 55 | 56 | @SuppressWarnings("unused") 57 | @ReactMethod 58 | public void stop(@NonNull final Promise promise) { 59 | if (currentServiceIntent != null) 60 | reactContext.stopService(currentServiceIntent); 61 | promise.resolve(null); 62 | } 63 | 64 | @SuppressWarnings("unused") 65 | @ReactMethod 66 | public void updateNotification(@NonNull final ReadableMap options, @NonNull final Promise promise) { 67 | // Get the task info from the options 68 | try { 69 | final BackgroundTaskOptions bgOptions = new BackgroundTaskOptions(reactContext, options); 70 | final Notification notification = RNBackgroundActionsTask.buildNotification(reactContext, bgOptions); 71 | final NotificationManager notificationManager = (NotificationManager) reactContext.getSystemService(Context.NOTIFICATION_SERVICE); 72 | notificationManager.notify(RNBackgroundActionsTask.SERVICE_NOTIFICATION_ID, notification); 73 | } catch (Exception e) { 74 | promise.reject(e); 75 | return; 76 | } 77 | promise.resolve(null); 78 | } 79 | 80 | @SuppressWarnings("unused") 81 | @ReactMethod 82 | public void addListener(String eventName) { 83 | // Keep: Required for RN built in Event Emitter Calls. 84 | } 85 | 86 | @SuppressWarnings("unused") 87 | @ReactMethod 88 | public void removeListeners(Integer count) { 89 | // Keep: Required for RN built in Event Emitter Calls. 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java: -------------------------------------------------------------------------------- 1 | package com.asterinet.react.bgactions; 2 | 3 | import android.graphics.Color; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.ColorInt; 7 | import androidx.annotation.IdRes; 8 | import androidx.annotation.NonNull; 9 | import androidx.annotation.Nullable; 10 | 11 | import com.facebook.react.bridge.Arguments; 12 | import com.facebook.react.bridge.ReactContext; 13 | import com.facebook.react.bridge.ReadableMap; 14 | 15 | public final class BackgroundTaskOptions { 16 | private final Bundle extras; 17 | 18 | public BackgroundTaskOptions(@NonNull final Bundle extras) { 19 | this.extras = extras; 20 | } 21 | 22 | public BackgroundTaskOptions(@NonNull final ReactContext reactContext, @NonNull final ReadableMap options) { 23 | // Create extras 24 | extras = Arguments.toBundle(options); 25 | if (extras == null) 26 | throw new IllegalArgumentException("Could not convert arguments to bundle"); 27 | // Get taskTitle 28 | try { 29 | if (options.getString("taskTitle") == null) 30 | throw new IllegalArgumentException(); 31 | } catch (Exception e) { 32 | throw new IllegalArgumentException("Task title cannot be null"); 33 | } 34 | // Get taskDesc 35 | try { 36 | if (options.getString("taskDesc") == null) 37 | throw new IllegalArgumentException(); 38 | } catch (Exception e) { 39 | throw new IllegalArgumentException("Task description cannot be null"); 40 | } 41 | // Get iconInt 42 | try { 43 | final ReadableMap iconMap = options.getMap("taskIcon"); 44 | if (iconMap == null) 45 | throw new IllegalArgumentException(); 46 | final String iconName = iconMap.getString("name"); 47 | final String iconType = iconMap.getString("type"); 48 | String iconPackage; 49 | try { 50 | iconPackage = iconMap.getString("package"); 51 | if (iconPackage == null) 52 | throw new IllegalArgumentException(); 53 | } catch (Exception e) { 54 | // Get the current package as default 55 | iconPackage = reactContext.getPackageName(); 56 | } 57 | final int iconInt = reactContext.getResources().getIdentifier(iconName, iconType, iconPackage); 58 | extras.putInt("iconInt", iconInt); 59 | if (iconInt == 0) 60 | throw new IllegalArgumentException(); 61 | } catch (Exception e) { 62 | throw new IllegalArgumentException("Task icon not found"); 63 | } 64 | // Get color 65 | try { 66 | final String color = options.getString("color"); 67 | extras.putInt("color", Color.parseColor(color)); 68 | } catch (Exception e) { 69 | extras.putInt("color", Color.parseColor("#ffffff")); 70 | } 71 | } 72 | 73 | public Bundle getExtras() { 74 | return extras; 75 | } 76 | 77 | public String getTaskTitle() { 78 | return extras.getString("taskTitle", ""); 79 | } 80 | 81 | public String getTaskDesc() { 82 | return extras.getString("taskDesc", ""); 83 | } 84 | 85 | @IdRes 86 | public int getIconInt() { 87 | return extras.getInt("iconInt"); 88 | } 89 | 90 | @ColorInt 91 | public int getColor() { 92 | return extras.getInt("color"); 93 | } 94 | 95 | @Nullable 96 | public String getLinkingURI() { 97 | return extras.getString("linkingURI"); 98 | } 99 | 100 | @Nullable 101 | public Bundle getProgressBar() { 102 | return extras.getBundle("progressBar"); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /examples/backgroundExample/App.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * 5 | * @format 6 | * @flow 7 | */ 8 | 9 | import React from 'react'; 10 | import { 11 | SafeAreaView, 12 | StyleSheet, 13 | ScrollView, 14 | View, 15 | Text, 16 | StatusBar, 17 | TouchableOpacity, 18 | Platform, 19 | Linking, 20 | } from 'react-native'; 21 | import { Header, Colors } from 'react-native/Libraries/NewAppScreen'; 22 | 23 | import BackgroundJob from 'react-native-background-actions'; 24 | 25 | const sleep = (time: any) => new Promise((resolve) => setTimeout(() => resolve(), time)); 26 | 27 | BackgroundJob.on('expiration', () => { 28 | console.log('iOS: I am being closed!'); 29 | }); 30 | 31 | const taskRandom = async (taskData: any) => { 32 | if (Platform.OS === 'ios') { 33 | console.warn( 34 | 'This task will not keep your app alive in the background by itself, use other library like react-native-track-player that use audio,', 35 | 'geolocalization, etc. to keep your app alive in the background while you excute the JS from this library.' 36 | ); 37 | } 38 | await new Promise(async (resolve) => { 39 | // For loop with a delay 40 | const { delay } = taskData; 41 | console.log(BackgroundJob.isRunning(), delay) 42 | for (let i = 0; BackgroundJob.isRunning(); i++) { 43 | console.log('Runned -> ', i); 44 | await BackgroundJob.updateNotification({ taskDesc: 'Runned -> ' + i }); 45 | await sleep(delay); 46 | } 47 | }); 48 | }; 49 | 50 | const options = { 51 | taskName: 'Example', 52 | taskTitle: 'ExampleTask title', 53 | taskDesc: 'ExampleTask desc', 54 | taskIcon: { 55 | name: 'ic_launcher', 56 | type: 'mipmap', 57 | }, 58 | color: '#ff00ff', 59 | linkingURI: 'exampleScheme://chat/jane', 60 | parameters: { 61 | delay: 1000, 62 | }, 63 | }; 64 | 65 | function handleOpenURL(evt: any) { 66 | console.log(evt.url); 67 | // do something with the url 68 | } 69 | 70 | Linking.addEventListener('url', handleOpenURL); 71 | 72 | 73 | 74 | 75 | export default App = () => { 76 | const usingHermes = typeof HermesInternal === 'object' && HermesInternal !== null; 77 | 78 | let playing = BackgroundJob.isRunning(); 79 | 80 | /** 81 | * Toggles the background task 82 | */ 83 | const toggleBackground = async () => { 84 | playing = !playing; 85 | if (playing) { 86 | try { 87 | console.log('Trying to start background service'); 88 | await BackgroundJob.start(taskRandom, options); 89 | console.log('Successful start!'); 90 | } catch (e) { 91 | console.log('Error', e); 92 | } 93 | } else { 94 | console.log('Stop background service'); 95 | await BackgroundJob.stop(); 96 | } 97 | }; 98 | return ( 99 | <> 100 | 101 | 102 | 105 |
106 | {!usingHermes ? null : ( 107 | 108 | Engine: Hermes 109 | 110 | )} 111 | 112 | 115 | 116 | 117 | 118 | 119 | ); 120 | } 121 | 122 | const styles = StyleSheet.create({ 123 | scrollView: { 124 | backgroundColor: Colors.lighter, 125 | }, 126 | engine: { 127 | position: 'absolute', 128 | right: 0, 129 | }, 130 | body: { 131 | backgroundColor: Colors.white, 132 | }, 133 | footer: { 134 | color: Colors.dark, 135 | fontSize: 12, 136 | fontWeight: '600', 137 | padding: 4, 138 | paddingRight: 12, 139 | textAlign: 'right', 140 | }, 141 | }); 142 | -------------------------------------------------------------------------------- /lib/types/index.d.ts: -------------------------------------------------------------------------------- 1 | export default backgroundServer; 2 | export type BackgroundTaskOptions = { 3 | taskName: string; 4 | taskTitle: string; 5 | taskDesc: string; 6 | taskIcon: { 7 | name: string; 8 | type: string; 9 | package?: string; 10 | }; 11 | color?: string | undefined; 12 | linkingURI?: string | undefined; 13 | progressBar?: { 14 | max: number; 15 | value: number; 16 | indeterminate?: boolean | undefined; 17 | } | undefined; 18 | }; 19 | declare const backgroundServer: BackgroundServer; 20 | /** 21 | * @typedef {{taskName: string, 22 | * taskTitle: string, 23 | * taskDesc: string, 24 | * taskIcon: {name: string, type: string, package?: string}, 25 | * color?: string 26 | * linkingURI?: string, 27 | * progressBar?: {max: number, value: number, indeterminate?: boolean} 28 | * }} BackgroundTaskOptions 29 | * @extends EventEmitter<'expiration',any> 30 | */ 31 | declare class BackgroundServer extends EventEmitter<"expiration", any> { 32 | /** @private */ 33 | private _runnedTasks; 34 | /** @private @type {(arg0?: any) => void} */ 35 | private _stopTask; 36 | /** @private */ 37 | private _isRunning; 38 | /** @private @type {BackgroundTaskOptions} */ 39 | private _currentOptions; 40 | /** 41 | * @private 42 | */ 43 | private _addListeners; 44 | /** 45 | * **ANDROID ONLY** 46 | * 47 | * Updates the task notification. 48 | * 49 | * *On iOS this method will return immediately* 50 | * 51 | * @param {{taskTitle?: string, 52 | * taskDesc?: string, 53 | * taskIcon?: {name: string, type: string, package?: string}, 54 | * color?: string, 55 | * linkingURI?: string, 56 | * progressBar?: {max: number, value: number, indeterminate?: boolean}}} taskData 57 | */ 58 | updateNotification(taskData: { 59 | taskTitle?: string; 60 | taskDesc?: string; 61 | taskIcon?: { 62 | name: string; 63 | type: string; 64 | package?: string; 65 | }; 66 | color?: string; 67 | linkingURI?: string; 68 | progressBar?: { 69 | max: number; 70 | value: number; 71 | indeterminate?: boolean; 72 | }; 73 | }): Promise; 74 | /** 75 | * Returns if the current background task is running. 76 | * 77 | * It returns `true` if `start()` has been called and the task has not finished. 78 | * 79 | * It returns `false` if `stop()` has been called, **even if the task has not finished**. 80 | */ 81 | isRunning(): boolean; 82 | /** 83 | * @template T 84 | * 85 | * @param {(taskData?: T) => Promise} task 86 | * @param {BackgroundTaskOptions & {parameters?: T}} options 87 | * @returns {Promise} 88 | */ 89 | start(task: (taskData?: T | undefined) => Promise, options: { 90 | taskName: string; 91 | taskTitle: string; 92 | taskDesc: string; 93 | taskIcon: { 94 | name: string; 95 | type: string; 96 | package?: string; 97 | }; 98 | color?: string | undefined; 99 | linkingURI?: string | undefined; 100 | progressBar?: { 101 | max: number; 102 | value: number; 103 | indeterminate?: boolean | undefined; 104 | } | undefined; 105 | } & { 106 | parameters?: T | undefined; 107 | }): Promise; 108 | /** 109 | * @private 110 | * @template T 111 | * @param {(taskData?: T) => Promise} task 112 | * @param {T} [parameters] 113 | */ 114 | private _generateTask; 115 | /** 116 | * @private 117 | * @param {BackgroundTaskOptions} options 118 | */ 119 | private _normalizeOptions; 120 | /** 121 | * Stops the background task. 122 | * 123 | * @returns {Promise} 124 | */ 125 | stop(): Promise; 126 | } 127 | import EventEmitter from "eventemitter3"; 128 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { Platform, AppRegistry } from 'react-native'; 2 | import { RNBackgroundActions, nativeEventEmitter } from './RNBackgroundActionsModule'; 3 | import EventEmitter from 'eventemitter3'; 4 | 5 | /** 6 | * @typedef {{taskName: string, 7 | * taskTitle: string, 8 | * taskDesc: string, 9 | * taskIcon: {name: string, type: string, package?: string}, 10 | * color?: string 11 | * linkingURI?: string, 12 | * progressBar?: {max: number, value: number, indeterminate?: boolean} 13 | * }} BackgroundTaskOptions 14 | * @extends EventEmitter<'expiration',any> 15 | */ 16 | class BackgroundServer extends EventEmitter { 17 | constructor() { 18 | super(); 19 | /** @private */ 20 | this._runnedTasks = 0; 21 | /** @private @type {(arg0?: any) => void} */ 22 | this._stopTask = () => {}; 23 | /** @private */ 24 | this._isRunning = false; 25 | /** @private @type {BackgroundTaskOptions} */ 26 | this._currentOptions; 27 | this._addListeners(); 28 | } 29 | 30 | /** 31 | * @private 32 | */ 33 | _addListeners() { 34 | nativeEventEmitter.addListener('expiration', () => this.emit('expiration')); 35 | } 36 | 37 | /** 38 | * **ANDROID ONLY** 39 | * 40 | * Updates the task notification. 41 | * 42 | * *On iOS this method will return immediately* 43 | * 44 | * @param {{taskTitle?: string, 45 | * taskDesc?: string, 46 | * taskIcon?: {name: string, type: string, package?: string}, 47 | * color?: string, 48 | * linkingURI?: string, 49 | * progressBar?: {max: number, value: number, indeterminate?: boolean}}} taskData 50 | */ 51 | async updateNotification(taskData) { 52 | if (Platform.OS !== 'android') return; 53 | if (!this.isRunning()) 54 | throw new Error('A BackgroundAction must be running before updating the notification'); 55 | this._currentOptions = this._normalizeOptions({ ...this._currentOptions, ...taskData }); 56 | await RNBackgroundActions.updateNotification(this._currentOptions); 57 | } 58 | 59 | /** 60 | * Returns if the current background task is running. 61 | * 62 | * It returns `true` if `start()` has been called and the task has not finished. 63 | * 64 | * It returns `false` if `stop()` has been called, **even if the task has not finished**. 65 | */ 66 | isRunning() { 67 | return this._isRunning; 68 | } 69 | 70 | /** 71 | * @template T 72 | * 73 | * @param {(taskData?: T) => Promise} task 74 | * @param {BackgroundTaskOptions & {parameters?: T}} options 75 | * @returns {Promise} 76 | */ 77 | async start(task, options) { 78 | this._runnedTasks++; 79 | this._currentOptions = this._normalizeOptions(options); 80 | const finalTask = this._generateTask(task, options.parameters); 81 | if (Platform.OS === 'android') { 82 | AppRegistry.registerHeadlessTask(this._currentOptions.taskName, () => finalTask); 83 | await RNBackgroundActions.start(this._currentOptions); 84 | this._isRunning = true; 85 | } else { 86 | await RNBackgroundActions.start(this._currentOptions); 87 | this._isRunning = true; 88 | finalTask(); 89 | } 90 | } 91 | 92 | /** 93 | * @private 94 | * @template T 95 | * @param {(taskData?: T) => Promise} task 96 | * @param {T} [parameters] 97 | */ 98 | _generateTask(task, parameters) { 99 | const self = this; 100 | return async () => { 101 | await new Promise((resolve) => { 102 | self._stopTask = resolve; 103 | task(parameters).then(() => self.stop()); 104 | }); 105 | }; 106 | } 107 | 108 | /** 109 | * @private 110 | * @param {BackgroundTaskOptions} options 111 | */ 112 | _normalizeOptions(options) { 113 | return { 114 | taskName: options.taskName + this._runnedTasks, 115 | taskTitle: options.taskTitle, 116 | taskDesc: options.taskDesc, 117 | taskIcon: { ...options.taskIcon }, 118 | color: options.color || '#ffffff', 119 | linkingURI: options.linkingURI, 120 | progressBar: options.progressBar, 121 | }; 122 | } 123 | 124 | /** 125 | * Stops the background task. 126 | * 127 | * @returns {Promise} 128 | */ 129 | async stop() { 130 | this._stopTask(); 131 | await RNBackgroundActions.stop(); 132 | this._isRunning = false; 133 | } 134 | } 135 | 136 | const backgroundServer = new BackgroundServer(); 137 | 138 | export default backgroundServer; 139 | -------------------------------------------------------------------------------- /android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java: -------------------------------------------------------------------------------- 1 | package com.asterinet.react.bgactions; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.app.Notification; 5 | import android.app.NotificationChannel; 6 | import android.app.NotificationManager; 7 | import android.app.PendingIntent; 8 | import android.content.Context; 9 | import android.content.Intent; 10 | import android.net.Uri; 11 | import android.os.Build; 12 | import android.os.Bundle; 13 | 14 | import androidx.annotation.NonNull; 15 | import androidx.annotation.Nullable; 16 | import androidx.core.app.NotificationCompat; 17 | 18 | import com.facebook.react.HeadlessJsTaskService; 19 | import com.facebook.react.bridge.Arguments; 20 | import com.facebook.react.jstasks.HeadlessJsTaskConfig; 21 | 22 | final public class RNBackgroundActionsTask extends HeadlessJsTaskService { 23 | 24 | public static final int SERVICE_NOTIFICATION_ID = 92901; 25 | private static final String CHANNEL_ID = "RN_BACKGROUND_ACTIONS_CHANNEL"; 26 | 27 | @SuppressLint("UnspecifiedImmutableFlag") 28 | @NonNull 29 | public static Notification buildNotification(@NonNull Context context, @NonNull final BackgroundTaskOptions bgOptions) { 30 | // Get info 31 | final String taskTitle = bgOptions.getTaskTitle(); 32 | final String taskDesc = bgOptions.getTaskDesc(); 33 | final int iconInt = bgOptions.getIconInt(); 34 | final int color = bgOptions.getColor(); 35 | final String linkingURI = bgOptions.getLinkingURI(); 36 | Intent notificationIntent; 37 | if (linkingURI != null) { 38 | notificationIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(linkingURI)); 39 | } else { 40 | //as RN works on single activity architecture - we don't need to find current activity on behalf of react context 41 | notificationIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER); 42 | } 43 | final PendingIntent contentIntent; 44 | if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { 45 | contentIntent = PendingIntent.getActivity(context,0, notificationIntent, PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT); 46 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 47 | contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_MUTABLE); 48 | } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 49 | contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); 50 | } else { 51 | contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); 52 | } 53 | final NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID) 54 | .setContentTitle(taskTitle) 55 | .setContentText(taskDesc) 56 | .setSmallIcon(iconInt) 57 | .setContentIntent(contentIntent) 58 | .setOngoing(true) 59 | .setPriority(NotificationCompat.PRIORITY_MIN) 60 | .setColor(color); 61 | 62 | final Bundle progressBarBundle = bgOptions.getProgressBar(); 63 | if (progressBarBundle != null) { 64 | final int progressMax = (int) Math.floor(progressBarBundle.getDouble("max")); 65 | final int progressCurrent = (int) Math.floor(progressBarBundle.getDouble("value")); 66 | final boolean progressIndeterminate = progressBarBundle.getBoolean("indeterminate"); 67 | builder.setProgress(progressMax, progressCurrent, progressIndeterminate); 68 | } 69 | return builder.build(); 70 | } 71 | 72 | @Override 73 | protected @Nullable 74 | HeadlessJsTaskConfig getTaskConfig(Intent intent) { 75 | final Bundle extras = intent.getExtras(); 76 | if (extras != null) { 77 | return new HeadlessJsTaskConfig(extras.getString("taskName"), Arguments.fromBundle(extras), 0, true); 78 | } 79 | return null; 80 | } 81 | 82 | @Override 83 | public int onStartCommand(Intent intent, int flags, int startId) { 84 | final Bundle extras = intent.getExtras(); 85 | if (extras == null) { 86 | throw new IllegalArgumentException("Extras cannot be null"); 87 | } 88 | final BackgroundTaskOptions bgOptions = new BackgroundTaskOptions(extras); 89 | createNotificationChannel(bgOptions.getTaskTitle(), bgOptions.getTaskDesc()); // Necessary creating channel for API 26+ 90 | // Create the notification 91 | final Notification notification = buildNotification(this, bgOptions); 92 | 93 | startForeground(SERVICE_NOTIFICATION_ID, notification); 94 | return super.onStartCommand(intent, flags, startId); 95 | } 96 | 97 | private void createNotificationChannel(@NonNull final String taskTitle, @NonNull final String taskDesc) { 98 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 99 | final int importance = NotificationManager.IMPORTANCE_LOW; 100 | final NotificationChannel channel = new NotificationChannel(CHANNEL_ID, taskTitle, importance); 101 | channel.setDescription(taskDesc); 102 | final NotificationManager notificationManager = getSystemService(NotificationManager.class); 103 | notificationManager.createNotificationChannel(channel); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /__tests__/index.test.js: -------------------------------------------------------------------------------- 1 | import { Platform, AppRegistry } from 'react-native'; 2 | import BackgroundActions from '../src/index'; 3 | import { 4 | RNBackgroundActions as RNBackgroundActionsModule, 5 | nativeEventEmitter, 6 | } from '../src/RNBackgroundActionsModule'; 7 | 8 | // @ts-ignore 9 | const mockedEventEmitter = /** @type {{ addListener: jest.Mock }} */ (nativeEventEmitter); 10 | 11 | // Flush promises 12 | const flushPromises = () => new Promise(setImmediate); 13 | 14 | Platform.OS = 'android'; 15 | 16 | // @ts-ignore 17 | AppRegistry.registerHeadlessTask = jest.fn(async (taskName, task) => task()()); 18 | 19 | const defaultOptions = { 20 | taskName: 'Example', 21 | taskTitle: 'ExampleTask title', 22 | taskDesc: 'ExampleTask desc', 23 | taskIcon: { 24 | name: 'ic_launcher', 25 | type: 'mipmap', 26 | }, 27 | parameters: { 28 | delay: 1000, 29 | }, 30 | }; 31 | 32 | test('stop-empty', async () => { 33 | expect(BackgroundActions.isRunning()).toBe(false); 34 | RNBackgroundActionsModule.stop.mockClear(); 35 | await BackgroundActions.stop(); 36 | expect(RNBackgroundActionsModule.stop).toHaveBeenCalledTimes(1); 37 | expect(BackgroundActions.isRunning()).toBe(false); 38 | }); 39 | 40 | test('start-android', async () => { 41 | let promiseFinish = () => {}; 42 | const defaultTask = jest.fn( 43 | // @ts-ignore 44 | async () => await new Promise((resolve) => (promiseFinish = resolve)) 45 | ); 46 | Platform.OS = 'android'; 47 | // @ts-ignore 48 | AppRegistry.registerHeadlessTask.mockClear(); 49 | RNBackgroundActionsModule.start.mockClear(); 50 | await BackgroundActions.start(defaultTask, defaultOptions); 51 | expect(defaultTask).toHaveBeenCalledTimes(1); 52 | expect(defaultTask).toHaveBeenCalledWith(defaultOptions.parameters); 53 | expect(AppRegistry.registerHeadlessTask).toHaveBeenCalledTimes(1); 54 | expect(RNBackgroundActionsModule.start).toHaveBeenCalledTimes(1); 55 | expect(BackgroundActions.isRunning()).toBe(true); 56 | promiseFinish(); 57 | await flushPromises(); 58 | expect(BackgroundActions.isRunning()).toBe(false); 59 | }); 60 | 61 | test('start-ios', async () => { 62 | let promiseFinish = () => {}; 63 | const defaultTask = jest.fn( 64 | // @ts-ignore 65 | async () => await new Promise((resolve) => (promiseFinish = resolve)) 66 | ); 67 | // @ts-ignore 68 | AppRegistry.registerHeadlessTask.mockClear(); 69 | Platform.OS = 'ios'; 70 | RNBackgroundActionsModule.start.mockClear(); 71 | await BackgroundActions.start(defaultTask, defaultOptions); 72 | expect(defaultTask).toHaveBeenCalledTimes(1); 73 | expect(defaultTask).toHaveBeenCalledWith(defaultOptions.parameters); 74 | expect(AppRegistry.registerHeadlessTask).toHaveBeenCalledTimes(0); 75 | expect(RNBackgroundActionsModule.start).toHaveBeenCalledTimes(1); 76 | expect(BackgroundActions.isRunning()).toBe(true); 77 | promiseFinish(); 78 | await flushPromises(); 79 | expect(BackgroundActions.isRunning()).toBe(false); 80 | }); 81 | 82 | test('stop', async () => { 83 | let promiseFinish = () => {}; 84 | const defaultTask = jest.fn( 85 | // @ts-ignore 86 | async () => await new Promise((resolve) => (promiseFinish = resolve)) 87 | ); 88 | await BackgroundActions.start(defaultTask, defaultOptions); 89 | RNBackgroundActionsModule.stop.mockClear(); 90 | await BackgroundActions.stop(); 91 | expect(RNBackgroundActionsModule.stop).toHaveBeenCalledTimes(1); 92 | expect(BackgroundActions.isRunning()).toBe(false); 93 | promiseFinish(); // Clear the promise 94 | }); 95 | 96 | test('updateNotification-ios', async () => { 97 | Platform.OS = 'ios'; 98 | let promiseFinish = () => {}; 99 | const defaultTask = jest.fn( 100 | // @ts-ignore 101 | async () => await new Promise((resolve) => (promiseFinish = resolve)) 102 | ); 103 | await BackgroundActions.start(defaultTask, defaultOptions); 104 | RNBackgroundActionsModule.updateNotification.mockClear(); 105 | await BackgroundActions.updateNotification({ taskDesc: 'New Desc' }); 106 | expect(RNBackgroundActionsModule.updateNotification).toHaveBeenCalledTimes(0); 107 | promiseFinish(); // Clear the promise 108 | }); 109 | 110 | test('updateNotification-android', async () => { 111 | Platform.OS = 'android'; 112 | let promiseFinish = () => {}; 113 | const defaultTask = jest.fn( 114 | // @ts-ignore 115 | async () => await new Promise((resolve) => (promiseFinish = resolve)) 116 | ); 117 | await BackgroundActions.start(defaultTask, defaultOptions); 118 | RNBackgroundActionsModule.updateNotification.mockClear(); 119 | const updatedOptions = { taskDesc: 'New Desc' }; 120 | await BackgroundActions.updateNotification(updatedOptions); 121 | expect(RNBackgroundActionsModule.updateNotification).toHaveBeenCalledTimes(1); 122 | const newOptions = RNBackgroundActionsModule.updateNotification.mock.calls[0][0]; 123 | expect(newOptions.taskDesc).toBe(updatedOptions.taskDesc); 124 | promiseFinish(); // Clear the promise 125 | }); 126 | 127 | test('updateNotification-android-notRunning', async () => { 128 | Platform.OS = 'android'; 129 | const updatedOptions = { taskDesc: 'New Desc' }; 130 | await expect(BackgroundActions.updateNotification(updatedOptions)).rejects.toBeDefined(); 131 | }); 132 | 133 | test('expiration-event', () => { 134 | Platform.OS = 'ios'; 135 | return new Promise((done) => { 136 | BackgroundActions.on('expiration', done); 137 | mockedEventEmitter.addListener.mock.calls[0][1](); 138 | }); 139 | }); 140 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample.xcodeproj/xcshareddata/xcschemes/backgroundExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | contact@rodrigomartin.dev. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/backgroundExample.xcodeproj/xcshareddata/xcschemes/backgroundExample-tvOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | 58 | 59 | 61 | 67 | 68 | 69 | 70 | 71 | 77 | 78 | 79 | 80 | 81 | 82 | 92 | 94 | 100 | 101 | 102 | 103 | 104 | 105 | 111 | 113 | 119 | 120 | 121 | 122 | 124 | 125 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /INSTALL.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | ## Install 6 | - [Getting started](#getting-started) 7 | - [Compatibility](#react-native-compatibility) 8 | - [Linking](#linking) 9 | 10 | ### Getting started 11 | Install the library using either Yarn: 12 | 13 | ``` 14 | yarn add react-native-background-actions 15 | ``` 16 | 17 | or npm: 18 | 19 | ``` 20 | npm install --save react-native-background-actions 21 | ``` 22 | 23 | ### React Native Compatibility 24 | To use this library you need to ensure you are using the correct version of React Native. If you are using a version of React Native that is lower than `0.47` you will need to upgrade before attempting to use this library latest version. 25 | 26 | ### Linking 27 | 28 | #### Using React Native >= 0.60 29 | Linking the package manually is not required anymore with [Autolinking](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md). 30 | 31 | - **iOS Platform:** 32 | 33 | `$ cd ios && pod install && cd ..` # CocoaPods on iOS needs this extra step 34 | 35 | The background support requires you to activate the background capability in Xcode. 36 | screenBack 37 | 38 | To support submitting the app to the App store you need to add the following to your `Info.plist`: 39 | 40 | ```xml 41 | BGTaskSchedulerPermittedIdentifiers 42 | 43 | $(PRODUCT_BUNDLE_IDENTIFIER) 44 | 45 | ``` 46 | 47 | - **Android Platform:** 48 | 49 | Modify your **`android/app/src/main/AndroidManifest.xml`** and add the following: 50 | ```xml 51 | 52 | ... 53 | 54 | 55 | ... 56 | 57 | ``` 58 | 59 | Android 14+ requires the [`foregroundServiceType`](https://developer.android.com/about/versions/14/changes/fgs-types-required) must be set in your service tag: 60 | ```xml 61 | 62 | ... 63 | 66 | 67 | ... 68 | 72 | ... 73 | 74 | ... 75 | 76 | ``` 77 | > **Important Notes**: 78 | > - Service Tag for General Background Tasks: 79 | > - The example above works for general background tasks that require data synchronization. 80 | > - Changing `foregroundServiceType` for Specific Functions: 81 | > - Depending on your use case, you may need to change the `foregroundServiceType` value. For example, for background location services, use `android:foregroundServiceType="location"` instead of `android:foregroundServiceType="dataSync"`. Add the following permissions to your AndroidManifest.xml: 82 | > - `android.permission.FOREGROUND_SERVICE_LOCATION` 83 | > - `android.permission.ACCESS_COARSE_LOCATION` 84 | > - `android.permission.ACCESS_FINE_LOCATION` 85 | > - Additional Permissions: 86 | > - Some foregroundServiceType values may need additional permissions. For more information, refer to the [Android Documentation](https://developer.android.com/about/versions/14/changes/fgs-types-required). 87 | > - Ensuring Compliance: 88 | > - By setting the `foregroundServiceType` relevant to your use case, you ensure that your foreground services comply with the latest Android 14 requirements, allowing your application to function properly and meet the required security standards. 89 | #### Using React Native < 0.60 90 | 91 | You then need to link the native parts of the library for the platforms you are using. The easiest way to link the library is using the CLI tool by running this command from the root of your project: 92 | 93 | `$ react-native link react-native-background-actions` 94 | 95 | If you can't or don't want to use the CLI tool, you can also manually link the library using the instructions below (click on the arrow to show them): 96 | 97 |
98 | Manually link the library on iOS 99 | 100 | 1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]` 101 | 2. Go to `node_modules` ➜ `react-native-background-actions` and add `RNBackgroundActions.xcodeproj` 102 | 3. In XCode, in the project navigator, select your project. Add `libRNBackgroundActions.a` to your project's `Build Phases` ➜ `Link Binary With Libraries` 103 | 4. Run your project (`Cmd+R`)< 104 |
105 | 106 |
107 | Manually link the library on Android 108 | 109 | 1. Open up `android/app/src/main/java/[...]/MainApplication.java` 110 | - Add `import com.asterinet.react.bgactions.BackgroundActionsPackage;` to the imports at the top of the file 111 | - Add `new BackgroundActionsPackage()` to the list returned by the `getPackages()` method 112 | 2. Append the following lines to `android/settings.gradle`: 113 | ``` 114 | include ':react-native-background-actions' 115 | project(':react-native-background-actions').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-background-actions/android') 116 | ``` 117 | 3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: 118 | ``` 119 | compile project(':react-native-background-actions') 120 | ``` 121 |
122 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin or MSYS, switch paths to Windows format before running java 129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=`expr $i + 1` 158 | done 159 | case $i in 160 | 0) set -- ;; 161 | 1) set -- "$args0" ;; 162 | 2) set -- "$args0" "$args1" ;; 163 | 3) set -- "$args0" "$args1" "$args2" ;; 164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=`save "$@"` 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | exec "$JAVACMD" "$@" 184 | -------------------------------------------------------------------------------- /examples/backgroundExample/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format 22 | * bundleCommand: "ram-bundle", 23 | * 24 | * // whether to bundle JS and assets in debug mode 25 | * bundleInDebug: false, 26 | * 27 | * // whether to bundle JS and assets in release mode 28 | * bundleInRelease: true, 29 | * 30 | * // whether to bundle JS and assets in another build variant (if configured). 31 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 32 | * // The configuration property can be in the following formats 33 | * // 'bundleIn${productFlavor}${buildType}' 34 | * // 'bundleIn${buildType}' 35 | * // bundleInFreeDebug: true, 36 | * // bundleInPaidRelease: true, 37 | * // bundleInBeta: true, 38 | * 39 | * // whether to disable dev mode in custom build variants (by default only disabled in release) 40 | * // for example: to disable dev mode in the staging build type (if configured) 41 | * devDisabledInStaging: true, 42 | * // The configuration property can be in the following formats 43 | * // 'devDisabledIn${productFlavor}${buildType}' 44 | * // 'devDisabledIn${buildType}' 45 | * 46 | * // the root of your project, i.e. where "package.json" lives 47 | * root: "../../", 48 | * 49 | * // where to put the JS bundle asset in debug mode 50 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 51 | * 52 | * // where to put the JS bundle asset in release mode 53 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 54 | * 55 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 56 | * // require('./image.png')), in debug mode 57 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 58 | * 59 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 60 | * // require('./image.png')), in release mode 61 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 62 | * 63 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 64 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 65 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 66 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 67 | * // for example, you might want to remove it from here. 68 | * inputExcludes: ["android/**", "ios/**"], 69 | * 70 | * // override which node gets called and with what additional arguments 71 | * nodeExecutableAndArgs: ["node"], 72 | * 73 | * // supply additional arguments to the packager 74 | * extraPackagerArgs: [] 75 | * ] 76 | */ 77 | 78 | project.ext.react = [ 79 | entryFile: "index.js", 80 | enableHermes: false, // clean and rebuild if changing 81 | ] 82 | 83 | apply from: "../../node_modules/react-native/react.gradle" 84 | 85 | /** 86 | * Set this to true to create two separate APKs instead of one: 87 | * - An APK that only works on ARM devices 88 | * - An APK that only works on x86 devices 89 | * The advantage is the size of the APK is reduced by about 4MB. 90 | * Upload all the APKs to the Play Store and people will download 91 | * the correct one based on the CPU architecture of their device. 92 | */ 93 | def enableSeparateBuildPerCPUArchitecture = false 94 | 95 | /** 96 | * Run Proguard to shrink the Java bytecode in release builds. 97 | */ 98 | def enableProguardInReleaseBuilds = false 99 | 100 | /** 101 | * The preferred build flavor of JavaScriptCore. 102 | * 103 | * For example, to use the international variant, you can use: 104 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 105 | * 106 | * The international variant includes ICU i18n library and necessary data 107 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 108 | * give correct results when using with locales other than en-US. Note that 109 | * this variant is about 6MiB larger per architecture than default. 110 | */ 111 | def jscFlavor = 'org.webkit:android-jsc:+' 112 | 113 | /** 114 | * Whether to enable the Hermes VM. 115 | * 116 | * This should be set on project.ext.react and mirrored here. If it is not set 117 | * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode 118 | * and the benefits of using Hermes will therefore be sharply reduced. 119 | */ 120 | def enableHermes = project.ext.react.get("enableHermes", false); 121 | 122 | android { 123 | compileSdkVersion rootProject.ext.compileSdkVersion 124 | 125 | compileOptions { 126 | sourceCompatibility JavaVersion.VERSION_1_8 127 | targetCompatibility JavaVersion.VERSION_1_8 128 | } 129 | 130 | defaultConfig { 131 | applicationId "com.backgroundexample" 132 | minSdkVersion rootProject.ext.minSdkVersion 133 | targetSdkVersion rootProject.ext.targetSdkVersion 134 | versionCode 1 135 | versionName "1.0" 136 | } 137 | splits { 138 | abi { 139 | reset() 140 | enable enableSeparateBuildPerCPUArchitecture 141 | universalApk false // If true, also generate a universal APK 142 | include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" 143 | } 144 | } 145 | signingConfigs { 146 | debug { 147 | storeFile file('debug.keystore') 148 | storePassword 'android' 149 | keyAlias 'androiddebugkey' 150 | keyPassword 'android' 151 | } 152 | } 153 | buildTypes { 154 | debug { 155 | signingConfig signingConfigs.debug 156 | } 157 | release { 158 | // Caution! In production, you need to generate your own keystore file. 159 | // see https://facebook.github.io/react-native/docs/signed-apk-android. 160 | signingConfig signingConfigs.debug 161 | minifyEnabled enableProguardInReleaseBuilds 162 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 163 | } 164 | } 165 | // applicationVariants are e.g. debug, release 166 | applicationVariants.all { variant -> 167 | variant.outputs.each { output -> 168 | // For each separate APK per architecture, set a unique version code as described here: 169 | // https://developer.android.com/studio/build/configure-apk-splits.html 170 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] 171 | def abi = output.getFilter(OutputFile.ABI) 172 | if (abi != null) { // null for the universal-debug, universal-release variants 173 | output.versionCodeOverride = 174 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 175 | } 176 | 177 | } 178 | } 179 | } 180 | 181 | dependencies { 182 | implementation fileTree(dir: "libs", include: ["*.jar"]) 183 | implementation "com.facebook.react:react-native:+" // From node_modules 184 | 185 | if (enableHermes) { 186 | def hermesPath = "../../node_modules/hermes-engine/android/"; 187 | debugImplementation files(hermesPath + "hermes-debug.aar") 188 | releaseImplementation files(hermesPath + "hermes-release.aar") 189 | } else { 190 | implementation jscFlavor 191 | } 192 | } 193 | 194 | // Run this once to be able to run the application with BUCK 195 | // puts all compile dependencies into folder libs for BUCK to use 196 | task copyDownloadableDepsToLibs(type: Copy) { 197 | from configurations.compile 198 | into 'libs' 199 | } 200 | 201 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 202 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [4.0.1](https://github.com/Rapsssito/react-native-background-actions/compare/v4.0.0...v4.0.1) (2024-07-09) 2 | 3 | 4 | ### Bug Fixes 5 | 6 | * **Android:** Fix RN 0.73 namespace requirement ([#229](https://github.com/Rapsssito/react-native-background-actions/issues/229)) ([d6f3135](https://github.com/Rapsssito/react-native-background-actions/commit/d6f31351ed745980d2d036d4d5c1c55884cea8d5)) 7 | 8 | # [4.0.0](https://github.com/Rapsssito/react-native-background-actions/compare/v3.0.1...v4.0.0) (2024-06-17) 9 | 10 | 11 | ### Bug Fixes 12 | 13 | * **Android:** Fix Android 14 crash with implicit intent ([#208](https://github.com/Rapsssito/react-native-background-actions/issues/208)) ([d30165f](https://github.com/Rapsssito/react-native-background-actions/commit/d30165fca1a1acb5837a7fd00361ff17f9169827)) 14 | 15 | 16 | ### BREAKING CHANGES 17 | 18 | * **Android:** `targetSdkVersion` is now required to be 34+ for Android users. 19 | 20 | ## [3.0.1](https://github.com/Rapsssito/react-native-background-actions/compare/v3.0.0...v3.0.1) (2023-10-11) 21 | 22 | 23 | ### Bug Fixes 24 | 25 | * **Android:** Register background service in package AndroidManifest.xml ([#184](https://github.com/Rapsssito/react-native-background-actions/issues/184)) ([32e9d20](https://github.com/Rapsssito/react-native-background-actions/commit/32e9d2063d4bbae6c675f700f7690a09d9d2b656)) 26 | 27 | # [3.0.0](https://github.com/Rapsssito/react-native-background-actions/compare/v2.6.7...v3.0.0) (2022-12-21) 28 | 29 | 30 | ### Bug Fixes 31 | 32 | * **Android:** Fix crash when targeting SDK 31+ ([#165](https://github.com/Rapsssito/react-native-background-actions/issues/165)) ([c70554e](https://github.com/Rapsssito/react-native-background-actions/commit/c70554e974366e658746953e2d49867a9278e41b)) 33 | 34 | 35 | ### BREAKING CHANGES 36 | 37 | * **Android:** `targetSdkVersion` is now required to be 31+ for Android users. 38 | 39 | ## [2.6.7](https://github.com/Rapsssito/react-native-background-actions/compare/v2.6.6...v2.6.7) (2022-04-25) 40 | 41 | 42 | ### Bug Fixes 43 | 44 | * **Android:** Revert [#124](https://github.com/Rapsssito/react-native-background-actions/issues/124) ([#127](https://github.com/Rapsssito/react-native-background-actions/issues/127)) ([ba3bf29](https://github.com/Rapsssito/react-native-background-actions/commit/ba3bf2946d8f9ec880be53161faa581fb8466e7f)), closes [#126](https://github.com/Rapsssito/react-native-background-actions/issues/126) 45 | 46 | ## [2.6.6](https://github.com/Rapsssito/react-native-background-actions/compare/v2.6.5...v2.6.6) (2022-03-22) 47 | 48 | 49 | ### Bug Fixes 50 | 51 | * Fix creation of multiple tasks ([#124](https://github.com/Rapsssito/react-native-background-actions/issues/124)) ([df268bd](https://github.com/Rapsssito/react-native-background-actions/commit/df268bd024c876b3d8499690417db341706bf5ec)) 52 | 53 | ## [2.6.5](https://github.com/Rapsssito/react-native-background-actions/compare/v2.6.4...v2.6.5) (2021-10-15) 54 | 55 | 56 | ### Bug Fixes 57 | 58 | * **Android:** Add RN 0.65 event emitter stubs ([83d4621](https://github.com/Rapsssito/react-native-background-actions/commit/83d4621f97d870fdde2229cf8bdc5803b0a891ea)), closes [#103](https://github.com/Rapsssito/react-native-background-actions/issues/103) 59 | 60 | ## [2.6.4](https://github.com/Rapsssito/react-native-background-actions/compare/v2.6.3...v2.6.4) (2021-10-04) 61 | 62 | 63 | ### Bug Fixes 64 | 65 | * **Android:** Fix Gradle 7 and Android S compatibility ([e7452ba](https://github.com/Rapsssito/react-native-background-actions/commit/e7452ba881ef01859bdd926186b8ff4d115d1ada)), closes [#88](https://github.com/Rapsssito/react-native-background-actions/issues/88) [#87](https://github.com/Rapsssito/react-native-background-actions/issues/87) 66 | 67 | ## [2.6.2](https://github.com/Rapsssito/react-native-background-actions/compare/v2.6.1...v2.6.2) (2021-06-30) 68 | 69 | 70 | ### Bug Fixes 71 | 72 | * Fix IllegalStateException "Not allowed to start service Intent" ([1ba26c7](https://github.com/Rapsssito/react-native-background-actions/commit/1ba26c710f8044bd94ee6b3b90f53787cabf24b0)) 73 | 74 | ## [2.6.1](https://github.com/Rapsssito/react-native-background-actions/compare/v2.6.0...v2.6.1) (2021-06-09) 75 | 76 | 77 | ### Bug Fixes 78 | 79 | * Fix [#61](https://github.com/Rapsssito/react-native-background-actions/issues/61) when React context was null ([2efefaa](https://github.com/Rapsssito/react-native-background-actions/commit/2efefaa20ec601e4822bd83574594a55a85dc96e)) 80 | 81 | # [2.6.0](https://github.com/Rapsssito/react-native-background-actions/compare/v2.5.3...v2.6.0) (2021-03-14) 82 | 83 | 84 | ### Features 85 | 86 | * **iOS:** Add 'expiration' event ([#74](https://github.com/Rapsssito/react-native-background-actions/issues/74)) ([4b820ee](https://github.com/Rapsssito/react-native-background-actions/commit/4b820ee276cd8c6bba3604d69b37c85a7341a718)) 87 | 88 | ## [2.5.3](https://github.com/Rapsssito/react-native-background-actions/compare/v2.5.2...v2.5.3) (2021-02-26) 89 | 90 | 91 | ### Bug Fixes 92 | 93 | * Fix podspec version ([e41bb0e](https://github.com/Rapsssito/react-native-background-actions/commit/e41bb0e0f1fca864a46ccd77737e4ea69f1bb366)) 94 | 95 | ## [2.5.2](https://github.com/Rapsssito/react-native-background-actions/compare/v2.5.1...v2.5.2) (2020-10-25) 96 | 97 | 98 | ### Bug Fixes 99 | 100 | * Upgrade TypeScript declaration ([#53](https://github.com/Rapsssito/react-native-background-actions/issues/53)) ([c74ade7](https://github.com/Rapsssito/react-native-background-actions/commit/c74ade7eee3bac80a95a8c1fc223f2bdf1c48afa)) 101 | 102 | ## [2.5.1](https://github.com/Rapsssito/react-native-background-actions/compare/v2.5.0...v2.5.1) (2020-10-01) 103 | 104 | 105 | ### Bug Fixes 106 | 107 | * Fix Xcode 12 compatibility ([e80bc0e](https://github.com/Rapsssito/react-native-background-actions/commit/e80bc0e3a3721315bd1f44de2dfb2edac60f7138)), closes [facebook/react-native#29633](https://github.com/facebook/react-native/issues/29633) 108 | 109 | # [2.5.0](https://github.com/Rapsssito/react-native-background-actions/compare/v2.4.0...v2.5.0) (2020-09-06) 110 | 111 | 112 | ### Features 113 | 114 | * **Android:** Add progress bar to notification ([#41](https://github.com/Rapsssito/react-native-background-actions/issues/41)) ([2ed041d](https://github.com/Rapsssito/react-native-background-actions/commit/2ed041dfb9d2b9a5419c5dd8330899b1e0123ac3)) 115 | 116 | # [2.4.0](https://github.com/Rapsssito/react-native-background-actions/compare/v2.3.0...v2.4.0) (2020-09-04) 117 | 118 | 119 | ### Features 120 | 121 | * **Android:** Add deep linking support when clicking on notification ([#40](https://github.com/Rapsssito/react-native-background-actions/issues/40)) ([c0849e3](https://github.com/Rapsssito/react-native-background-actions/commit/c0849e3ec31c0f6c8ceb43df7730ed84e2b4c17d)) 122 | 123 | # [2.3.0](https://github.com/Rapsssito/react-native-background-actions/compare/v2.2.0...v2.3.0) (2020-09-02) 124 | 125 | 126 | ### Features 127 | 128 | * **Android:** Add updateNotification() method ([#37](https://github.com/Rapsssito/react-native-background-actions/issues/37)) ([7582ed7](https://github.com/Rapsssito/react-native-background-actions/commit/7582ed7141c9d65b08038cbe5f7946413027b8b9)) 129 | 130 | # [2.2.0](https://github.com/Rapsssito/react-native-background-actions/compare/v2.1.0...v2.2.0) (2020-02-24) 131 | 132 | 133 | ### Features 134 | 135 | * Add TypeScript declaration files ([#15](https://github.com/Rapsssito/react-native-background-actions/issues/15)) ([1c9f9b1](https://github.com/Rapsssito/react-native-background-actions/commit/1c9f9b133e80a741a13c6c2d1bbc524907a6ee72)) 136 | 137 | # [2.1.0](https://github.com/Rapsssito/react-native-background-actions/compare/v2.0.0...v2.1.0) (2020-02-20) 138 | 139 | 140 | ### Features 141 | 142 | * Know the task's state with isRunning() method ([#13](https://github.com/Rapsssito/react-native-background-actions/issues/13)) ([d3954dd](https://github.com/Rapsssito/react-native-background-actions/commit/d3954dd3504973b19ed386d10ca2a31174375b20)) 143 | 144 | # [2.0.0](https://github.com/Rapsssito/react-native-background-actions/compare/v1.1.0...v2.0.0) (2020-02-20) 145 | 146 | 147 | ### Features 148 | 149 | * Allow non-serializable parameters ([#12](https://github.com/Rapsssito/react-native-background-actions/issues/12)) ([e3ccbbe](https://github.com/Rapsssito/react-native-background-actions/commit/e3ccbbe7e3f3be819ff0952271e95f3cf4e1dff7)) 150 | 151 | 152 | ### BREAKING CHANGES 153 | 154 | * This breaks compatibility with the old parameters handling 155 | 156 | # [1.2.0](https://github.com/Rapsssito/react-native-background-actions/compare/v1.1.0...v1.2.0) (2020-02-20) 157 | 158 | 159 | ### Features 160 | 161 | * Allow non-serializable parameters ([#12](https://github.com/Rapsssito/react-native-background-actions/issues/12)) ([9addd1e](https://github.com/Rapsssito/react-native-background-actions/commit/9addd1e80be4f16ef7b7efc1ab9c4784fcec6ec8)) 162 | 163 | # [1.1.0](https://github.com/Rapsssito/react-native-background-actions/compare/v1.0.4...v1.1.0) (2020-01-30) 164 | 165 | 166 | ### Features 167 | 168 | * **Android:** Set notification color ([3f7fb1a](https://github.com/Rapsssito/react-native-background-actions/commit/3f7fb1ae994de0070ca4c3fd81a9783133c1e840)) 169 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | 6 | 7 |

8 | 9 | React Native background service library for running **background tasks forever in Android & iOS**. Schedule a background job that will run your JavaScript when your app is in the background or foreground. 10 | 11 | ### WARNING 12 | - **Android**: This library relies on React Native's [`HeadlessJS`](https://facebook.github.io/react-native/docs/headless-js-android) for Android. Before building your JS task, make sure to read all the [documentation](https://facebook.github.io/react-native/docs/headless-js-android). The jobs will run even if the app has been closed. [In Android 12+](https://developer.android.com/guide/components/foreground-services#background-start-restrictions) you will not be able to launch background tasks from the background. A notification will be shown when the task is running, it is not possible to start the service without it. The notification will only be visible in Android. 13 | 14 | - **iOS**: This library relies on iOS's [`UIApplication beginBackgroundTaskWithName` method](https://developer.apple.com/documentation/uikit/uiapplication/1623051-beginbackgroundtaskwithname?language=objc), which **won't keep your app in the background forever** by itself. However, you can rely on other libraries like [`react-native-track-player`](https://github.com/react-native-kit/react-native-track-player) that use audio, geolocalization, etc. to keep your app alive in the background while you excute the JS from this library. 15 | 16 | 17 | ## Table of Contents 18 | 19 | - [React Native / Android / iOS compatibility](#react-native--android--ios-compatibility) 20 | - [Install](#install) 21 | - [Usage](#usage) 22 | - [Example Code](#example-code) 23 | - [Options](#options) 24 | - [taskIconOptions](#taskiconoptions) 25 | - [taskProgressBarOptions](#taskprogressbaroptions) 26 | - [Deep Linking](#deep-linking) 27 | - [Events](#events) 28 | - ['expiration'](#expiration) 29 | - [Maintainers](#maintainers) 30 | - [Acknowledgments](#acknowledgments) 31 | - [License](#license) 32 | 33 | ## React Native / Android / iOS compatibility 34 | To use this module you need to ensure you are using the correct version of React Native. If you are using an Android (targetSdkVersion) version lower than 31 (introduced in React Native 0.68.0) you will need to upgrade before attempting to use `react-native-background-actions`'s latest version. 35 | 36 | | Version | React Native version | Android (targetSdkVersion) version | iOS version | 37 | | ------- | -------------------- | ---------------------------------- | ------------ | 38 | | `4.X.X` | `>= Unknown` | `>= 34` | `>= Unknown` | 39 | | `3.X.X` | `>= Unknown` | `>= 31` | `>= Unknown` | 40 | | `2.6.7` | `>= Unknown` | `>= Unknown` | `>= Unknown` | 41 | 42 | ## Install 43 | 44 | Go to [INSTALL.md](./INSTALL.md) to see the how to install, compatibility with RN and Linking process. 45 | 46 | ## Usage 47 | 48 | ### Example Code 49 | 50 | ```js 51 | import BackgroundService from 'react-native-background-actions'; 52 | 53 | const sleep = (time) => new Promise((resolve) => setTimeout(() => resolve(), time)); 54 | 55 | // You can do anything in your task such as network requests, timers and so on, 56 | // as long as it doesn't touch UI. Once your task completes (i.e. the promise is resolved), 57 | // React Native will go into "paused" mode (unless there are other tasks running, 58 | // or there is a foreground app). 59 | const veryIntensiveTask = async (taskDataArguments) => { 60 | // Example of an infinite loop task 61 | const { delay } = taskDataArguments; 62 | await new Promise( async (resolve) => { 63 | for (let i = 0; BackgroundService.isRunning(); i++) { 64 | console.log(i); 65 | await sleep(delay); 66 | } 67 | }); 68 | }; 69 | 70 | const options = { 71 | taskName: 'Example', 72 | taskTitle: 'ExampleTask title', 73 | taskDesc: 'ExampleTask description', 74 | taskIcon: { 75 | name: 'ic_launcher', 76 | type: 'mipmap', 77 | }, 78 | color: '#ff00ff', 79 | linkingURI: 'yourSchemeHere://chat/jane', // See Deep Linking for more info 80 | parameters: { 81 | delay: 1000, 82 | }, 83 | }; 84 | 85 | 86 | await BackgroundService.start(veryIntensiveTask, options); 87 | await BackgroundService.updateNotification({taskDesc: 'New ExampleTask description'}); // Only Android, iOS will ignore this call 88 | // iOS will also run everything here in the background until .stop() is called 89 | await BackgroundService.stop(); 90 | ``` 91 | > If you call stop() on background no new tasks will be able to be started! 92 | > Don't call .start() twice, as it will stop performing previous background tasks and start a new one. 93 | > If .start() is called on the backgound, it will not have any effect. 94 | 95 | ### Options 96 | | Property | Type | Description | 97 | | ------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 98 | | `taskName` | `` | Task name for identification. | 99 | | `taskTitle` | `` | **Android Required**. Notification title. | 100 | | `taskDesc` | `` | **Android Required**. Notification description. | 101 | | `taskIcon` | [``](#taskIconOptions) | **Android Required**. Notification icon. | 102 | | `color` | `` | Notification color. **Default**: `"#ffffff"`. | 103 | | `linkingURI` | `` | Link that will be called when the notification is clicked. Example: `"yourSchemeHere://chat/jane"`. See [Deep Linking](#deep-linking) for more info. **Default**: `undefined`. | 104 | | `progressBar` | [``](#taskProgressBarOptions) | Notification progress bar. | 105 | | `parameters` | `` | Parameters to pass to the task. | 106 | 107 | #### taskIconOptions 108 | **Android only** 109 | | Property | Type | Description | 110 | | --------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | 111 | | `name` | `` | **Required**. Icon name in res/ folder. Ex: `ic_launcher`. | 112 | | `type` | `` | **Required**. Icon type in res/ folder. Ex: `mipmap`. | 113 | | `package` | `` | Icon package where to search the icon. Ex: `com.example.package`. **It defaults to the app's package. It is highly recommended to leave like that.** | 114 | 115 | Example: 116 | 117 | ![photo5837026843969041365](https://user-images.githubusercontent.com/44206249/72532521-de49e280-3873-11ea-8bf6-00618bcb82ab.jpg) 118 | 119 | #### taskProgressBarOptions 120 | **Android only** 121 | | Property | Type | Description | 122 | | --------------- | ----------- | --------------------------------------------- | 123 | | `max` | `` | **Required**. Maximum value. | 124 | | `value` | `` | **Required**. Current value. | 125 | | `indeterminate` | `` | Display the progress status as indeterminate. | 126 | 127 | Example: 128 | 129 | ![ProgressBar](https://developer.android.com/images/ui/notifications/notification-progressbar_2x.png) 130 | 131 | ### Deep Linking 132 | **Android only** 133 | 134 | To handle incoming links when the notification is clicked by the user, first you need to modify your **`android/app/src/main/AndroidManifest.xml`** and add an `` (fill `yourSchemeHere` with the name you prefer): 135 | ```xml 136 | 137 | ... 138 | 139 | // Add this if not present 142 | ... 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | ``` 152 | 153 | You must provide a `linkingURI` in the BackgroundService's [options](#options) that matches the scheme you just added to **`android/app/src/main/AndroidManifest.xml`**: 154 | ```js 155 | const options = { 156 | taskName: 'Example', 157 | taskTitle: 'ExampleTask title', 158 | taskDesc: 'ExampleTask description', 159 | taskIcon: { 160 | name: 'ic_launcher', 161 | type: 'mipmap', 162 | }, 163 | color: '#ff00ff', 164 | linkingURI: 'yourSchemeHere://chat/jane', // Add this 165 | parameters: { 166 | delay: 1000, 167 | }, 168 | }; 169 | 170 | 171 | await BackgroundService.start(veryIntensiveTask, options); 172 | ``` 173 | 174 | React Native provides a `Linking` class to get notified of incoming links. Your JavaScript code must then listen to the url using React Native `Linking` class: 175 | ```js 176 | import { Linking } from 'react-native'; 177 | 178 | Linking.addEventListener('url', handleOpenURL); 179 | 180 | function handleOpenURL(evt) { 181 | // Will be called when the notification is pressed 182 | console.log(evt.url); 183 | // do something 184 | } 185 | ``` 186 | 187 | ### Events 188 | #### 'expiration' 189 | **iOS only** 190 | Listen for the iOS-only expiration handler that allows you to 'clean up' shortly before the app’s remaining background time reaches 0. Check the iOS [documentation](https://developer.apple.com/documentation/uikit/uiapplication/1623031-beginbackgroundtask) for more info. 191 | 192 | ```js 193 | BackgroundService.on('expiration', () => { 194 | console.log('I am being closed :('); 195 | }); 196 | 197 | await BackgroundService.start(veryIntensiveTask, options); 198 | 199 | ``` 200 | 201 | ## Maintainers 202 | 203 | * [Rapsssito](https://github.com/rapsssito) [[Support me :heart:](https://github.com/sponsors/Rapsssito)] 204 | 205 | ## Acknowledgments 206 | 207 | * iOS part originally forked from [react-native-background-timer](https://github.com/ocetnik/react-native-background-timer) 208 | 209 | ## License 210 | 211 | The library is released under the MIT license. For more information see [`LICENSE`](/LICENSE). 212 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost-for-react-native (1.63.0) 3 | - DoubleConversion (1.1.6) 4 | - FBLazyVector (0.61.5) 5 | - FBReactNativeSpec (0.61.5): 6 | - Folly (= 2018.10.22.00) 7 | - RCTRequired (= 0.61.5) 8 | - RCTTypeSafety (= 0.61.5) 9 | - React-Core (= 0.61.5) 10 | - React-jsi (= 0.61.5) 11 | - ReactCommon/turbomodule/core (= 0.61.5) 12 | - Folly (2018.10.22.00): 13 | - boost-for-react-native 14 | - DoubleConversion 15 | - Folly/Default (= 2018.10.22.00) 16 | - glog 17 | - Folly/Default (2018.10.22.00): 18 | - boost-for-react-native 19 | - DoubleConversion 20 | - glog 21 | - glog (0.3.5) 22 | - RCTRequired (0.61.5) 23 | - RCTTypeSafety (0.61.5): 24 | - FBLazyVector (= 0.61.5) 25 | - Folly (= 2018.10.22.00) 26 | - RCTRequired (= 0.61.5) 27 | - React-Core (= 0.61.5) 28 | - React (0.61.5): 29 | - React-Core (= 0.61.5) 30 | - React-Core/DevSupport (= 0.61.5) 31 | - React-Core/RCTWebSocket (= 0.61.5) 32 | - React-RCTActionSheet (= 0.61.5) 33 | - React-RCTAnimation (= 0.61.5) 34 | - React-RCTBlob (= 0.61.5) 35 | - React-RCTImage (= 0.61.5) 36 | - React-RCTLinking (= 0.61.5) 37 | - React-RCTNetwork (= 0.61.5) 38 | - React-RCTSettings (= 0.61.5) 39 | - React-RCTText (= 0.61.5) 40 | - React-RCTVibration (= 0.61.5) 41 | - React-Core (0.61.5): 42 | - Folly (= 2018.10.22.00) 43 | - glog 44 | - React-Core/Default (= 0.61.5) 45 | - React-cxxreact (= 0.61.5) 46 | - React-jsi (= 0.61.5) 47 | - React-jsiexecutor (= 0.61.5) 48 | - Yoga 49 | - React-Core/CoreModulesHeaders (0.61.5): 50 | - Folly (= 2018.10.22.00) 51 | - glog 52 | - React-Core/Default 53 | - React-cxxreact (= 0.61.5) 54 | - React-jsi (= 0.61.5) 55 | - React-jsiexecutor (= 0.61.5) 56 | - Yoga 57 | - React-Core/Default (0.61.5): 58 | - Folly (= 2018.10.22.00) 59 | - glog 60 | - React-cxxreact (= 0.61.5) 61 | - React-jsi (= 0.61.5) 62 | - React-jsiexecutor (= 0.61.5) 63 | - Yoga 64 | - React-Core/DevSupport (0.61.5): 65 | - Folly (= 2018.10.22.00) 66 | - glog 67 | - React-Core/Default (= 0.61.5) 68 | - React-Core/RCTWebSocket (= 0.61.5) 69 | - React-cxxreact (= 0.61.5) 70 | - React-jsi (= 0.61.5) 71 | - React-jsiexecutor (= 0.61.5) 72 | - React-jsinspector (= 0.61.5) 73 | - Yoga 74 | - React-Core/RCTActionSheetHeaders (0.61.5): 75 | - Folly (= 2018.10.22.00) 76 | - glog 77 | - React-Core/Default 78 | - React-cxxreact (= 0.61.5) 79 | - React-jsi (= 0.61.5) 80 | - React-jsiexecutor (= 0.61.5) 81 | - Yoga 82 | - React-Core/RCTAnimationHeaders (0.61.5): 83 | - Folly (= 2018.10.22.00) 84 | - glog 85 | - React-Core/Default 86 | - React-cxxreact (= 0.61.5) 87 | - React-jsi (= 0.61.5) 88 | - React-jsiexecutor (= 0.61.5) 89 | - Yoga 90 | - React-Core/RCTBlobHeaders (0.61.5): 91 | - Folly (= 2018.10.22.00) 92 | - glog 93 | - React-Core/Default 94 | - React-cxxreact (= 0.61.5) 95 | - React-jsi (= 0.61.5) 96 | - React-jsiexecutor (= 0.61.5) 97 | - Yoga 98 | - React-Core/RCTImageHeaders (0.61.5): 99 | - Folly (= 2018.10.22.00) 100 | - glog 101 | - React-Core/Default 102 | - React-cxxreact (= 0.61.5) 103 | - React-jsi (= 0.61.5) 104 | - React-jsiexecutor (= 0.61.5) 105 | - Yoga 106 | - React-Core/RCTLinkingHeaders (0.61.5): 107 | - Folly (= 2018.10.22.00) 108 | - glog 109 | - React-Core/Default 110 | - React-cxxreact (= 0.61.5) 111 | - React-jsi (= 0.61.5) 112 | - React-jsiexecutor (= 0.61.5) 113 | - Yoga 114 | - React-Core/RCTNetworkHeaders (0.61.5): 115 | - Folly (= 2018.10.22.00) 116 | - glog 117 | - React-Core/Default 118 | - React-cxxreact (= 0.61.5) 119 | - React-jsi (= 0.61.5) 120 | - React-jsiexecutor (= 0.61.5) 121 | - Yoga 122 | - React-Core/RCTSettingsHeaders (0.61.5): 123 | - Folly (= 2018.10.22.00) 124 | - glog 125 | - React-Core/Default 126 | - React-cxxreact (= 0.61.5) 127 | - React-jsi (= 0.61.5) 128 | - React-jsiexecutor (= 0.61.5) 129 | - Yoga 130 | - React-Core/RCTTextHeaders (0.61.5): 131 | - Folly (= 2018.10.22.00) 132 | - glog 133 | - React-Core/Default 134 | - React-cxxreact (= 0.61.5) 135 | - React-jsi (= 0.61.5) 136 | - React-jsiexecutor (= 0.61.5) 137 | - Yoga 138 | - React-Core/RCTVibrationHeaders (0.61.5): 139 | - Folly (= 2018.10.22.00) 140 | - glog 141 | - React-Core/Default 142 | - React-cxxreact (= 0.61.5) 143 | - React-jsi (= 0.61.5) 144 | - React-jsiexecutor (= 0.61.5) 145 | - Yoga 146 | - React-Core/RCTWebSocket (0.61.5): 147 | - Folly (= 2018.10.22.00) 148 | - glog 149 | - React-Core/Default (= 0.61.5) 150 | - React-cxxreact (= 0.61.5) 151 | - React-jsi (= 0.61.5) 152 | - React-jsiexecutor (= 0.61.5) 153 | - Yoga 154 | - React-CoreModules (0.61.5): 155 | - FBReactNativeSpec (= 0.61.5) 156 | - Folly (= 2018.10.22.00) 157 | - RCTTypeSafety (= 0.61.5) 158 | - React-Core/CoreModulesHeaders (= 0.61.5) 159 | - React-RCTImage (= 0.61.5) 160 | - ReactCommon/turbomodule/core (= 0.61.5) 161 | - React-cxxreact (0.61.5): 162 | - boost-for-react-native (= 1.63.0) 163 | - DoubleConversion 164 | - Folly (= 2018.10.22.00) 165 | - glog 166 | - React-jsinspector (= 0.61.5) 167 | - React-jsi (0.61.5): 168 | - boost-for-react-native (= 1.63.0) 169 | - DoubleConversion 170 | - Folly (= 2018.10.22.00) 171 | - glog 172 | - React-jsi/Default (= 0.61.5) 173 | - React-jsi/Default (0.61.5): 174 | - boost-for-react-native (= 1.63.0) 175 | - DoubleConversion 176 | - Folly (= 2018.10.22.00) 177 | - glog 178 | - React-jsiexecutor (0.61.5): 179 | - DoubleConversion 180 | - Folly (= 2018.10.22.00) 181 | - glog 182 | - React-cxxreact (= 0.61.5) 183 | - React-jsi (= 0.61.5) 184 | - React-jsinspector (0.61.5) 185 | - React-RCTActionSheet (0.61.5): 186 | - React-Core/RCTActionSheetHeaders (= 0.61.5) 187 | - React-RCTAnimation (0.61.5): 188 | - React-Core/RCTAnimationHeaders (= 0.61.5) 189 | - React-RCTBlob (0.61.5): 190 | - React-Core/RCTBlobHeaders (= 0.61.5) 191 | - React-Core/RCTWebSocket (= 0.61.5) 192 | - React-jsi (= 0.61.5) 193 | - React-RCTNetwork (= 0.61.5) 194 | - React-RCTImage (0.61.5): 195 | - React-Core/RCTImageHeaders (= 0.61.5) 196 | - React-RCTNetwork (= 0.61.5) 197 | - React-RCTLinking (0.61.5): 198 | - React-Core/RCTLinkingHeaders (= 0.61.5) 199 | - React-RCTNetwork (0.61.5): 200 | - React-Core/RCTNetworkHeaders (= 0.61.5) 201 | - React-RCTSettings (0.61.5): 202 | - React-Core/RCTSettingsHeaders (= 0.61.5) 203 | - React-RCTText (0.61.5): 204 | - React-Core/RCTTextHeaders (= 0.61.5) 205 | - React-RCTVibration (0.61.5): 206 | - React-Core/RCTVibrationHeaders (= 0.61.5) 207 | - ReactCommon/jscallinvoker (0.61.5): 208 | - DoubleConversion 209 | - Folly (= 2018.10.22.00) 210 | - glog 211 | - React-cxxreact (= 0.61.5) 212 | - ReactCommon/turbomodule/core (0.61.5): 213 | - DoubleConversion 214 | - Folly (= 2018.10.22.00) 215 | - glog 216 | - React-Core (= 0.61.5) 217 | - React-cxxreact (= 0.61.5) 218 | - React-jsi (= 0.61.5) 219 | - ReactCommon/jscallinvoker (= 0.61.5) 220 | - Yoga (1.14.0) 221 | 222 | DEPENDENCIES: 223 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 224 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 225 | - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) 226 | - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) 227 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 228 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 229 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 230 | - React (from `../node_modules/react-native/`) 231 | - React-Core (from `../node_modules/react-native/`) 232 | - React-Core/DevSupport (from `../node_modules/react-native/`) 233 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 234 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 235 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 236 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 237 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 238 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 239 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 240 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 241 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 242 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 243 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 244 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 245 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 246 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 247 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 248 | - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) 249 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 250 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 251 | 252 | SPEC REPOS: 253 | trunk: 254 | - boost-for-react-native 255 | 256 | EXTERNAL SOURCES: 257 | DoubleConversion: 258 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 259 | FBLazyVector: 260 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 261 | FBReactNativeSpec: 262 | :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" 263 | Folly: 264 | :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" 265 | glog: 266 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 267 | RCTRequired: 268 | :path: "../node_modules/react-native/Libraries/RCTRequired" 269 | RCTTypeSafety: 270 | :path: "../node_modules/react-native/Libraries/TypeSafety" 271 | React: 272 | :path: "../node_modules/react-native/" 273 | React-Core: 274 | :path: "../node_modules/react-native/" 275 | React-CoreModules: 276 | :path: "../node_modules/react-native/React/CoreModules" 277 | React-cxxreact: 278 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 279 | React-jsi: 280 | :path: "../node_modules/react-native/ReactCommon/jsi" 281 | React-jsiexecutor: 282 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 283 | React-jsinspector: 284 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 285 | React-RCTActionSheet: 286 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 287 | React-RCTAnimation: 288 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 289 | React-RCTBlob: 290 | :path: "../node_modules/react-native/Libraries/Blob" 291 | React-RCTImage: 292 | :path: "../node_modules/react-native/Libraries/Image" 293 | React-RCTLinking: 294 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 295 | React-RCTNetwork: 296 | :path: "../node_modules/react-native/Libraries/Network" 297 | React-RCTSettings: 298 | :path: "../node_modules/react-native/Libraries/Settings" 299 | React-RCTText: 300 | :path: "../node_modules/react-native/Libraries/Text" 301 | React-RCTVibration: 302 | :path: "../node_modules/react-native/Libraries/Vibration" 303 | ReactCommon: 304 | :path: "../node_modules/react-native/ReactCommon" 305 | Yoga: 306 | :path: "../node_modules/react-native/ReactCommon/yoga" 307 | 308 | SPEC CHECKSUMS: 309 | boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c 310 | DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 311 | FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f 312 | FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 313 | Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 314 | glog: 1f3da668190260b06b429bb211bfbee5cd790c28 315 | RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 316 | RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 317 | React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78 318 | React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04 319 | React-CoreModules: d04f8494c1a328b69ec11db9d1137d667f916dcb 320 | React-cxxreact: d0f7bcafa196ae410e5300736b424455e7fb7ba7 321 | React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7 322 | React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386 323 | React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 324 | React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 325 | React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360 326 | React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72 327 | React-RCTImage: 6b8e8df449eb7c814c99a92d6b52de6fe39dea4e 328 | React-RCTLinking: 121bb231c7503cf9094f4d8461b96a130fabf4a5 329 | React-RCTNetwork: fb353640aafcee84ca8b78957297bd395f065c9a 330 | React-RCTSettings: 8db258ea2a5efee381fcf7a6d5044e2f8b68b640 331 | React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe 332 | React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad 333 | ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd 334 | Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b 335 | 336 | PODFILE CHECKSUM: a90ff6bc1df3babb3172c16eefeae5f811147b69 337 | 338 | COCOAPODS: 1.8.4 339 | -------------------------------------------------------------------------------- /examples/backgroundExample/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost-for-react-native (1.63.0) 3 | - DoubleConversion (1.1.6) 4 | - FBLazyVector (0.61.5) 5 | - FBReactNativeSpec (0.61.5): 6 | - Folly (= 2018.10.22.00) 7 | - RCTRequired (= 0.61.5) 8 | - RCTTypeSafety (= 0.61.5) 9 | - React-Core (= 0.61.5) 10 | - React-jsi (= 0.61.5) 11 | - ReactCommon/turbomodule/core (= 0.61.5) 12 | - Folly (2018.10.22.00): 13 | - boost-for-react-native 14 | - DoubleConversion 15 | - Folly/Default (= 2018.10.22.00) 16 | - glog 17 | - Folly/Default (2018.10.22.00): 18 | - boost-for-react-native 19 | - DoubleConversion 20 | - glog 21 | - glog (0.3.5) 22 | - RCTRequired (0.61.5) 23 | - RCTTypeSafety (0.61.5): 24 | - FBLazyVector (= 0.61.5) 25 | - Folly (= 2018.10.22.00) 26 | - RCTRequired (= 0.61.5) 27 | - React-Core (= 0.61.5) 28 | - React (0.61.5): 29 | - React-Core (= 0.61.5) 30 | - React-Core/DevSupport (= 0.61.5) 31 | - React-Core/RCTWebSocket (= 0.61.5) 32 | - React-RCTActionSheet (= 0.61.5) 33 | - React-RCTAnimation (= 0.61.5) 34 | - React-RCTBlob (= 0.61.5) 35 | - React-RCTImage (= 0.61.5) 36 | - React-RCTLinking (= 0.61.5) 37 | - React-RCTNetwork (= 0.61.5) 38 | - React-RCTSettings (= 0.61.5) 39 | - React-RCTText (= 0.61.5) 40 | - React-RCTVibration (= 0.61.5) 41 | - React-Core (0.61.5): 42 | - Folly (= 2018.10.22.00) 43 | - glog 44 | - React-Core/Default (= 0.61.5) 45 | - React-cxxreact (= 0.61.5) 46 | - React-jsi (= 0.61.5) 47 | - React-jsiexecutor (= 0.61.5) 48 | - Yoga 49 | - React-Core/CoreModulesHeaders (0.61.5): 50 | - Folly (= 2018.10.22.00) 51 | - glog 52 | - React-Core/Default 53 | - React-cxxreact (= 0.61.5) 54 | - React-jsi (= 0.61.5) 55 | - React-jsiexecutor (= 0.61.5) 56 | - Yoga 57 | - React-Core/Default (0.61.5): 58 | - Folly (= 2018.10.22.00) 59 | - glog 60 | - React-cxxreact (= 0.61.5) 61 | - React-jsi (= 0.61.5) 62 | - React-jsiexecutor (= 0.61.5) 63 | - Yoga 64 | - React-Core/DevSupport (0.61.5): 65 | - Folly (= 2018.10.22.00) 66 | - glog 67 | - React-Core/Default (= 0.61.5) 68 | - React-Core/RCTWebSocket (= 0.61.5) 69 | - React-cxxreact (= 0.61.5) 70 | - React-jsi (= 0.61.5) 71 | - React-jsiexecutor (= 0.61.5) 72 | - React-jsinspector (= 0.61.5) 73 | - Yoga 74 | - React-Core/RCTActionSheetHeaders (0.61.5): 75 | - Folly (= 2018.10.22.00) 76 | - glog 77 | - React-Core/Default 78 | - React-cxxreact (= 0.61.5) 79 | - React-jsi (= 0.61.5) 80 | - React-jsiexecutor (= 0.61.5) 81 | - Yoga 82 | - React-Core/RCTAnimationHeaders (0.61.5): 83 | - Folly (= 2018.10.22.00) 84 | - glog 85 | - React-Core/Default 86 | - React-cxxreact (= 0.61.5) 87 | - React-jsi (= 0.61.5) 88 | - React-jsiexecutor (= 0.61.5) 89 | - Yoga 90 | - React-Core/RCTBlobHeaders (0.61.5): 91 | - Folly (= 2018.10.22.00) 92 | - glog 93 | - React-Core/Default 94 | - React-cxxreact (= 0.61.5) 95 | - React-jsi (= 0.61.5) 96 | - React-jsiexecutor (= 0.61.5) 97 | - Yoga 98 | - React-Core/RCTImageHeaders (0.61.5): 99 | - Folly (= 2018.10.22.00) 100 | - glog 101 | - React-Core/Default 102 | - React-cxxreact (= 0.61.5) 103 | - React-jsi (= 0.61.5) 104 | - React-jsiexecutor (= 0.61.5) 105 | - Yoga 106 | - React-Core/RCTLinkingHeaders (0.61.5): 107 | - Folly (= 2018.10.22.00) 108 | - glog 109 | - React-Core/Default 110 | - React-cxxreact (= 0.61.5) 111 | - React-jsi (= 0.61.5) 112 | - React-jsiexecutor (= 0.61.5) 113 | - Yoga 114 | - React-Core/RCTNetworkHeaders (0.61.5): 115 | - Folly (= 2018.10.22.00) 116 | - glog 117 | - React-Core/Default 118 | - React-cxxreact (= 0.61.5) 119 | - React-jsi (= 0.61.5) 120 | - React-jsiexecutor (= 0.61.5) 121 | - Yoga 122 | - React-Core/RCTSettingsHeaders (0.61.5): 123 | - Folly (= 2018.10.22.00) 124 | - glog 125 | - React-Core/Default 126 | - React-cxxreact (= 0.61.5) 127 | - React-jsi (= 0.61.5) 128 | - React-jsiexecutor (= 0.61.5) 129 | - Yoga 130 | - React-Core/RCTTextHeaders (0.61.5): 131 | - Folly (= 2018.10.22.00) 132 | - glog 133 | - React-Core/Default 134 | - React-cxxreact (= 0.61.5) 135 | - React-jsi (= 0.61.5) 136 | - React-jsiexecutor (= 0.61.5) 137 | - Yoga 138 | - React-Core/RCTVibrationHeaders (0.61.5): 139 | - Folly (= 2018.10.22.00) 140 | - glog 141 | - React-Core/Default 142 | - React-cxxreact (= 0.61.5) 143 | - React-jsi (= 0.61.5) 144 | - React-jsiexecutor (= 0.61.5) 145 | - Yoga 146 | - React-Core/RCTWebSocket (0.61.5): 147 | - Folly (= 2018.10.22.00) 148 | - glog 149 | - React-Core/Default (= 0.61.5) 150 | - React-cxxreact (= 0.61.5) 151 | - React-jsi (= 0.61.5) 152 | - React-jsiexecutor (= 0.61.5) 153 | - Yoga 154 | - React-CoreModules (0.61.5): 155 | - FBReactNativeSpec (= 0.61.5) 156 | - Folly (= 2018.10.22.00) 157 | - RCTTypeSafety (= 0.61.5) 158 | - React-Core/CoreModulesHeaders (= 0.61.5) 159 | - React-RCTImage (= 0.61.5) 160 | - ReactCommon/turbomodule/core (= 0.61.5) 161 | - React-cxxreact (0.61.5): 162 | - boost-for-react-native (= 1.63.0) 163 | - DoubleConversion 164 | - Folly (= 2018.10.22.00) 165 | - glog 166 | - React-jsinspector (= 0.61.5) 167 | - React-jsi (0.61.5): 168 | - boost-for-react-native (= 1.63.0) 169 | - DoubleConversion 170 | - Folly (= 2018.10.22.00) 171 | - glog 172 | - React-jsi/Default (= 0.61.5) 173 | - React-jsi/Default (0.61.5): 174 | - boost-for-react-native (= 1.63.0) 175 | - DoubleConversion 176 | - Folly (= 2018.10.22.00) 177 | - glog 178 | - React-jsiexecutor (0.61.5): 179 | - DoubleConversion 180 | - Folly (= 2018.10.22.00) 181 | - glog 182 | - React-cxxreact (= 0.61.5) 183 | - React-jsi (= 0.61.5) 184 | - React-jsinspector (0.61.5) 185 | - react-native-background-actions (2.5.3): 186 | - React-Core 187 | - React-RCTActionSheet (0.61.5): 188 | - React-Core/RCTActionSheetHeaders (= 0.61.5) 189 | - React-RCTAnimation (0.61.5): 190 | - React-Core/RCTAnimationHeaders (= 0.61.5) 191 | - React-RCTBlob (0.61.5): 192 | - React-Core/RCTBlobHeaders (= 0.61.5) 193 | - React-Core/RCTWebSocket (= 0.61.5) 194 | - React-jsi (= 0.61.5) 195 | - React-RCTNetwork (= 0.61.5) 196 | - React-RCTImage (0.61.5): 197 | - React-Core/RCTImageHeaders (= 0.61.5) 198 | - React-RCTNetwork (= 0.61.5) 199 | - React-RCTLinking (0.61.5): 200 | - React-Core/RCTLinkingHeaders (= 0.61.5) 201 | - React-RCTNetwork (0.61.5): 202 | - React-Core/RCTNetworkHeaders (= 0.61.5) 203 | - React-RCTSettings (0.61.5): 204 | - React-Core/RCTSettingsHeaders (= 0.61.5) 205 | - React-RCTText (0.61.5): 206 | - React-Core/RCTTextHeaders (= 0.61.5) 207 | - React-RCTVibration (0.61.5): 208 | - React-Core/RCTVibrationHeaders (= 0.61.5) 209 | - ReactCommon/jscallinvoker (0.61.5): 210 | - DoubleConversion 211 | - Folly (= 2018.10.22.00) 212 | - glog 213 | - React-cxxreact (= 0.61.5) 214 | - ReactCommon/turbomodule/core (0.61.5): 215 | - DoubleConversion 216 | - Folly (= 2018.10.22.00) 217 | - glog 218 | - React-Core (= 0.61.5) 219 | - React-cxxreact (= 0.61.5) 220 | - React-jsi (= 0.61.5) 221 | - ReactCommon/jscallinvoker (= 0.61.5) 222 | - Yoga (1.14.0) 223 | 224 | DEPENDENCIES: 225 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 226 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 227 | - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`) 228 | - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`) 229 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 230 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 231 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 232 | - React (from `../node_modules/react-native/`) 233 | - React-Core (from `../node_modules/react-native/`) 234 | - React-Core/DevSupport (from `../node_modules/react-native/`) 235 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 236 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 237 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 238 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 239 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 240 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 241 | - react-native-background-actions (from `../../..`) 242 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 243 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 244 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 245 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 246 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 247 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 248 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 249 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 250 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 251 | - ReactCommon/jscallinvoker (from `../node_modules/react-native/ReactCommon`) 252 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 253 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 254 | 255 | SPEC REPOS: 256 | trunk: 257 | - boost-for-react-native 258 | 259 | EXTERNAL SOURCES: 260 | DoubleConversion: 261 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 262 | FBLazyVector: 263 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 264 | FBReactNativeSpec: 265 | :path: "../node_modules/react-native/Libraries/FBReactNativeSpec" 266 | Folly: 267 | :podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec" 268 | glog: 269 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 270 | RCTRequired: 271 | :path: "../node_modules/react-native/Libraries/RCTRequired" 272 | RCTTypeSafety: 273 | :path: "../node_modules/react-native/Libraries/TypeSafety" 274 | React: 275 | :path: "../node_modules/react-native/" 276 | React-Core: 277 | :path: "../node_modules/react-native/" 278 | React-CoreModules: 279 | :path: "../node_modules/react-native/React/CoreModules" 280 | React-cxxreact: 281 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 282 | React-jsi: 283 | :path: "../node_modules/react-native/ReactCommon/jsi" 284 | React-jsiexecutor: 285 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 286 | React-jsinspector: 287 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 288 | react-native-background-actions: 289 | :path: "../../.." 290 | React-RCTActionSheet: 291 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 292 | React-RCTAnimation: 293 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 294 | React-RCTBlob: 295 | :path: "../node_modules/react-native/Libraries/Blob" 296 | React-RCTImage: 297 | :path: "../node_modules/react-native/Libraries/Image" 298 | React-RCTLinking: 299 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 300 | React-RCTNetwork: 301 | :path: "../node_modules/react-native/Libraries/Network" 302 | React-RCTSettings: 303 | :path: "../node_modules/react-native/Libraries/Settings" 304 | React-RCTText: 305 | :path: "../node_modules/react-native/Libraries/Text" 306 | React-RCTVibration: 307 | :path: "../node_modules/react-native/Libraries/Vibration" 308 | ReactCommon: 309 | :path: "../node_modules/react-native/ReactCommon" 310 | Yoga: 311 | :path: "../node_modules/react-native/ReactCommon/yoga" 312 | 313 | SPEC CHECKSUMS: 314 | boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c 315 | DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 316 | FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f 317 | FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 318 | Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 319 | glog: 1f3da668190260b06b429bb211bfbee5cd790c28 320 | RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 321 | RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 322 | React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78 323 | React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04 324 | React-CoreModules: d04f8494c1a328b69ec11db9d1137d667f916dcb 325 | React-cxxreact: d0f7bcafa196ae410e5300736b424455e7fb7ba7 326 | React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7 327 | React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386 328 | React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 329 | react-native-background-actions: 6acd6f3b369ab93e80e47018c61e7d60586c2d8d 330 | React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 331 | React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360 332 | React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72 333 | React-RCTImage: 6b8e8df449eb7c814c99a92d6b52de6fe39dea4e 334 | React-RCTLinking: 121bb231c7503cf9094f4d8461b96a130fabf4a5 335 | React-RCTNetwork: fb353640aafcee84ca8b78957297bd395f065c9a 336 | React-RCTSettings: 8db258ea2a5efee381fcf7a6d5044e2f8b68b640 337 | React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe 338 | React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad 339 | ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd 340 | Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b 341 | 342 | PODFILE CHECKSUM: 6d56a26ae5d1018372dcc850090bad58f9b1c9d0 343 | 344 | COCOAPODS: 1.10.1 345 | -------------------------------------------------------------------------------- /ios/RNBackgroundActions.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 379852B93950BCF4EB85ADA5 /* Pods_RNBackgroundActions.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12CAC3D778A2077AE84799FE /* Pods_RNBackgroundActions.framework */; }; 11 | 6419269B1ECB4266009CF731 /* RNBackgroundActions.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNBackgroundActions.m */; }; 12 | B3E7B58A1CC2AC0600A0062D /* RNBackgroundActions.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNBackgroundActions.m */; }; 13 | /* End PBXBuildFile section */ 14 | 15 | /* Begin PBXCopyFilesBuildPhase section */ 16 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 17 | isa = PBXCopyFilesBuildPhase; 18 | buildActionMask = 2147483647; 19 | dstPath = "include/$(PRODUCT_NAME)"; 20 | dstSubfolderSpec = 16; 21 | files = ( 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | 641926901ECB4257009CF731 /* CopyFiles */ = { 26 | isa = PBXCopyFilesBuildPhase; 27 | buildActionMask = 2147483647; 28 | dstPath = "include/$(PRODUCT_NAME)"; 29 | dstSubfolderSpec = 16; 30 | files = ( 31 | ); 32 | runOnlyForDeploymentPostprocessing = 0; 33 | }; 34 | /* End PBXCopyFilesBuildPhase section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | 12CAC3D778A2077AE84799FE /* Pods_RNBackgroundActions.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RNBackgroundActions.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 134814201AA4EA6300B7C361 /* libRNBackgroundActions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNBackgroundActions.a; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 5694935E99A79F9E84DE86A2 /* Pods-RNBackgroundActions.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNBackgroundActions.release.xcconfig"; path = "Target Support Files/Pods-RNBackgroundActions/Pods-RNBackgroundActions.release.xcconfig"; sourceTree = ""; }; 40 | 641926921ECB4257009CF731 /* libRNBackgroundActions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNBackgroundActions.a; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 71DD9836C50E2FFD2D98ADD0 /* Pods-RNBackgroundActions.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNBackgroundActions.debug.xcconfig"; path = "Target Support Files/Pods-RNBackgroundActions/Pods-RNBackgroundActions.debug.xcconfig"; sourceTree = ""; }; 42 | B3E7B5881CC2AC0600A0062D /* RNBackgroundActions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNBackgroundActions.h; sourceTree = ""; }; 43 | B3E7B5891CC2AC0600A0062D /* RNBackgroundActions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNBackgroundActions.m; sourceTree = ""; }; 44 | /* End PBXFileReference section */ 45 | 46 | /* Begin PBXFrameworksBuildPhase section */ 47 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 48 | isa = PBXFrameworksBuildPhase; 49 | buildActionMask = 2147483647; 50 | files = ( 51 | 379852B93950BCF4EB85ADA5 /* Pods_RNBackgroundActions.framework in Frameworks */, 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | 6419268F1ECB4257009CF731 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXFrameworksBuildPhase section */ 63 | 64 | /* Begin PBXGroup section */ 65 | 134814211AA4EA7D00B7C361 /* Products */ = { 66 | isa = PBXGroup; 67 | children = ( 68 | 134814201AA4EA6300B7C361 /* libRNBackgroundActions.a */, 69 | ); 70 | name = Products; 71 | sourceTree = ""; 72 | }; 73 | 1CF73046BC523C646FA05356 /* Frameworks */ = { 74 | isa = PBXGroup; 75 | children = ( 76 | 12CAC3D778A2077AE84799FE /* Pods_RNBackgroundActions.framework */, 77 | ); 78 | name = Frameworks; 79 | sourceTree = ""; 80 | }; 81 | 58B511D21A9E6C8500147676 = { 82 | isa = PBXGroup; 83 | children = ( 84 | B3E7B5881CC2AC0600A0062D /* RNBackgroundActions.h */, 85 | B3E7B5891CC2AC0600A0062D /* RNBackgroundActions.m */, 86 | 134814211AA4EA7D00B7C361 /* Products */, 87 | 641926921ECB4257009CF731 /* libRNBackgroundActions.a */, 88 | 62EDDBCED6A5B89493EF0704 /* Pods */, 89 | 1CF73046BC523C646FA05356 /* Frameworks */, 90 | ); 91 | sourceTree = ""; 92 | }; 93 | 62EDDBCED6A5B89493EF0704 /* Pods */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | 71DD9836C50E2FFD2D98ADD0 /* Pods-RNBackgroundActions.debug.xcconfig */, 97 | 5694935E99A79F9E84DE86A2 /* Pods-RNBackgroundActions.release.xcconfig */, 98 | ); 99 | path = Pods; 100 | sourceTree = ""; 101 | }; 102 | /* End PBXGroup section */ 103 | 104 | /* Begin PBXNativeTarget section */ 105 | 58B511DA1A9E6C8500147676 /* RNBackgroundActions */ = { 106 | isa = PBXNativeTarget; 107 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNBackgroundActions" */; 108 | buildPhases = ( 109 | 9E63BEA3B70BEBF00C883285 /* [CP] Check Pods Manifest.lock */, 110 | 58B511D71A9E6C8500147676 /* Sources */, 111 | 58B511D81A9E6C8500147676 /* Frameworks */, 112 | 58B511D91A9E6C8500147676 /* CopyFiles */, 113 | ); 114 | buildRules = ( 115 | ); 116 | dependencies = ( 117 | ); 118 | name = RNBackgroundActions; 119 | productName = RCTDataManager; 120 | productReference = 134814201AA4EA6300B7C361 /* libRNBackgroundActions.a */; 121 | productType = "com.apple.product-type.library.static"; 122 | }; 123 | 641926911ECB4257009CF731 /* RNBackgroundActions-tvOS */ = { 124 | isa = PBXNativeTarget; 125 | buildConfigurationList = 6419269A1ECB4257009CF731 /* Build configuration list for PBXNativeTarget "RNBackgroundActions-tvOS" */; 126 | buildPhases = ( 127 | 6419268E1ECB4257009CF731 /* Sources */, 128 | 6419268F1ECB4257009CF731 /* Frameworks */, 129 | 641926901ECB4257009CF731 /* CopyFiles */, 130 | ); 131 | buildRules = ( 132 | ); 133 | dependencies = ( 134 | ); 135 | name = "RNBackgroundActions-tvOS"; 136 | productName = "RNBackgroundActions-tvOS"; 137 | productReference = 641926921ECB4257009CF731 /* libRNBackgroundActions.a */; 138 | productType = "com.apple.product-type.library.static"; 139 | }; 140 | /* End PBXNativeTarget section */ 141 | 142 | /* Begin PBXProject section */ 143 | 58B511D31A9E6C8500147676 /* Project object */ = { 144 | isa = PBXProject; 145 | attributes = { 146 | LastUpgradeCheck = 1130; 147 | ORGANIZATIONNAME = Facebook; 148 | TargetAttributes = { 149 | 58B511DA1A9E6C8500147676 = { 150 | CreatedOnToolsVersion = 6.1.1; 151 | }; 152 | 641926911ECB4257009CF731 = { 153 | CreatedOnToolsVersion = 8.3.2; 154 | ProvisioningStyle = Automatic; 155 | }; 156 | }; 157 | }; 158 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNBackgroundActions" */; 159 | compatibilityVersion = "Xcode 3.2"; 160 | developmentRegion = en; 161 | hasScannedForEncodings = 0; 162 | knownRegions = ( 163 | en, 164 | Base, 165 | ); 166 | mainGroup = 58B511D21A9E6C8500147676; 167 | productRefGroup = 58B511D21A9E6C8500147676; 168 | projectDirPath = ""; 169 | projectRoot = ""; 170 | targets = ( 171 | 58B511DA1A9E6C8500147676 /* RNBackgroundActions */, 172 | 641926911ECB4257009CF731 /* RNBackgroundActions-tvOS */, 173 | ); 174 | }; 175 | /* End PBXProject section */ 176 | 177 | /* Begin PBXShellScriptBuildPhase section */ 178 | 9E63BEA3B70BEBF00C883285 /* [CP] Check Pods Manifest.lock */ = { 179 | isa = PBXShellScriptBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | ); 183 | inputFileListPaths = ( 184 | ); 185 | inputPaths = ( 186 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 187 | "${PODS_ROOT}/Manifest.lock", 188 | ); 189 | name = "[CP] Check Pods Manifest.lock"; 190 | outputFileListPaths = ( 191 | ); 192 | outputPaths = ( 193 | "$(DERIVED_FILE_DIR)/Pods-RNBackgroundActions-checkManifestLockResult.txt", 194 | ); 195 | runOnlyForDeploymentPostprocessing = 0; 196 | shellPath = /bin/sh; 197 | 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"; 198 | showEnvVarsInLog = 0; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 58B511D71A9E6C8500147676 /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | B3E7B58A1CC2AC0600A0062D /* RNBackgroundActions.m in Sources */, 208 | ); 209 | runOnlyForDeploymentPostprocessing = 0; 210 | }; 211 | 6419268E1ECB4257009CF731 /* Sources */ = { 212 | isa = PBXSourcesBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | 6419269B1ECB4266009CF731 /* RNBackgroundActions.m in Sources */, 216 | ); 217 | runOnlyForDeploymentPostprocessing = 0; 218 | }; 219 | /* End PBXSourcesBuildPhase section */ 220 | 221 | /* Begin XCBuildConfiguration section */ 222 | 58B511ED1A9E6C8500147676 /* Debug */ = { 223 | isa = XCBuildConfiguration; 224 | buildSettings = { 225 | ALWAYS_SEARCH_USER_PATHS = NO; 226 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 227 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 228 | CLANG_CXX_LIBRARY = "libc++"; 229 | CLANG_ENABLE_MODULES = YES; 230 | CLANG_ENABLE_OBJC_ARC = YES; 231 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 232 | CLANG_WARN_BOOL_CONVERSION = YES; 233 | CLANG_WARN_COMMA = YES; 234 | CLANG_WARN_CONSTANT_CONVERSION = YES; 235 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 236 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 237 | CLANG_WARN_EMPTY_BODY = YES; 238 | CLANG_WARN_ENUM_CONVERSION = YES; 239 | CLANG_WARN_INFINITE_RECURSION = YES; 240 | CLANG_WARN_INT_CONVERSION = YES; 241 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 242 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 243 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 244 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 245 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 246 | CLANG_WARN_STRICT_PROTOTYPES = YES; 247 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 248 | CLANG_WARN_UNREACHABLE_CODE = YES; 249 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 250 | COPY_PHASE_STRIP = NO; 251 | ENABLE_STRICT_OBJC_MSGSEND = YES; 252 | ENABLE_TESTABILITY = YES; 253 | GCC_C_LANGUAGE_STANDARD = gnu99; 254 | GCC_DYNAMIC_NO_PIC = NO; 255 | GCC_NO_COMMON_BLOCKS = YES; 256 | GCC_OPTIMIZATION_LEVEL = 0; 257 | GCC_PREPROCESSOR_DEFINITIONS = ( 258 | "DEBUG=1", 259 | "$(inherited)", 260 | ); 261 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 262 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 263 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 264 | GCC_WARN_UNDECLARED_SELECTOR = YES; 265 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 266 | GCC_WARN_UNUSED_FUNCTION = YES; 267 | GCC_WARN_UNUSED_VARIABLE = YES; 268 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 269 | MTL_ENABLE_DEBUG_INFO = YES; 270 | ONLY_ACTIVE_ARCH = YES; 271 | SDKROOT = iphoneos; 272 | }; 273 | name = Debug; 274 | }; 275 | 58B511EE1A9E6C8500147676 /* Release */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | ALWAYS_SEARCH_USER_PATHS = NO; 279 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 280 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 281 | CLANG_CXX_LIBRARY = "libc++"; 282 | CLANG_ENABLE_MODULES = YES; 283 | CLANG_ENABLE_OBJC_ARC = YES; 284 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_COMMA = YES; 287 | CLANG_WARN_CONSTANT_CONVERSION = YES; 288 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 289 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 290 | CLANG_WARN_EMPTY_BODY = YES; 291 | CLANG_WARN_ENUM_CONVERSION = YES; 292 | CLANG_WARN_INFINITE_RECURSION = YES; 293 | CLANG_WARN_INT_CONVERSION = YES; 294 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 295 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 296 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 297 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 298 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 299 | CLANG_WARN_STRICT_PROTOTYPES = YES; 300 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 301 | CLANG_WARN_UNREACHABLE_CODE = YES; 302 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 303 | COPY_PHASE_STRIP = YES; 304 | ENABLE_NS_ASSERTIONS = NO; 305 | ENABLE_STRICT_OBJC_MSGSEND = YES; 306 | GCC_C_LANGUAGE_STANDARD = gnu99; 307 | GCC_NO_COMMON_BLOCKS = YES; 308 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 309 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 310 | GCC_WARN_UNDECLARED_SELECTOR = YES; 311 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 312 | GCC_WARN_UNUSED_FUNCTION = YES; 313 | GCC_WARN_UNUSED_VARIABLE = YES; 314 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 315 | MTL_ENABLE_DEBUG_INFO = NO; 316 | SDKROOT = iphoneos; 317 | VALIDATE_PRODUCT = YES; 318 | }; 319 | name = Release; 320 | }; 321 | 58B511F01A9E6C8500147676 /* Debug */ = { 322 | isa = XCBuildConfiguration; 323 | baseConfigurationReference = 71DD9836C50E2FFD2D98ADD0 /* Pods-RNBackgroundActions.debug.xcconfig */; 324 | buildSettings = { 325 | HEADER_SEARCH_PATHS = ( 326 | "$(inherited)", 327 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 328 | "$(SRCROOT)/../../../React/**", 329 | "$(SRCROOT)/../../react-native/React/**", 330 | ); 331 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 332 | OTHER_LDFLAGS = "-ObjC"; 333 | PRODUCT_NAME = RNBackgroundActions; 334 | SKIP_INSTALL = YES; 335 | }; 336 | name = Debug; 337 | }; 338 | 58B511F11A9E6C8500147676 /* Release */ = { 339 | isa = XCBuildConfiguration; 340 | baseConfigurationReference = 5694935E99A79F9E84DE86A2 /* Pods-RNBackgroundActions.release.xcconfig */; 341 | buildSettings = { 342 | HEADER_SEARCH_PATHS = ( 343 | "$(inherited)", 344 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 345 | "$(SRCROOT)/../../../React/**", 346 | "$(SRCROOT)/../../react-native/React/**", 347 | ); 348 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 349 | OTHER_LDFLAGS = "-ObjC"; 350 | PRODUCT_NAME = RNBackgroundActions; 351 | SKIP_INSTALL = YES; 352 | }; 353 | name = Release; 354 | }; 355 | 641926981ECB4257009CF731 /* Debug */ = { 356 | isa = XCBuildConfiguration; 357 | buildSettings = { 358 | CLANG_ANALYZER_NONNULL = YES; 359 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 360 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 361 | CLANG_WARN_INFINITE_RECURSION = YES; 362 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 363 | DEBUG_INFORMATION_FORMAT = dwarf; 364 | ENABLE_TESTABILITY = YES; 365 | GCC_NO_COMMON_BLOCKS = YES; 366 | OTHER_LDFLAGS = "-ObjC"; 367 | PRODUCT_NAME = RNBackgroundActions; 368 | SDKROOT = appletvos; 369 | SKIP_INSTALL = YES; 370 | TVOS_DEPLOYMENT_TARGET = 10.2; 371 | }; 372 | name = Debug; 373 | }; 374 | 641926991ECB4257009CF731 /* Release */ = { 375 | isa = XCBuildConfiguration; 376 | buildSettings = { 377 | CLANG_ANALYZER_NONNULL = YES; 378 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 379 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 380 | CLANG_WARN_INFINITE_RECURSION = YES; 381 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 382 | COPY_PHASE_STRIP = NO; 383 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 384 | GCC_NO_COMMON_BLOCKS = YES; 385 | OTHER_LDFLAGS = "-ObjC"; 386 | PRODUCT_NAME = RNBackgroundActions; 387 | SDKROOT = appletvos; 388 | SKIP_INSTALL = YES; 389 | TVOS_DEPLOYMENT_TARGET = 10.2; 390 | }; 391 | name = Release; 392 | }; 393 | /* End XCBuildConfiguration section */ 394 | 395 | /* Begin XCConfigurationList section */ 396 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNBackgroundActions" */ = { 397 | isa = XCConfigurationList; 398 | buildConfigurations = ( 399 | 58B511ED1A9E6C8500147676 /* Debug */, 400 | 58B511EE1A9E6C8500147676 /* Release */, 401 | ); 402 | defaultConfigurationIsVisible = 0; 403 | defaultConfigurationName = Release; 404 | }; 405 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNBackgroundActions" */ = { 406 | isa = XCConfigurationList; 407 | buildConfigurations = ( 408 | 58B511F01A9E6C8500147676 /* Debug */, 409 | 58B511F11A9E6C8500147676 /* Release */, 410 | ); 411 | defaultConfigurationIsVisible = 0; 412 | defaultConfigurationName = Release; 413 | }; 414 | 6419269A1ECB4257009CF731 /* Build configuration list for PBXNativeTarget "RNBackgroundActions-tvOS" */ = { 415 | isa = XCConfigurationList; 416 | buildConfigurations = ( 417 | 641926981ECB4257009CF731 /* Debug */, 418 | 641926991ECB4257009CF731 /* Release */, 419 | ); 420 | defaultConfigurationIsVisible = 0; 421 | defaultConfigurationName = Release; 422 | }; 423 | /* End XCConfigurationList section */ 424 | }; 425 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 426 | } 427 | --------------------------------------------------------------------------------