├── android ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── reactNativeQuickActions │ │ ├── AppShortcutsPackage.java │ │ ├── UserInfo.java │ │ ├── ShortcutItem.java │ │ └── AppShortcutsModule.java └── build.gradle ├── assets ├── ios.png └── example.png ├── RNQuickAction ├── RNQuickAction.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj └── RNQuickAction │ ├── RNQuickActionManager.h │ └── RNQuickActionManager.m ├── package.json ├── index.d.ts ├── RNQuickAction.podspec ├── index.android.js ├── .npmignore ├── .gitignore ├── LICENSE ├── index.ios.js ├── CONTRIBUTING.md └── README.md /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /assets/ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanbyron/react-native-quick-actions/HEAD/assets/ios.png -------------------------------------------------------------------------------- /assets/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jordanbyron/react-native-quick-actions/HEAD/assets/example.png -------------------------------------------------------------------------------- /RNQuickAction/RNQuickAction.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-quick-actions", 3 | "version": "0.3.13", 4 | "description": "A react-native interface for Touch 3D home screen quick actions", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/jordanbyron/react-native-quick-actions" 8 | }, 9 | "author": "Jordan Byron ", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "react-native": "^0.40" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RNQuickAction/RNQuickAction/RNQuickActionManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RNQuickAction.h 3 | // RNQuickAction 4 | // 5 | // Created by Jordan Byron on 9/26/15. 6 | // Copyright © 2015 react-native. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RNQuickActionManager : NSObject 12 | +(void) onQuickActionPress:(UIApplicationShortcutItem *) shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler; 13 | @end 14 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | def safeExtGet(prop, fallback) { 3 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 4 | } 5 | android { 6 | compileSdkVersion safeExtGet('compileSdkVersion', 25) 7 | buildToolsVersion safeExtGet('buildToolsVersion', '25.0.2') 8 | 9 | defaultConfig { 10 | minSdkVersion safeExtGet('minSdkVersion', 21) 11 | targetSdkVersion safeExtGet('targetSdkVersion', 25) 12 | } 13 | } 14 | 15 | dependencies { 16 | api "com.facebook.react:react-native:+" 17 | } 18 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'react-native-quick-actions' { 2 | 3 | export interface ShortcutItem { 4 | type: string; 5 | title: string; 6 | subtitle?: string; 7 | icon: string; 8 | userInfo: { 9 | url: string 10 | } 11 | } 12 | 13 | export function popInitialAction(): Promise; 14 | 15 | export function setShortcutItems(shortcutItems: Array): void; 16 | 17 | export function clearShortcutItems(): void; 18 | 19 | export function isSupported(callback: (error: Error | any, supported: boolean) => void): void; 20 | } -------------------------------------------------------------------------------- /RNQuickAction.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | version = JSON.parse(File.read('package.json'))["version"] 3 | 4 | Pod::Spec.new do |s| 5 | 6 | s.name = "RNQuickAction" 7 | s.version = version 8 | s.homepage = "https://github.com/jordanbyron/react-native-quick-actions" 9 | s.summary = "A react-native interface for Touch 3D home screen quick actions" 10 | s.license = "MIT" 11 | s.author = { "Jordan Byron" => "jordan.byron@gmail.com" } 12 | s.platform = :ios, "9.0" 13 | s.source = { :git => "https://github.com/jordanbyron/react-native-quick-actions.git", :tag => "#{s.version}" } 14 | s.source_files = 'RNQuickAction/RNQuickAction/*.{h,m}' 15 | s.preserve_paths = "**/*.js" 16 | s.dependency 'React' 17 | 18 | end 19 | -------------------------------------------------------------------------------- /index.android.js: -------------------------------------------------------------------------------- 1 | var ReactAppShortcuts = require('react-native').NativeModules.ReactAppShortcuts; 2 | 3 | module.exports = { 4 | /** 5 | * An initial action will be available if the app was cold-launched 6 | * from an action. 7 | * 8 | * The first caller of `popInitialAction` will get the initial 9 | * action object, or `null`. Subsequent invocations will return null. 10 | */ 11 | popInitialAction: function() { 12 | return ReactAppShortcuts.popInitialAction(); 13 | }, 14 | 15 | /** 16 | * Adds shortcut items to application 17 | */ 18 | setShortcutItems: function(items) { 19 | ReactAppShortcuts.setShortcutItems(items); 20 | }, 21 | 22 | /** 23 | * Clears all previously set dynamic icons 24 | */ 25 | clearShortcutItems: function() { 26 | ReactAppShortcuts.clearShortcutItems(); 27 | }, 28 | 29 | /** 30 | * Check if quick actions are supported 31 | */ 32 | isSupported: function(callback) { 33 | ReactAppShortcuts.isSupported(callback); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | 29 | # CocoaPods 30 | # 31 | # We recommend against adding the Pods directory to your .gitignore. However 32 | # you should judge for yourself, the pros and cons are mentioned at: 33 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 34 | # 35 | #Pods/ 36 | 37 | # Carthage 38 | # 39 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 40 | # Carthage/Checkouts 41 | 42 | Carthage/Build 43 | 44 | node_modules/**/* 45 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactNativeQuickActions/AppShortcutsPackage.java: -------------------------------------------------------------------------------- 1 | package com.reactNativeQuickActions; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | public class AppShortcutsPackage implements ReactPackage { 13 | 14 | @Override 15 | public List createNativeModules(ReactApplicationContext reactContext) { 16 | return Collections.singletonList(new AppShortcutsModule(reactContext)); 17 | } 18 | 19 | public List> createJSModules() { 20 | return Collections.emptyList(); 21 | } 22 | 23 | @Override 24 | public List createViewManagers(ReactApplicationContext reactContext) { 25 | return Collections.emptyList(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Android Studio 6 | *.iml 7 | .idea 8 | .gradle 9 | local.properties 10 | 11 | ## Build generated 12 | build/ 13 | DerivedData 14 | 15 | ## Various settings 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata 25 | 26 | ## Other 27 | *.xccheckout 28 | *.moved-aside 29 | *.xcuserstate 30 | 31 | ## Obj-C/Swift specific 32 | *.hmap 33 | *.ipa 34 | 35 | # CocoaPods 36 | # 37 | # We recommend against adding the Pods directory to your .gitignore. However 38 | # you should judge for yourself, the pros and cons are mentioned at: 39 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 40 | # 41 | #Pods/ 42 | 43 | # Carthage 44 | # 45 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 46 | # Carthage/Checkouts 47 | 48 | Carthage/Build 49 | 50 | node_modules/**/* 51 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactNativeQuickActions/UserInfo.java: -------------------------------------------------------------------------------- 1 | package com.reactNativeQuickActions; 2 | 3 | import android.os.PersistableBundle; 4 | 5 | import com.facebook.react.bridge.Arguments; 6 | import com.facebook.react.bridge.ReadableMap; 7 | import com.facebook.react.bridge.WritableMap; 8 | 9 | class UserInfo { 10 | 11 | private String url; 12 | 13 | static UserInfo fromReadableMap(ReadableMap map) { 14 | final UserInfo info = new UserInfo(); 15 | info.url = map.getString("url"); 16 | return info; 17 | } 18 | 19 | static UserInfo fromPersistableBundle(PersistableBundle bundle) { 20 | final UserInfo info = new UserInfo(); 21 | info.url = bundle.getString("url"); 22 | return info; 23 | } 24 | 25 | PersistableBundle toPersistableBundle() { 26 | PersistableBundle bundle = new PersistableBundle(); 27 | bundle.putString("url", url); 28 | return bundle; 29 | } 30 | 31 | WritableMap toWritableMap() { 32 | WritableMap map = Arguments.createMap(); 33 | map.putString("url", url); 34 | return map; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jordan Byron (http://github.com/jordanbyron/) 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.ios.js: -------------------------------------------------------------------------------- 1 | var RNQuickActionManager = require('react-native').NativeModules.RNQuickActionManager; 2 | var _initialAction = RNQuickActionManager && RNQuickActionManager.initialAction; 3 | 4 | module.exports = { 5 | /** 6 | * An initial action will be available if the app was cold-launched 7 | * from an action. 8 | * 9 | * The first caller of `popInitialAction` will get the initial 10 | * action object, or `null`. Subsequent invocations will return null. 11 | */ 12 | popInitialAction: function() { 13 | return new Promise((resolve) => { 14 | var initialAction = _initialAction; 15 | _initialAction = null; 16 | resolve(initialAction); 17 | }) 18 | }, 19 | 20 | /** 21 | * Adds shortcut items to application 22 | */ 23 | setShortcutItems: function(items) { 24 | RNQuickActionManager.setShortcutItems(items); 25 | }, 26 | 27 | /** 28 | * Clears all previously set dynamic icons 29 | */ 30 | clearShortcutItems: function() { 31 | RNQuickActionManager.clearShortcutItems(); 32 | }, 33 | 34 | /** 35 | * Check if quick actions are supported 36 | */ 37 | isSupported: function(callback) { 38 | RNQuickActionManager.isSupported(callback); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactNativeQuickActions/ShortcutItem.java: -------------------------------------------------------------------------------- 1 | package com.reactNativeQuickActions; 2 | 3 | import android.os.PersistableBundle; 4 | 5 | import com.facebook.react.bridge.Arguments; 6 | import com.facebook.react.bridge.ReadableMap; 7 | import com.facebook.react.bridge.WritableMap; 8 | 9 | class ShortcutItem { 10 | String type; 11 | String title; 12 | String icon; 13 | UserInfo userInfo; 14 | 15 | static ShortcutItem fromReadableMap(ReadableMap map) { 16 | final ShortcutItem item = new ShortcutItem(); 17 | item.type = map.getString("type"); 18 | item.title = map.getString("title"); 19 | item.icon = map.getString("icon"); 20 | item.userInfo = UserInfo.fromReadableMap(map.getMap("userInfo")); 21 | return item; 22 | } 23 | 24 | static ShortcutItem fromPersistableBundle(PersistableBundle bundle) { 25 | final ShortcutItem item = new ShortcutItem(); 26 | item.type = bundle.getString("type"); 27 | item.title = bundle.getString("title"); 28 | item.icon = bundle.getString("icon"); 29 | item.userInfo = UserInfo.fromPersistableBundle(bundle.getPersistableBundle("userInfo")); 30 | return item; 31 | } 32 | 33 | PersistableBundle toPersistableBundle() { 34 | PersistableBundle bundle = new PersistableBundle(); 35 | bundle.putString("type", type); 36 | bundle.putString("title", title); 37 | bundle.putString("icon", icon); 38 | bundle.putPersistableBundle("userInfo", userInfo.toPersistableBundle()); 39 | return bundle; 40 | } 41 | 42 | WritableMap toWritableMap() { 43 | WritableMap map = Arguments.createMap(); 44 | map.putString("type", type); 45 | map.putString("title", title); 46 | map.putString("icon", icon); 47 | map.putMap("userInfo", userInfo.toWritableMap()); 48 | return map; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to this project 2 | 3 | Please take a moment to review this document in order to make the contribution 4 | process easy and effective for everyone involved. 5 | 6 | Following these guidelines helps to communicate that you respect the time of 7 | the developers managing and developing this open source project. In return, 8 | they should reciprocate that respect in addressing your issue or assessing 9 | patches and features. 10 | 11 | 12 | ## Using the issue tracker 13 | 14 | The issue tracker is the preferred channel for [bug reports](#bugs), 15 | [features requests](#features) and [submitting pull 16 | requests](#pull-requests), but please respect the following restrictions: 17 | 18 | * Please **do not** use the issue tracker for personal support requests (use 19 | [Stack Overflow](http://stackoverflow.com) or an equivalent support community). 20 | 21 | * Please **do not** derail or troll issues. Keep the discussion on topic and 22 | respect the opinions of others. 23 | 24 | 25 | 26 | ## Bug reports 27 | 28 | A bug is a _demonstrable problem_ that is caused by the code in the repository. 29 | Good bug reports are extremely helpful - thank you! 30 | 31 | Guidelines for bug reports: 32 | 33 | 1. **Use the GitHub issue search** — check if the issue has already been 34 | reported. 35 | 36 | 2. **Check if the issue has been fixed** — try to reproduce it using the 37 | latest `master` or development branch in the repository. 38 | 39 | 3. **Isolate the problem** — create a [reduced test 40 | case](http://css-tricks.com/reduced-test-cases/) and a live example. 41 | 42 | A good bug report shouldn't leave others needing to chase you up for more 43 | information. Please try to be as detailed as possible in your report. What is 44 | your environment? What steps will reproduce the issue? What browser(s) and OS 45 | experience the problem? What would you expect to be the outcome? All these 46 | details will help people to fix any potential bugs. 47 | 48 | Example: 49 | 50 | > Short and descriptive example bug report title 51 | > 52 | > A summary of the issue and the browser/OS environment in which it occurs. If 53 | > suitable, include the steps required to reproduce the bug. 54 | > 55 | > 1. This is the first step 56 | > 2. This is the second step 57 | > 3. Further steps, etc. 58 | > 59 | > `` - a link to the reduced test case 60 | > 61 | > Any other information you want to share that is relevant to the issue being 62 | > reported. This might include the lines of code that you have identified as 63 | > causing the bug, and potential solutions (and your opinions on their 64 | > merits). 65 | 66 | 67 | 68 | ## Feature requests 69 | 70 | Feature requests are welcome. But take a moment to find out whether your idea 71 | fits with the scope and aims of the project. It's up to *you* to make a strong 72 | case to convince the project's developers of the merits of this feature. Please 73 | provide as much detail and context as possible. 74 | 75 | 76 | 77 | ## Pull requests 78 | 79 | Good pull requests - patches, improvements, new features - are a fantastic 80 | help. They should remain focused in scope and avoid containing unrelated 81 | commits. 82 | 83 | **Please ask first** before embarking on any significant pull request (e.g. 84 | implementing features, refactoring code, porting to a different language), 85 | otherwise you risk spending a lot of time working on something that the 86 | project's developers might not want to merge into the project. 87 | 88 | Please adhere to the coding conventions used throughout a project (indentation, 89 | accurate comments, etc.) and any other requirements (such as test coverage). 90 | 91 | Follow this process if you'd like your work considered for inclusion in the 92 | project: 93 | 94 | 1. [Fork](http://help.github.com/fork-a-repo/) the project, clone your fork, 95 | and configure the remotes: 96 | 97 | ```bash 98 | # Clone your fork of the repo into the current directory 99 | git clone https://github.com//react-native-quick-actions 100 | # Navigate to the newly cloned directory 101 | cd react-native-quick-actions 102 | # Assign the original repo to a remote called "upstream" 103 | git remote add upstream https://github.com/jordanbyron/react-native-quick-actions 104 | ``` 105 | 106 | 2. If you cloned a while ago, get the latest changes from upstream: 107 | 108 | ```bash 109 | git checkout 110 | git pull upstream 111 | ``` 112 | 113 | 3. Create a new topic branch (off the main project development branch) to 114 | contain your feature, change, or fix: 115 | 116 | ```bash 117 | git checkout -b 118 | ``` 119 | 120 | 4. Commit your changes in logical chunks. Please adhere to these [git commit 121 | message guidelines](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) 122 | or your code is unlikely be merged into the main project. Use Git's 123 | [interactive rebase](https://help.github.com/articles/interactive-rebase) 124 | feature to tidy up your commits before making them public. 125 | 126 | 5. Locally merge (or rebase) the upstream development branch into your topic branch: 127 | 128 | ```bash 129 | git pull [--rebase] upstream 130 | ``` 131 | 132 | 6. Push your topic branch up to your fork: 133 | 134 | ```bash 135 | git push origin 136 | ``` 137 | 138 | 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) 139 | with a clear title and description. 140 | 141 | **IMPORTANT**: By submitting a patch, you agree to allow the project owner to 142 | license your work under the same license as that used by the project. 143 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactNativeQuickActions/AppShortcutsModule.java: -------------------------------------------------------------------------------- 1 | package com.reactNativeQuickActions; 2 | 3 | import android.annotation.TargetApi; 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.pm.ShortcutInfo; 8 | import android.content.pm.ShortcutManager; 9 | import android.graphics.drawable.Icon; 10 | import android.os.Build; 11 | import android.os.PersistableBundle; 12 | 13 | import com.facebook.react.bridge.ActivityEventListener; 14 | import com.facebook.react.bridge.Callback; 15 | import com.facebook.react.bridge.JSApplicationIllegalArgumentException; 16 | import com.facebook.react.bridge.Promise; 17 | import com.facebook.react.bridge.ReactApplicationContext; 18 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 19 | import com.facebook.react.bridge.ReactMethod; 20 | import com.facebook.react.bridge.ReadableArray; 21 | import com.facebook.react.bridge.WritableMap; 22 | import com.facebook.react.module.annotations.ReactModule; 23 | import com.facebook.react.modules.core.DeviceEventManagerModule; 24 | 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | @ReactModule(name = AppShortcutsModule.REACT_NAME) 29 | class AppShortcutsModule extends ReactContextBaseJavaModule { 30 | 31 | static final String REACT_NAME = "ReactAppShortcuts"; 32 | 33 | private static final String ACTION_SHORTCUT = "ACTION_SHORTCUT"; 34 | private static final String SHORTCUT_ITEM = "SHORTCUT_ITEM"; 35 | 36 | AppShortcutsModule(ReactApplicationContext reactContext) { 37 | super(reactContext); 38 | 39 | reactContext.addActivityEventListener(new ActivityEventListener() { 40 | @Override 41 | public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) { 42 | // Do nothing 43 | } 44 | 45 | @Override 46 | public void onNewIntent(Intent intent) { 47 | sendJSEvent(intent); 48 | } 49 | }); 50 | } 51 | 52 | @Override 53 | public String getName() { 54 | return REACT_NAME; 55 | } 56 | 57 | @ReactMethod 58 | @TargetApi(25) 59 | public void popInitialAction(Promise promise) { 60 | try { 61 | Activity currentActivity = getCurrentActivity(); 62 | WritableMap map = null; 63 | 64 | if (currentActivity != null) { 65 | Intent intent = currentActivity.getIntent(); 66 | 67 | if (ACTION_SHORTCUT.equals(intent.getAction())) { 68 | PersistableBundle bundle = intent.getParcelableExtra(SHORTCUT_ITEM); 69 | if (bundle != null) { 70 | ShortcutItem item = ShortcutItem.fromPersistableBundle(bundle); 71 | map = item.toWritableMap(); 72 | } 73 | } 74 | } 75 | 76 | promise.resolve(map); 77 | } catch (Exception e) { 78 | promise.reject(new JSApplicationIllegalArgumentException( 79 | "AppShortcuts.popInitialAction error. " + e.getMessage())); 80 | } 81 | } 82 | 83 | @ReactMethod 84 | @TargetApi(25) 85 | public void setShortcutItems(ReadableArray items) { 86 | if (!isShortcutSupported() || items.size() == 0) { 87 | return; 88 | } 89 | 90 | Activity currentActivity = getCurrentActivity(); 91 | if (currentActivity == null) { 92 | return; 93 | } 94 | 95 | Context context = getReactApplicationContext(); 96 | List shortcuts = new ArrayList<>(items.size()); 97 | 98 | for (int i = 0; i < items.size(); i++) { 99 | ShortcutItem item = ShortcutItem.fromReadableMap(items.getMap(i)); 100 | 101 | int iconResId = context.getResources() 102 | .getIdentifier(item.icon, "drawable", context.getPackageName()); 103 | Intent intent = new Intent(context, currentActivity.getClass()); 104 | intent.setAction(ACTION_SHORTCUT); 105 | intent.putExtra(SHORTCUT_ITEM, item.toPersistableBundle()); 106 | 107 | shortcuts.add(new ShortcutInfo.Builder(context, "id" + i) 108 | .setShortLabel(item.title) 109 | .setLongLabel(item.title) 110 | .setIcon(Icon.createWithResource(context, iconResId)) 111 | .setIntent(intent) 112 | .build()); 113 | } 114 | 115 | getReactApplicationContext().getSystemService(ShortcutManager.class).setDynamicShortcuts(shortcuts); 116 | } 117 | 118 | @ReactMethod 119 | @TargetApi(25) 120 | public void clearShortcutItems() { 121 | if (!isShortcutSupported()) { 122 | return; 123 | } 124 | 125 | getReactApplicationContext().getSystemService(ShortcutManager.class).removeAllDynamicShortcuts(); 126 | } 127 | 128 | @ReactMethod 129 | public void isSupported(Callback callback) { 130 | if (callback != null) { 131 | callback.invoke(null, isShortcutSupported()); 132 | } 133 | } 134 | 135 | private boolean isShortcutSupported() { 136 | return Build.VERSION.SDK_INT >= 25; 137 | } 138 | 139 | private void sendJSEvent(Intent intent) { 140 | if (!ACTION_SHORTCUT.equals(intent.getAction()) || !isShortcutSupported()) { 141 | return; 142 | } 143 | 144 | ShortcutItem item = null; 145 | PersistableBundle bundle = intent.getParcelableExtra(SHORTCUT_ITEM); 146 | if (bundle != null) { 147 | item = ShortcutItem.fromPersistableBundle(bundle); 148 | } 149 | if (item != null) { 150 | getReactApplicationContext() 151 | .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) 152 | .emit("quickActionShortcut", item.toWritableMap()); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native Quick Actions 2 | 3 | Support for the new 3D Touch home screen quick actions for your React Native apps! 4 | 5 | **This project currently supports iOS 9+ and Android 7** 6 | 7 | ![](/assets/example.png) 8 | 9 | ## Installing 10 | 11 | ```bash 12 | $ yarn add react-native-quick-actions 13 | $ react-native link react-native-quick-actions 14 | ``` 15 | 16 | ### Additional steps on iOS 17 | 18 | Add the following lines to your `AppDelegate.m` file: 19 | 20 | ```obj-c 21 | #import "RNQuickActionManager.h" 22 | 23 | // @implementation AppDelegate 24 | 25 | - (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler { 26 | [RNQuickActionManager onQuickActionPress:shortcutItem completionHandler:completionHandler]; 27 | } 28 | 29 | // @end 30 | ``` 31 | 32 | ### Manual Linking on Android 33 | 34 | Add the following to `app/build.gradle` within the `dependencies { ... }` section 35 | 36 | ```java 37 | implementation project(':react-native-quick-actions') 38 | ```` 39 | 40 | Add `import com.reactNativeQuickActions.AppShortcutsPackage;` to your `MainApplication.java` 41 | 42 | Also add `new AppShortcutsPackage()` within the 43 | 44 | ```java 45 | public List createAdditionalReactPackages() { 46 | return Arrays.asList( 47 | ... 48 | ); 49 | } 50 | ``` 51 | section of `MainApplication.java` 52 | 53 | ## Usage 54 | 55 | ### Adding static quick actions - iOS only 56 | 57 | Add these entries into to your `Info.plist` file and replace the generic stuff (Action Title, .action, etc): 58 | 59 | ```xml 60 | UIApplicationShortcutItems 61 | 62 | 63 | UIApplicationShortcutItemIconType 64 | UIApplicationShortcutIconTypeLocation 65 | UIApplicationShortcutItemTitle 66 | Action Title 67 | UIApplicationShortcutItemType 68 | $(PRODUCT_BUNDLE_IDENTIFIER).action 69 | 70 | 71 | ``` 72 | 73 | A full list of available icons can be found here: 74 | 75 | 76 | 77 | ### Adding dynamic quick actions 78 | 79 | In order to add / remove dynamic actions during application lifecycle, you need to import `react-native-quick-actions` and call either `setShortcutItems` to set actions or `clearShortcutItems` to clear. 80 | 81 | ```js 82 | import QuickActions from "react-native-quick-actions"; 83 | 84 | QuickActions.setShortcutItems([ 85 | { 86 | type: "Orders", // Required 87 | title: "See your orders", // Optional, if empty, `type` will be used instead 88 | subtitle: "See orders you've made", 89 | icon: "Compose", // Icons instructions below 90 | userInfo: { 91 | url: "app://orders" // Provide any custom data like deep linking URL 92 | } 93 | } 94 | ]); 95 | ``` 96 | 97 | **NOTE** Currently android only supports a `url` key in `userInfo`. No other keys are supported. See [#93](https://github.com/jordanbyron/react-native-quick-actions/issues/93) for more information. 98 | 99 | To clear actions: 100 | 101 | ```js 102 | QuickActions.clearShortcutItems(); 103 | ``` 104 | 105 | #### Icons 106 | 107 | ##### iOS 108 | 109 | On iOS you can use the default icons provided by Apple, they're listed here: https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/system-icons/#quick-action-icons 110 | 111 | You can also use custom icons creating new Image set inside Image.xcassets on XCode. You'll need to define the 1x, 2x and 3x sizes. 112 | 113 | ![](/assets/ios.png) 114 | 115 | ##### Android 116 | 117 | On Android you'll need to create an image file (use PNG) inside `android/app/src/main/res/drawable`. 118 | 119 | Name the image with underscores, don't use hyphens. 120 | 121 | ### Listening for quick actions 122 | 123 | First, you'll need to make sure `DeviceEventEmitter` is added to the list of 124 | requires for React Native. 125 | 126 | ```js 127 | import { DeviceEventEmitter } from "react-native"; 128 | ``` 129 | 130 | Use `DeviceEventEmitter` to listen for `quickActionShortcut` messages. 131 | 132 | ```js 133 | DeviceEventEmitter.addListener("quickActionShortcut", data => { 134 | console.log(data.title); 135 | console.log(data.type); 136 | console.log(data.userInfo); 137 | }); 138 | ``` 139 | 140 | To get any actions sent when the app is cold-launched using the following code: 141 | 142 | ```js 143 | import QuickActions from "react-native-quick-actions"; 144 | 145 | function doSomethingWithTheAction(data) { 146 | console.log(data.title); 147 | console.log(data.type); 148 | console.log(data.userInfo); 149 | } 150 | 151 | QuickActions.popInitialAction() 152 | .then(doSomethingWithTheAction) 153 | .catch(console.error); 154 | ``` 155 | 156 | Please note that on Android if android:launchMode is set to default value standard in AndroidManifest.xml, the app will be re-created each time when app is being brought back from background and it won't receive quickActionShortcut event from DeviceEventEmitter, instead popInitialAction will be receiving the app shortcut event. 157 | 158 | ### Check if 3D Touch is supported 159 | 160 | The following function will alert you if the user's device supports 3D Touch. Please 161 | note this project currently only supports iOS 9+ which means this code will not 162 | work on iOS devices running versions < 9.0. 163 | 164 | ```js 165 | import QuickActions from "react-native-quick-actions"; 166 | 167 | QuickActions.isSupported((error, supported) => { 168 | if (!supported) { 169 | console.log("Device does not support 3D Touch or 3D Touch is disabled."); 170 | } 171 | }); 172 | ``` 173 | 174 | ## License 175 | 176 | Copyright (c) 2015 Jordan Byron (http://github.com/jordanbyron/) 177 | 178 | Permission is hereby granted, free of charge, to any person obtaining a copy 179 | of this software and associated documentation files (the "Software"), to deal 180 | in the Software without restriction, including without limitation the rights 181 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 182 | copies of the Software, and to permit persons to whom the Software is 183 | furnished to do so, subject to the following conditions: 184 | 185 | The above copyright notice and this permission notice shall be included in 186 | all copies or substantial portions of the Software. 187 | 188 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 189 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 190 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 191 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 192 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 193 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 194 | THE SOFTWARE. 195 | -------------------------------------------------------------------------------- /RNQuickAction/RNQuickAction/RNQuickActionManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // RNQuickAction.m 3 | // RNQuickAction 4 | // 5 | // Created by Jordan Byron on 9/26/15. 6 | // Copyright © 2015 react-native. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import "RNQuickActionManager.h" 14 | 15 | NSString *const RCTShortcutItemClicked = @"ShortcutItemClicked"; 16 | 17 | NSDictionary *RNQuickAction(UIApplicationShortcutItem *item) { 18 | if (!item) return nil; 19 | return @{ 20 | @"type": item.type, 21 | @"title": item.localizedTitle, 22 | @"userInfo": item.userInfo ?: @{} 23 | }; 24 | } 25 | 26 | @implementation RNQuickActionManager 27 | { 28 | UIApplicationShortcutItem *_initialAction; 29 | } 30 | 31 | RCT_EXPORT_MODULE(); 32 | 33 | @synthesize bridge = _bridge; 34 | 35 | - (instancetype)init 36 | { 37 | if ((self = [super init])) { 38 | [[NSNotificationCenter defaultCenter] addObserver:self 39 | selector:@selector(handleQuickActionPress:) 40 | name:RCTShortcutItemClicked 41 | object:nil]; 42 | } 43 | return self; 44 | } 45 | 46 | - (dispatch_queue_t)methodQueue { 47 | return dispatch_get_main_queue(); 48 | } 49 | 50 | + (BOOL)requiresMainQueueSetup { 51 | return YES; 52 | } 53 | 54 | - (void)dealloc 55 | { 56 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 57 | } 58 | 59 | - (void)setBridge:(RCTBridge *)bridge 60 | { 61 | _bridge = bridge; 62 | _initialAction = [bridge.launchOptions[UIApplicationLaunchOptionsShortcutItemKey] copy]; 63 | } 64 | 65 | // Map user passed array of UIApplicationShortcutItem 66 | - (NSArray*)dynamicShortcutItemsForPassedArray:(NSArray*)passedArray { 67 | // FIXME: Dynamically map icons from UIApplicationShortcutIconType to / from their string counterparts 68 | // so we don't have to update this list every time Apple adds new system icons. 69 | NSDictionary *icons = @{ 70 | @"Compose": @(UIApplicationShortcutIconTypeCompose), 71 | @"Play": @(UIApplicationShortcutIconTypePlay), 72 | @"Pause": @(UIApplicationShortcutIconTypePause), 73 | @"Add": @(UIApplicationShortcutIconTypeAdd), 74 | @"Location": @(UIApplicationShortcutIconTypeLocation), 75 | @"Search": @(UIApplicationShortcutIconTypeSearch), 76 | @"Share": @(UIApplicationShortcutIconTypeShare), 77 | @"Prohibit": @(UIApplicationShortcutIconTypeProhibit), 78 | @"Contact": @(UIApplicationShortcutIconTypeContact), 79 | @"Home": @(UIApplicationShortcutIconTypeHome), 80 | @"MarkLocation": @(UIApplicationShortcutIconTypeMarkLocation), 81 | @"Favorite": @(UIApplicationShortcutIconTypeFavorite), 82 | @"Love": @(UIApplicationShortcutIconTypeLove), 83 | @"Cloud": @(UIApplicationShortcutIconTypeCloud), 84 | @"Invitation": @(UIApplicationShortcutIconTypeInvitation), 85 | @"Confirmation": @(UIApplicationShortcutIconTypeConfirmation), 86 | @"Mail": @(UIApplicationShortcutIconTypeMail), 87 | @"Message": @(UIApplicationShortcutIconTypeMessage), 88 | @"Date": @(UIApplicationShortcutIconTypeDate), 89 | @"Time": @(UIApplicationShortcutIconTypeTime), 90 | @"CapturePhoto": @(UIApplicationShortcutIconTypeCapturePhoto), 91 | @"CaptureVideo": @(UIApplicationShortcutIconTypeCaptureVideo), 92 | @"Task": @(UIApplicationShortcutIconTypeTask), 93 | @"TaskCompleted": @(UIApplicationShortcutIconTypeTaskCompleted), 94 | @"Alarm": @(UIApplicationShortcutIconTypeAlarm), 95 | @"Bookmark": @(UIApplicationShortcutIconTypeBookmark), 96 | @"Shuffle": @(UIApplicationShortcutIconTypeShuffle), 97 | @"Audio": @(UIApplicationShortcutIconTypeAudio), 98 | @"Update": @(UIApplicationShortcutIconTypeUpdate) 99 | }; 100 | 101 | NSMutableArray *shortcutItems = [NSMutableArray new]; 102 | 103 | [passedArray enumerateObjectsUsingBlock:^(NSDictionary *item, NSUInteger idx, BOOL *stop) { 104 | NSString *iconName = item[@"icon"]; 105 | 106 | // If passed iconName is enum, use system icon 107 | // Otherwise, load from bundle 108 | UIApplicationShortcutIcon *shortcutIcon; 109 | NSNumber *iconType = icons[iconName]; 110 | 111 | if (iconType) { 112 | shortcutIcon = [UIApplicationShortcutIcon iconWithType:[iconType intValue]]; 113 | } else if (iconName) { 114 | shortcutIcon = [UIApplicationShortcutIcon iconWithTemplateImageName:iconName]; 115 | } 116 | 117 | [shortcutItems addObject:[[UIApplicationShortcutItem alloc] initWithType:item[@"type"] 118 | localizedTitle:item[@"title"] ?: item[@"type"] 119 | localizedSubtitle:item[@"subtitle"] 120 | icon:shortcutIcon 121 | userInfo:item[@"userInfo"]]]; 122 | }]; 123 | 124 | return shortcutItems; 125 | } 126 | 127 | RCT_EXPORT_METHOD(setShortcutItems:(NSArray *) shortcutItems) 128 | { 129 | dispatch_async(dispatch_get_main_queue(), ^{ 130 | NSArray *dynamicShortcuts = [self dynamicShortcutItemsForPassedArray:shortcutItems]; 131 | [UIApplication sharedApplication].shortcutItems = dynamicShortcuts; 132 | }); 133 | } 134 | 135 | RCT_EXPORT_METHOD(isSupported:(RCTResponseSenderBlock)callback) 136 | { 137 | BOOL supported = [[UIApplication sharedApplication].delegate.window.rootViewController.traitCollection forceTouchCapability] == UIForceTouchCapabilityAvailable; 138 | 139 | callback(@[[NSNull null], [NSNumber numberWithBool:supported]]); 140 | } 141 | 142 | RCT_EXPORT_METHOD(clearShortcutItems) 143 | { 144 | [UIApplication sharedApplication].shortcutItems = nil; 145 | } 146 | 147 | + (void)onQuickActionPress:(UIApplicationShortcutItem *) shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler 148 | { 149 | RCTLogInfo(@"[RNQuickAction] Quick action shortcut item pressed: %@", [shortcutItem type]); 150 | 151 | [[NSNotificationCenter defaultCenter] postNotificationName:RCTShortcutItemClicked 152 | object:self 153 | userInfo:RNQuickAction(shortcutItem)]; 154 | 155 | completionHandler(YES); 156 | } 157 | 158 | - (void)handleQuickActionPress:(NSNotification *) notification 159 | { 160 | [_bridge.eventDispatcher sendDeviceEventWithName:@"quickActionShortcut" 161 | body:notification.userInfo]; 162 | } 163 | 164 | - (NSDictionary *)constantsToExport 165 | { 166 | return @{ 167 | @"initialAction": RCTNullIfNil(RNQuickAction(_initialAction)) 168 | }; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /RNQuickAction/RNQuickAction.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AD90517D1BD2EE4A00EFDEBC /* RNQuickActionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = AD90517B1BD2EE4A00EFDEBC /* RNQuickActionManager.m */; settings = {ASSET_TAGS = (); }; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 91090D891BB6C934009AE358 /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = "include/$(PRODUCT_NAME)"; 18 | dstSubfolderSpec = 16; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 0; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 91090D8B1BB6C934009AE358 /* libRNQuickAction.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNQuickAction.a; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | AD90517B1BD2EE4A00EFDEBC /* RNQuickActionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNQuickActionManager.m; sourceTree = ""; }; 28 | AD90517C1BD2EE4A00EFDEBC /* RNQuickActionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNQuickActionManager.h; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 91090D881BB6C934009AE358 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 91090D821BB6C934009AE358 = { 43 | isa = PBXGroup; 44 | children = ( 45 | 91090D8D1BB6C934009AE358 /* RNQuickAction */, 46 | 91090D8C1BB6C934009AE358 /* Products */, 47 | ); 48 | sourceTree = ""; 49 | }; 50 | 91090D8C1BB6C934009AE358 /* Products */ = { 51 | isa = PBXGroup; 52 | children = ( 53 | 91090D8B1BB6C934009AE358 /* libRNQuickAction.a */, 54 | ); 55 | name = Products; 56 | sourceTree = ""; 57 | }; 58 | 91090D8D1BB6C934009AE358 /* RNQuickAction */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | AD90517B1BD2EE4A00EFDEBC /* RNQuickActionManager.m */, 62 | AD90517C1BD2EE4A00EFDEBC /* RNQuickActionManager.h */, 63 | ); 64 | path = RNQuickAction; 65 | sourceTree = ""; 66 | }; 67 | /* End PBXGroup section */ 68 | 69 | /* Begin PBXNativeTarget section */ 70 | 91090D8A1BB6C934009AE358 /* RNQuickAction */ = { 71 | isa = PBXNativeTarget; 72 | buildConfigurationList = 91090D941BB6C934009AE358 /* Build configuration list for PBXNativeTarget "RNQuickAction" */; 73 | buildPhases = ( 74 | 91090D871BB6C934009AE358 /* Sources */, 75 | 91090D881BB6C934009AE358 /* Frameworks */, 76 | 91090D891BB6C934009AE358 /* CopyFiles */, 77 | ); 78 | buildRules = ( 79 | ); 80 | dependencies = ( 81 | ); 82 | name = RNQuickAction; 83 | productName = RNQuickAction; 84 | productReference = 91090D8B1BB6C934009AE358 /* libRNQuickAction.a */; 85 | productType = "com.apple.product-type.library.static"; 86 | }; 87 | /* End PBXNativeTarget section */ 88 | 89 | /* Begin PBXProject section */ 90 | 91090D831BB6C934009AE358 /* Project object */ = { 91 | isa = PBXProject; 92 | attributes = { 93 | LastUpgradeCheck = 0710; 94 | ORGANIZATIONNAME = "react-native"; 95 | TargetAttributes = { 96 | 91090D8A1BB6C934009AE358 = { 97 | CreatedOnToolsVersion = 7.1; 98 | DevelopmentTeam = 468H2V2QVS; 99 | }; 100 | }; 101 | }; 102 | buildConfigurationList = 91090D861BB6C934009AE358 /* Build configuration list for PBXProject "RNQuickAction" */; 103 | compatibilityVersion = "Xcode 3.2"; 104 | developmentRegion = English; 105 | hasScannedForEncodings = 0; 106 | knownRegions = ( 107 | en, 108 | ); 109 | mainGroup = 91090D821BB6C934009AE358; 110 | productRefGroup = 91090D8C1BB6C934009AE358 /* Products */; 111 | projectDirPath = ""; 112 | projectRoot = ""; 113 | targets = ( 114 | 91090D8A1BB6C934009AE358 /* RNQuickAction */, 115 | ); 116 | }; 117 | /* End PBXProject section */ 118 | 119 | /* Begin PBXSourcesBuildPhase section */ 120 | 91090D871BB6C934009AE358 /* Sources */ = { 121 | isa = PBXSourcesBuildPhase; 122 | buildActionMask = 2147483647; 123 | files = ( 124 | AD90517D1BD2EE4A00EFDEBC /* RNQuickActionManager.m in Sources */, 125 | ); 126 | runOnlyForDeploymentPostprocessing = 0; 127 | }; 128 | /* End PBXSourcesBuildPhase section */ 129 | 130 | /* Begin XCBuildConfiguration section */ 131 | 91090D921BB6C934009AE358 /* Debug */ = { 132 | isa = XCBuildConfiguration; 133 | buildSettings = { 134 | ALWAYS_SEARCH_USER_PATHS = NO; 135 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 136 | CLANG_CXX_LIBRARY = "libc++"; 137 | CLANG_ENABLE_MODULES = YES; 138 | CLANG_ENABLE_OBJC_ARC = YES; 139 | CLANG_WARN_BOOL_CONVERSION = YES; 140 | CLANG_WARN_CONSTANT_CONVERSION = YES; 141 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 142 | CLANG_WARN_EMPTY_BODY = YES; 143 | CLANG_WARN_ENUM_CONVERSION = YES; 144 | CLANG_WARN_INT_CONVERSION = YES; 145 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 146 | CLANG_WARN_UNREACHABLE_CODE = YES; 147 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 148 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 149 | COPY_PHASE_STRIP = NO; 150 | DEBUG_INFORMATION_FORMAT = dwarf; 151 | ENABLE_STRICT_OBJC_MSGSEND = YES; 152 | ENABLE_TESTABILITY = YES; 153 | GCC_C_LANGUAGE_STANDARD = gnu99; 154 | GCC_DYNAMIC_NO_PIC = NO; 155 | GCC_NO_COMMON_BLOCKS = YES; 156 | GCC_OPTIMIZATION_LEVEL = 0; 157 | GCC_PREPROCESSOR_DEFINITIONS = ( 158 | "DEBUG=1", 159 | "$(inherited)", 160 | ); 161 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 162 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 163 | GCC_WARN_UNDECLARED_SELECTOR = YES; 164 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 165 | GCC_WARN_UNUSED_FUNCTION = YES; 166 | GCC_WARN_UNUSED_VARIABLE = YES; 167 | HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/React/**"; 168 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 169 | MTL_ENABLE_DEBUG_INFO = YES; 170 | ONLY_ACTIVE_ARCH = YES; 171 | SDKROOT = iphoneos; 172 | }; 173 | name = Debug; 174 | }; 175 | 91090D931BB6C934009AE358 /* Release */ = { 176 | isa = XCBuildConfiguration; 177 | buildSettings = { 178 | ALWAYS_SEARCH_USER_PATHS = NO; 179 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 180 | CLANG_CXX_LIBRARY = "libc++"; 181 | CLANG_ENABLE_MODULES = YES; 182 | CLANG_ENABLE_OBJC_ARC = YES; 183 | CLANG_WARN_BOOL_CONVERSION = YES; 184 | CLANG_WARN_CONSTANT_CONVERSION = YES; 185 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 186 | CLANG_WARN_EMPTY_BODY = YES; 187 | CLANG_WARN_ENUM_CONVERSION = YES; 188 | CLANG_WARN_INT_CONVERSION = YES; 189 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 190 | CLANG_WARN_UNREACHABLE_CODE = YES; 191 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 192 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 193 | COPY_PHASE_STRIP = NO; 194 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 195 | ENABLE_NS_ASSERTIONS = NO; 196 | ENABLE_STRICT_OBJC_MSGSEND = YES; 197 | GCC_C_LANGUAGE_STANDARD = gnu99; 198 | GCC_NO_COMMON_BLOCKS = YES; 199 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 200 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 201 | GCC_WARN_UNDECLARED_SELECTOR = YES; 202 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 203 | GCC_WARN_UNUSED_FUNCTION = YES; 204 | GCC_WARN_UNUSED_VARIABLE = YES; 205 | HEADER_SEARCH_PATHS = "$(SRCROOT)/../node_modules/react-native/React/**"; 206 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 207 | MTL_ENABLE_DEBUG_INFO = NO; 208 | SDKROOT = iphoneos; 209 | VALIDATE_PRODUCT = YES; 210 | }; 211 | name = Release; 212 | }; 213 | 91090D951BB6C934009AE358 /* Debug */ = { 214 | isa = XCBuildConfiguration; 215 | buildSettings = { 216 | HEADER_SEARCH_PATHS = ( 217 | "$(SRCROOT)/../node_modules/react-native/React/**", 218 | "$(SRCROOT)/../../react-native/React/**", 219 | ); 220 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 221 | OTHER_LDFLAGS = "-ObjC"; 222 | PRODUCT_NAME = "$(TARGET_NAME)"; 223 | SKIP_INSTALL = YES; 224 | }; 225 | name = Debug; 226 | }; 227 | 91090D961BB6C934009AE358 /* Release */ = { 228 | isa = XCBuildConfiguration; 229 | buildSettings = { 230 | HEADER_SEARCH_PATHS = ( 231 | "$(SRCROOT)/../node_modules/react-native/React/**", 232 | "$(SRCROOT)/../../react-native/React/**", 233 | ); 234 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 235 | OTHER_LDFLAGS = "-ObjC"; 236 | PRODUCT_NAME = "$(TARGET_NAME)"; 237 | SKIP_INSTALL = YES; 238 | }; 239 | name = Release; 240 | }; 241 | /* End XCBuildConfiguration section */ 242 | 243 | /* Begin XCConfigurationList section */ 244 | 91090D861BB6C934009AE358 /* Build configuration list for PBXProject "RNQuickAction" */ = { 245 | isa = XCConfigurationList; 246 | buildConfigurations = ( 247 | 91090D921BB6C934009AE358 /* Debug */, 248 | 91090D931BB6C934009AE358 /* Release */, 249 | ); 250 | defaultConfigurationIsVisible = 0; 251 | defaultConfigurationName = Release; 252 | }; 253 | 91090D941BB6C934009AE358 /* Build configuration list for PBXNativeTarget "RNQuickAction" */ = { 254 | isa = XCConfigurationList; 255 | buildConfigurations = ( 256 | 91090D951BB6C934009AE358 /* Debug */, 257 | 91090D961BB6C934009AE358 /* Release */, 258 | ); 259 | defaultConfigurationIsVisible = 0; 260 | defaultConfigurationName = Release; 261 | }; 262 | /* End XCConfigurationList section */ 263 | }; 264 | rootObject = 91090D831BB6C934009AE358 /* Project object */; 265 | } 266 | --------------------------------------------------------------------------------