├── .eslintrc
├── .flowconfig
├── .gitignore
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── ReactNativeFabric.podspec
├── android
├── build.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── smixx
│ └── fabric
│ ├── FabricPackage.java
│ ├── SMXAnswers.java
│ └── SMXCrashlytics.java
├── changelog.js
├── circle.yml
├── commitlint.config.js
├── example
├── .babelrc
├── .buckconfig
├── .flowconfig
├── .gitattributes
├── .gitignore
├── .watchmanconfig
├── android
│ ├── app
│ │ ├── BUCK
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ ├── react.gradle
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── MainApplication.java
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ ├── keystores
│ │ ├── BUCK
│ │ └── debug.keystore.properties
│ └── settings.gradle
├── index.android.js
├── index.ios.js
├── ios
│ ├── Crashlytics.framework
│ │ ├── Crashlytics
│ │ ├── Headers
│ │ │ ├── ANSCompatibility.h
│ │ │ ├── Answers.h
│ │ │ ├── CLSAttributes.h
│ │ │ ├── CLSLogging.h
│ │ │ ├── CLSReport.h
│ │ │ ├── CLSStackFrame.h
│ │ │ └── Crashlytics.h
│ │ ├── Info.plist
│ │ ├── Modules
│ │ │ └── module.modulemap
│ │ ├── run
│ │ ├── submit
│ │ └── uploadDSYM
│ ├── Fabric.framework
│ │ ├── Fabric
│ │ ├── Headers
│ │ │ ├── FABAttributes.h
│ │ │ └── Fabric.h
│ │ ├── Info.plist
│ │ ├── Modules
│ │ │ └── module.modulemap
│ │ ├── run
│ │ └── uploadDSYM
│ ├── example-tvOS
│ │ └── Info.plist
│ ├── example-tvOSTests
│ │ └── Info.plist
│ ├── example.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ ├── example-tvOS.xcscheme
│ │ │ └── example.xcscheme
│ ├── example
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── Images.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── main.m
│ └── exampleTests
│ │ ├── Info.plist
│ │ └── exampleTests.m
├── package.json
└── yarn.lock
├── ios
├── SMXCrashlytics.xcodeproj
│ └── project.pbxproj
└── SMXCrashlytics
│ ├── SMXAnswers.h
│ ├── SMXAnswers.m
│ ├── SMXCrashlytics.h
│ └── SMXCrashlytics.m
├── package.json
├── react-native.config.js
├── src
├── Answers.js
├── Crashlytics.js
└── index.js
├── typings
└── react-native-fabric.d.ts
└── yarn.lock
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "env": {
4 | "browser": true,
5 | "node": true,
6 | "jest": true,
7 | "es6": true,
8 | },
9 | "plugins": [
10 | "react",
11 | "react-native",
12 | "flowtype",
13 | "import"
14 | ],
15 | "parserOptions": {
16 | "ecmaVersion": 6,
17 | "sourceType": "module",
18 | "ecmaFeatures": {
19 | "modules": true
20 | }
21 | },
22 | "extends": [
23 | "eslint:recommended",
24 | "plugin:react/recommended",
25 | "plugin:import/errors"
26 | ],
27 | "rules": {
28 | "comma-dangle": [2, "always-multiline"],
29 | "quotes": [2, "single", { "allowTemplateLiterals": true }],
30 | "react/prop-types": 0,
31 | "no-case-declarations": 0,
32 | "react/jsx-no-bind": 0,
33 | "react/display-name": 0,
34 | "new-cap": 0,
35 | "react-native/no-unused-styles": 2,
36 | "react-native/split-platform-components": 0,
37 | "react-native/no-inline-styles": 0,
38 | "react-native/no-color-literals": 0,
39 | "no-unexpected-multiline": 0,
40 | "no-class-assign": 1,
41 | "no-console": 2,
42 | "object-curly-spacing": [1, "always"],
43 | "flowtype/define-flow-type": 1,
44 | "flowtype/use-flow-type": 1,
45 | "import/first": 2,
46 | "import/default": 0,
47 | "no-unused-vars": ["error", { "ignoreRestSiblings": true }],
48 | "import/named": 0,
49 | "import/namespace": [2, { "allowComputed": true }],
50 | "no-extra-boolean-cast": 0,
51 | "import/no-duplicates": 2,
52 | "react/no-deprecated": 0
53 | },
54 | "settings": {
55 | "import/resolver": {
56 | "node": {
57 | "extensions":[
58 | ".js",
59 | ".android.js",
60 | ".ios.js",
61 | ".json"
62 | ]
63 | }
64 | }
65 | },
66 | "globals": {
67 | "__DEV__": true
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | #.*/KeychainExample/*
3 |
4 | # We fork some components by platform.
5 | .*/*.web.js
6 | .*/*.android.js
7 |
8 | # Some modules have their own node_modules with overlap
9 | .*/node_modules/node-haste/.*
10 |
11 | # Ignore react-tools where there are overlaps, but don't ignore anything that
12 | # react-native relies on
13 | .*/node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js
14 | .*/node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js
15 | .*/node_modules/react-tools/src/browser/ui/React.js
16 | .*/node_modules/react-tools/src/core/ReactInstanceHandles.js
17 | .*/node_modules/react-tools/src/event/EventPropagators.js
18 |
19 | # Ignore commoner tests
20 | .*/node_modules/commoner/test/.*
21 |
22 | # See https://github.com/facebook/flow/issues/442
23 | .*/react-tools/node_modules/commoner/lib/reader.js
24 |
25 | # Ignore jest
26 | .*/react-native/node_modules/jest-cli/.*
27 |
28 | [include]
29 |
30 | [libs]
31 | node_modules/react-native/Libraries/react-native/react-native-interface.js
32 |
33 | [options]
34 | module.system=haste
35 |
36 | suppress_type=$FlowIssue
37 | suppress_type=$FlowFixMe
38 | suppress_type=$FixMe
39 |
40 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
41 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-3]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
42 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
43 |
44 | [version]
45 | 0.54.1
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # node-waf configuration
17 | .lock-wscript
18 |
19 | # Compiled binary addons (http://nodejs.org/api/addons.html)
20 | build/Release
21 |
22 | # Dependency directory
23 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
24 | node_modules
25 |
26 | # OSX
27 | .DS_Store
28 |
29 | # Xcode
30 | build/
31 | *.pbxuser
32 | !default.pbxuser
33 | *.mode1v3
34 | !default.mode1v3
35 | *.mode2v3
36 | !default.mode2v3
37 | *.perspectivev3
38 | !default.perspectivev3
39 | xcuserdata
40 | *.xccheckout
41 | *.moved-aside
42 | DerivedData
43 | *.hmap
44 | *.ipa
45 | *.xcuserstate
46 | project.xcworkspace
47 | .idea
48 |
49 | # Idea and Android Studio
50 | *.iml
51 | .idea
52 | .gradle
53 | local.properties
54 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | build/
2 | .idea
3 | example/
4 | android/build
5 | *.iml
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | #### 0.5.2-1 (2018-09-28)
2 |
3 | ##### Documentation Changes
4 |
5 | * fix example hyphen case ([#135](https://github.com/corymsmith/react-native-fabric/pull/135)) ([9ddee63a](https://github.com/corymsmith/react-native-fabric/commit/9ddee63a10665f09ce6674dbca3a9626a877e954))
6 |
7 | ##### New Features
8 |
9 | * **upgrade:** upgrade to latest crashlytics version ([9d432c24](https://github.com/corymsmith/react-native-fabric/commit/9d432c2408236049bb87bd319e3fddf69da6be8c))
10 |
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Cory Smith
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.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-fabric
2 | A React Native library for Fabric, Crashlytics and Answers
3 |
4 | [](https://nodei.co/npm/react-native-fabric/)
5 |
6 |
7 | ## Versioning
8 | - For React Native > 0.40 use version 0.5.1
9 | - For React Native < 0.40 use version 0.3.2
10 |
11 | For Twitter Kit support, see [react-native-fabric-twitterkit](https://github.com/tkporter/react-native-fabric-twitterkit)
12 |
13 | ## Installation
14 |
15 | ### 1. Add Fabric / Crashlytics to your project
16 |
17 | - First, set up Fabric / Crashlytics in your app as instructed on [Fabric.io](https://fabric.io). This includes downloading the fabric app and walking through the setup steps (downloading the SDK, adding it to your project and making some changes to your project).
18 |
19 | ### 2. Add react-native-fabric
20 |
21 | #### Automatically
22 |
23 | `react-native install react-native-fabric`, or with [rnpm](https://github.com/rnpm/rnpm): `rnpm install react-native-fabric`
24 |
25 | React Native / rnpm will automatically link all the necessary libraries for both iOS and Android.
26 |
27 | If the installation goes off without a hitch, you can now skip to the **[Crashlytics Usage section](#crashlytics-usage)** or the **[Answers Usage section](#answers-usage)**.
28 |
29 | #### Manually
30 |
31 | `npm install react-native-fabric --save`
32 |
33 | - Alternatively for Android, if you **don't** use Android studio you can skip the first step and instead follow the steps described in [`Android`](#android) **as well as** the steps in [`Android without Android Studio`](#no_android_studio).
34 |
35 | ##### Manually iOS With CocoaPods support
36 |
37 | - add the following line to Podfile
38 |
39 | `pod 'ReactNativeFabric', :path => '../node_modules/react-native-fabric'`
40 |
41 | ##### Manually iOS Without CocoaPods support
42 |
43 | Download the [Crashlytics
44 | SDK](https://fabric.io/kits/ios/crashlytics/manual-install) and place the two
45 | frameworks in a directory called `Crashlytics` in the `ios` directory. You may
46 | want to add this directory to your `.gitignore` as they take up a decent amount
47 | of space and will slow down Git.
48 |
49 | You will also need to modify the Run Script Phase that you likely added to Build
50 | Phases so that it points to the correct location for the Fabric framework. If
51 | you placed the framework directly under `ios/Crashlytics` as specified above,t
52 | the contents of the script will then be:
53 |
54 | ```
55 | "${SRCROOT}/Crashlytics/Fabric.framework/run" API_KEY API_SECRET
56 | ```
57 |
58 | Then do the following:
59 |
60 | - Open your project in Xcode
61 | - Run ```open node_modules/react-native-fabric/ios```
62 | - Drag `SMXCrashlytics.xcodeproj` into your `Libraries` group
63 | - Select your main project in the navigator to bring up settings
64 | - Under `Build Phases` expand the `Link Binary With Libraries` header
65 | - Scroll down and click the `+` to add a library
66 | - Find and add `libSMXCrashlytics.a` under the `Workspace` group
67 | - ⌘+B
68 |
69 |
70 | ##### Android
71 |
72 | *Note: Android support requires React Native 0.16 or later
73 |
74 | * Edit `android/settings.gradle` to look like this (without the +):
75 |
76 | ```diff
77 | rootProject.name = 'MyApp'
78 |
79 | include ':app'
80 |
81 | + include ':react-native-fabric'
82 | + project(':react-native-fabric').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-fabric/android')
83 | ```
84 |
85 | * Edit `android/app/build.gradle` (note: **app** folder) to look like this:
86 |
87 | ```diff
88 | apply plugin: 'com.android.application'
89 |
90 | android {
91 | ...
92 | }
93 |
94 | dependencies {
95 | compile 'com.android.support:appcompat-v7:23.0.0'
96 | compile 'com.facebook.react:react-native:0.19.+'
97 | + compile project(':react-native-fabric')
98 | }
99 | ```
100 |
101 | * RN < 0.29 - Edit your `MainActivity.java` (deep in `android/app/src/main/java/...`) to look like this (note **two** places to edit):
102 |
103 | ```diff
104 | package com.myapp;
105 |
106 | + import com.smixx.fabric.FabricPackage;
107 |
108 | ....
109 | public class MainActivity extends ReactActivity {
110 | @Override
111 | protected List getPackages() {
112 | return Arrays.asList(
113 | + new FabricPackage(),
114 | new MainReactPackage()
115 | );
116 | }
117 | }
118 | ```
119 |
120 | * RN 0.29+ - Edit your `MainApplication.java` (deep in `android/app/src/main/java/...`) to look like this (note **two** places to edit):
121 |
122 | ```diff
123 | package com.myapp;
124 |
125 | + import com.smixx.fabric.FabricPackage;
126 |
127 | ....
128 | public class MainApplication extends Application implements ReactApplication {
129 | @Override
130 | protected List getPackages() {
131 | return Arrays.asList(
132 | + new FabricPackage(),
133 | new MainReactPackage()
134 | );
135 | }
136 | }
137 | ```
138 |
139 |
140 | ##### Android without Android Studio
141 |
142 | Make sure you also follow the steps described in [`Android`](#android).
143 |
144 | * Edit your `build.gradle` (note: **app** folder) to look like this:
145 |
146 | ```diff
147 | apply plugin: "com.android.application"
148 |
149 | + buildscript {
150 | + repositories {
151 | + maven { url 'https://maven.fabric.io/public' }
152 | + }
153 | + dependencies {
154 | + // The Fabric Gradle plugin uses an open ended version to react
155 | + // quickly to Android tooling updates
156 | + classpath 'io.fabric.tools:gradle:1.+'
157 | + }
158 | + }
159 | + apply plugin: 'io.fabric'
160 | + repositories {
161 | + maven { url 'https://maven.fabric.io/public' }
162 | + }
163 |
164 | [...]
165 |
166 | dependencies {
167 | [...]
168 | + compile('com.crashlytics.sdk.android:crashlytics:2.9.2@aar') {
169 | + transitive = true;
170 | + }
171 | }
172 | ```
173 |
174 | * RN < 0.29 - Edit your `MainActivity.java` (deep in `android/app/src/main/java/...`) to look like this (note **two** places to edit):
175 |
176 | ```diff
177 | + import android.os.Bundle;
178 | + import com.crashlytics.android.Crashlytics;
179 | + import io.fabric.sdk.android.Fabric;
180 |
181 | public class MainActivity extends ReactActivity {
182 |
183 | + @Override
184 | + protected void onCreate(Bundle savedInstanceState) {
185 | + super.onCreate(savedInstanceState);
186 | + Fabric.with(this, new Crashlytics());
187 | + }
188 |
189 | [...]
190 |
191 | }
192 | ```
193 |
194 | * RN 0.29+ - Edit your `MainApplication.java` (deep in `android/app/src/main/java/...`) to look like this (note **two** places to edit):
195 |
196 | ```diff
197 | + import com.crashlytics.android.Crashlytics;
198 | + import io.fabric.sdk.android.Fabric;
199 |
200 | public class MainApplication extends Application implements ReactApplication {
201 |
202 | + @Override
203 | + public void onCreate() {
204 | + super.onCreate();
205 | + Fabric.with(this, new Crashlytics());
206 | + }
207 |
208 | [...]
209 |
210 | }
211 | ```
212 |
213 | * Note: the `onCreate` access privilege goes from `protected` to `public` from RN 0.28+
214 |
215 | * Edit your `AndroidManifest.xml` (in `android/app/src/main/`) to look like this. Make sure to enter your fabric API key after `android:value=`, you can find your key on your fabric organisation page.
216 |
217 | ```diff
218 |
226 |
227 | +
228 |
229 | ```
230 |
231 | ## Crashlytics Usage
232 |
233 | **Note: logging will not be registered on Android to the Fabric dashboard until the app is bundled for release.**
234 |
235 | To see all available methods take a look at [Crashlytics.js](https://github.com/corymsmith/react-native-fabric/blob/master/src/Crashlytics.js)
236 |
237 | ```js
238 | var Fabric = require('react-native-fabric');
239 |
240 | var { Crashlytics } = Fabric;
241 |
242 | Crashlytics.setUserName('megaman');
243 |
244 | Crashlytics.setUserEmail('user@email.com');
245 |
246 | Crashlytics.setUserIdentifier('1234');
247 |
248 | Crashlytics.setBool('has_posted', true);
249 |
250 | Crashlytics.setString('organization', 'Acme. Corp');
251 |
252 | // Forces a native crash for testing
253 | Crashlytics.crash();
254 |
255 | // Due to differences in primitive types between iOS and Android I've exposed a setNumber function vs. setInt, setFloat, setDouble, setLong, etc
256 | Crashlytics.setNumber('post_count', 5);
257 |
258 | // Record a non-fatal JS error only on Android
259 | Crashlytics.logException('');
260 |
261 | // Record a non-fatal JS error only on iOS
262 | Crashlytics.recordError('something went wrong!');
263 |
264 | ```
265 |
266 | ## Answers Usage
267 | To see all available function take a look at [Answers.js](https://github.com/corymsmith/react-native-fabric/blob/master/src/Answers.js)
268 |
269 | ```js
270 | var Fabric = require('react-native-fabric');
271 |
272 | var { Answers } = Fabric;
273 |
274 | // All log functions take an optional object of custom attributes as the last parameter
275 | Answers.logCustom('Performed a custom event', { bigData: true });
276 |
277 | Answers.logContentView('To-Do Edit', 'To-Do', 'to-do-42', { userId: 93 });
278 |
279 | Answers.logAddToCart(24.50, 'USD', 'Air Jordans', 'shoes', '987654', {color: 'red'});
280 |
281 | Answers.logInvite('Facebook');
282 |
283 | Answers.logLogin('Twitter', true);
284 |
285 | Answers.logSearch('React Native');
286 |
287 | Answers.logShare('Twitter', 'Big news article', 'post', '1234');
288 |
289 | Answers.logSignUp('Twitter', true);
290 |
291 | Answers.logPurchase(24.99,'USD',true, 'Air Jordans', 'shoes', '987654');
292 |
293 |
294 | ```
295 |
296 |
297 | ## License
298 | MIT © Cory Smith 2016
299 |
300 |
301 | [rnpm]: https://github.com/rnpm/rnpm
302 |
--------------------------------------------------------------------------------
/ReactNativeFabric.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 = 'ReactNativeFabric'
7 | s.version = package['version']
8 | s.summary = package['description']
9 | s.description = package['description']
10 | s.homepage = package['homepage']
11 | s.license = package['license']
12 | s.author = package['author']
13 | s.source = { :git => 'https://github.com/corymsmith/react-native-fabric.git', :tag => 'v'+s.version.to_s }
14 |
15 | s.ios.deployment_target = '9.0'
16 | s.tvos.deployment_target = '9.0'
17 |
18 | s.dependency 'React'
19 | s.dependency 'Fabric'
20 | s.dependency 'Crashlytics'
21 | s.ios.xcconfig = {
22 | 'FRAMEWORK_SEARCH_PATHS' => '"${PODS_ROOT}/Crashlytics/iOS" "${PODS_ROOT}/Fabric/iOS"',
23 | 'OTHER_LDFLAGS' => '-framework Crashlytics -framework Fabric'
24 | }
25 |
26 | s.preserve_paths = 'README.md', 'LICENSE', 'package.json'
27 | s.source_files = 'ios/**/*.{h,m}'
28 | s.exclude_files = 'android/**/*'
29 | end
30 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | def safeExtGet(prop, fallback) {
2 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
3 | }
4 |
5 | allprojects {
6 | repositories {
7 | mavenCentral()
8 | google()
9 | jcenter() //also add it here!!!
10 | }
11 | }
12 |
13 | buildscript {
14 | repositories {
15 | google()
16 | jcenter()
17 | maven {
18 | url 'https://maven.google.com/'
19 | name 'Google'
20 | }
21 | }
22 |
23 | dependencies {
24 | classpath 'com.android.tools.build:gradle:3.1.4'
25 | }
26 | }
27 |
28 | apply plugin: 'com.android.library'
29 |
30 | android {
31 | compileSdkVersion safeExtGet('compileSdkVersion', 27)
32 | buildToolsVersion safeExtGet('buildToolsVersion', '27.0.3')
33 |
34 | defaultConfig {
35 | minSdkVersion safeExtGet('minSdkVersion', 16)
36 | targetSdkVersion safeExtGet('targetSdkVersion', 26)
37 | versionCode 1
38 | versionName '1.0'
39 | }
40 | lintOptions {
41 | abortOnError false
42 | }
43 | }
44 |
45 | repositories {
46 | mavenCentral()
47 | }
48 |
49 | repositories {
50 | maven { url 'https://maven.fabric.io/public' }
51 | maven {
52 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
53 | url "$rootDir/../node_modules/react-native/android"
54 | }
55 | google()
56 | }
57 |
58 | dependencies {
59 | implementation "com.facebook.react:react-native:${safeExtGet('reactNative', '+')}"
60 | implementation("com.crashlytics.sdk.android:crashlytics:2.9.5@aar") {
61 | transitive = true;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/android/src/main/java/com/smixx/fabric/FabricPackage.java:
--------------------------------------------------------------------------------
1 | package com.smixx.fabric;
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.ArrayList;
10 | import java.util.List;
11 |
12 | public class FabricPackage implements ReactPackage {
13 |
14 | @Override
15 | public List createNativeModules(
16 | ReactApplicationContext reactContext) {
17 | List modules = new ArrayList<>();
18 | modules.add(new SMXCrashlytics(reactContext));
19 | modules.add(new SMXAnswers(reactContext));
20 | return modules;
21 | }
22 |
23 | // Deprecated RN 0.47
24 | public List> createJSModules() {
25 | return new ArrayList<>();
26 | }
27 |
28 | @Override
29 | public List createViewManagers(ReactApplicationContext reactContext) {
30 | return new ArrayList<>();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/android/src/main/java/com/smixx/fabric/SMXAnswers.java:
--------------------------------------------------------------------------------
1 | package com.smixx.fabric;
2 |
3 | import android.app.Activity;
4 | import android.util.Log;
5 |
6 | import com.crashlytics.android.answers.AddToCartEvent;
7 | import com.crashlytics.android.answers.Answers;
8 | import com.crashlytics.android.answers.AnswersEvent;
9 | import com.crashlytics.android.answers.ContentViewEvent;
10 | import com.crashlytics.android.answers.CustomEvent;
11 | import com.crashlytics.android.answers.InviteEvent;
12 | import com.crashlytics.android.answers.LevelEndEvent;
13 | import com.crashlytics.android.answers.LevelStartEvent;
14 | import com.crashlytics.android.answers.LoginEvent;
15 | import com.crashlytics.android.answers.PurchaseEvent;
16 | import com.crashlytics.android.answers.RatingEvent;
17 | import com.crashlytics.android.answers.SearchEvent;
18 | import com.crashlytics.android.answers.ShareEvent;
19 | import com.crashlytics.android.answers.SignUpEvent;
20 | import com.crashlytics.android.answers.StartCheckoutEvent;
21 | import com.facebook.react.bridge.ReactApplicationContext;
22 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
23 | import com.facebook.react.bridge.ReactMethod;
24 | import com.facebook.react.bridge.ReadableMap;
25 | import com.facebook.react.bridge.ReadableMapKeySetIterator;
26 | import com.facebook.react.bridge.ReadableType;
27 |
28 | import java.math.BigDecimal;
29 | import java.util.Currency;
30 |
31 | public class SMXAnswers extends ReactContextBaseJavaModule {
32 | public Activity activity;
33 |
34 | public SMXAnswers(ReactApplicationContext reactContext) {
35 | super(reactContext);
36 | this.activity = getCurrentActivity();
37 | }
38 |
39 | @Override
40 | public String getName() {
41 | return "SMXAnswers";
42 | }
43 |
44 | @ReactMethod
45 | public void logAddToCart(String itemPrice, String currency, String itemName, String itemType, String itemId, ReadableMap customAttributes) {
46 |
47 | AddToCartEvent event = new AddToCartEvent();
48 | if (currency != null)
49 | event.putCurrency(Currency.getInstance(currency));
50 | if (itemPrice != null)
51 | event.putItemPrice(new BigDecimal(itemPrice));
52 | if (itemName != null)
53 | event.putItemName(itemName);
54 | if (itemType != null)
55 | event.putItemType(itemType);
56 | if (itemId != null)
57 | event.putItemId(itemId);
58 | addCustomAttributes(event, customAttributes);
59 | Answers.getInstance().logAddToCart(event);
60 | }
61 |
62 | @ReactMethod
63 | public void logContentView(String contentName, String contentType, String contentId, ReadableMap customAttributes) {
64 | ContentViewEvent event = new ContentViewEvent();
65 | if (contentId != null)
66 | event.putContentId(contentId);
67 | if (contentType != null)
68 | event.putContentType(contentType);
69 | if (contentName != null)
70 | event.putContentName(contentName);
71 |
72 | addCustomAttributes(event, customAttributes);
73 | Answers.getInstance().logContentView(event);
74 | }
75 |
76 | @ReactMethod
77 | public void logCustom(String eventName, ReadableMap customAttributes) {
78 | CustomEvent event = new CustomEvent(eventName);
79 | addCustomAttributes(event, customAttributes);
80 | Answers.getInstance().logCustom(event);
81 | }
82 |
83 | @ReactMethod
84 | public void logInvite(String method, ReadableMap customAttributes) {
85 | InviteEvent event = new InviteEvent();
86 | event.putMethod(method);
87 | addCustomAttributes(event, customAttributes);
88 | Answers.getInstance().logInvite(event);
89 | }
90 |
91 | @ReactMethod
92 | public void logLevelStart(String levelName, ReadableMap customAttributes) {
93 | LevelStartEvent event = new LevelStartEvent();
94 | event.putLevelName(levelName);
95 | addCustomAttributes(event, customAttributes);
96 | Answers.getInstance().logLevelStart(event);
97 | }
98 |
99 | @ReactMethod
100 | public void logLevelEnd(String levelName, String score, boolean success, ReadableMap customAttributes) {
101 | LevelEndEvent event = new LevelEndEvent();
102 | if (levelName != null)
103 | event.putLevelName(levelName);
104 |
105 | event.putSuccess(success);
106 |
107 | if (score != null)
108 | event.putScore(Double.valueOf(score));
109 |
110 | addCustomAttributes(event, customAttributes);
111 | Answers.getInstance().logLevelEnd(event);
112 | }
113 |
114 | @ReactMethod
115 | public void logLogin(String method, boolean success, ReadableMap customAttributes) {
116 | LoginEvent event = new LoginEvent();
117 | event.putMethod(method);
118 | event.putSuccess(success);
119 | addCustomAttributes(event, customAttributes);
120 | Answers.getInstance().logLogin(event);
121 | }
122 |
123 | @ReactMethod
124 | public void logPurchase(String itemPrice, String currency, boolean success, String itemName, String itemType, String itemId, ReadableMap customAttributes) {
125 | PurchaseEvent event = new PurchaseEvent();
126 |
127 | if (currency != null)
128 | event.putCurrency(Currency.getInstance(currency));
129 | if (itemPrice != null)
130 | event.putItemPrice(new BigDecimal(itemPrice));
131 | if (itemName != null)
132 | event.putItemName(itemName);
133 | if (itemType != null)
134 | event.putItemType(itemType);
135 | if (itemId != null)
136 | event.putItemId(itemId);
137 |
138 | event.putSuccess(success);
139 | addCustomAttributes(event, customAttributes);
140 | Answers.getInstance().logPurchase(event);
141 | }
142 |
143 | @ReactMethod
144 | public void logRating(String rating, String contentId, String contentType, String contentName, ReadableMap customAttributes) {
145 | RatingEvent event = new RatingEvent();
146 | event.putRating(Integer.valueOf(rating));
147 |
148 | if (contentId != null)
149 | event.putContentId(contentId);
150 | if (contentType != null)
151 | event.putContentType(contentType);
152 | if (contentName != null)
153 | event.putContentName(contentName);
154 |
155 | addCustomAttributes(event, customAttributes);
156 | Answers.getInstance().logRating(event);
157 | }
158 |
159 | @ReactMethod
160 | public void logSearch(String query, ReadableMap customAttributes) {
161 | SearchEvent event = new SearchEvent();
162 | event.putQuery(query);
163 | addCustomAttributes(event, customAttributes);
164 | Answers.getInstance().logSearch(event);
165 | }
166 |
167 | @ReactMethod
168 | public void logShare(String method, String contentName, String contentType, String contentId, ReadableMap customAttributes) {
169 | ShareEvent event = new ShareEvent();
170 | event.putMethod(method);
171 | if (contentId != null)
172 | event.putContentId(contentId);
173 | if (contentType != null)
174 | event.putContentType(contentType);
175 | if (contentName != null)
176 | event.putContentName(contentName);
177 | addCustomAttributes(event, customAttributes);
178 | Answers.getInstance().logShare(event);
179 | }
180 |
181 | @ReactMethod
182 | public void logSignUp(String method, boolean success, ReadableMap customAttributes) {
183 | SignUpEvent event = new SignUpEvent();
184 | event.putMethod(method);
185 | event.putSuccess(success);
186 | addCustomAttributes(event, customAttributes);
187 | Answers.getInstance().logSignUp(event);
188 | }
189 |
190 | @ReactMethod
191 | public void logStartCheckout(String totalPrice, String count, String currency, ReadableMap customAttributes) {
192 | StartCheckoutEvent event = new StartCheckoutEvent();
193 | if (currency != null)
194 | event.putCurrency(Currency.getInstance(currency));
195 | if (count != null)
196 | event.putItemCount(Integer.valueOf(count));
197 | if (totalPrice != null)
198 | event.putTotalPrice(new BigDecimal(totalPrice));
199 |
200 | addCustomAttributes(event, customAttributes);
201 | Answers.getInstance().logStartCheckout(event);
202 | }
203 |
204 | private void addCustomAttributes(AnswersEvent event, ReadableMap attributes) {
205 | if (attributes != null) {
206 | ReadableMapKeySetIterator itr = attributes.keySetIterator();
207 | while (itr.hasNextKey()) {
208 | String key = itr.nextKey();
209 |
210 | ReadableType type = attributes.getType(key);
211 | switch (type) {
212 | case Boolean:
213 | event.putCustomAttribute(key, String.valueOf(attributes.getBoolean(key)));
214 | break;
215 | case Number:
216 | event.putCustomAttribute(key, attributes.getDouble(key));
217 | break;
218 | case String:
219 | event.putCustomAttribute(key, attributes.getString(key));
220 | break;
221 | case Null:
222 | break;
223 | default:
224 | Log.e("ReactNativeFabric", "Can't add objects or arrays");
225 | }
226 | }
227 | }
228 | }
229 |
230 |
231 | }
232 |
--------------------------------------------------------------------------------
/android/src/main/java/com/smixx/fabric/SMXCrashlytics.java:
--------------------------------------------------------------------------------
1 | package com.smixx.fabric;
2 |
3 | import android.app.Activity;
4 | import android.util.Log;
5 |
6 | import com.crashlytics.android.Crashlytics;
7 | import com.facebook.react.bridge.ReactApplicationContext;
8 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
9 | import com.facebook.react.bridge.ReactMethod;
10 | import com.facebook.react.bridge.ReadableArray;
11 | import com.facebook.react.bridge.ReadableMap;
12 |
13 | public class SMXCrashlytics extends ReactContextBaseJavaModule {
14 | public Activity activity;
15 |
16 | public SMXCrashlytics(ReactApplicationContext reactContext) {
17 | super(reactContext);
18 | this.activity = getCurrentActivity();
19 | }
20 |
21 | @Override
22 | public String getName() {
23 | return "SMXCrashlytics";
24 | }
25 |
26 | @ReactMethod
27 | public void crash() {
28 | Crashlytics.getInstance().crash();
29 | }
30 |
31 | @ReactMethod
32 | public void logException(String value) {
33 | Crashlytics.logException(new RuntimeException(value));
34 | }
35 |
36 | @ReactMethod
37 | public void log(String message) {
38 | Crashlytics.log(message);
39 | }
40 |
41 | @ReactMethod
42 | public void setUserEmail(String email) {
43 | Crashlytics.setUserEmail(email);
44 | }
45 |
46 | @ReactMethod
47 | public void setUserIdentifier(String userIdentifier) {
48 | Crashlytics.setUserIdentifier(userIdentifier);
49 | }
50 |
51 | @ReactMethod
52 | public void setUserName(String userName) {
53 | Crashlytics.setUserName(userName);
54 | }
55 |
56 | @ReactMethod
57 | public void setBool(String key, Boolean value) {
58 | Crashlytics.setBool(key, value);
59 | }
60 |
61 | @ReactMethod
62 | public void setString(String key, String value) {
63 | Crashlytics.setString(key, value);
64 | }
65 |
66 | @ReactMethod
67 | public void setNumber(String key, String numberString) {
68 | try {
69 | Number number = parse(numberString);
70 | if (number.getClass().equals(Double.class)) {
71 | Crashlytics.setDouble(key, number.doubleValue());
72 | } else if (number.getClass().equals(Float.class)) {
73 | Crashlytics.setFloat(key, number.floatValue());
74 | } else if (number.getClass().equals(Integer.class)) {
75 | Crashlytics.setInt(key, number.intValue());
76 | } else if (number.getClass().equals(Long.class)) {
77 | Crashlytics.setLong(key, number.longValue());
78 | }
79 | } catch (Exception ex) {
80 | Log.e("RNFabric:", ex.getMessage());
81 | ex.printStackTrace();
82 | }
83 | }
84 |
85 | @ReactMethod
86 | public void recordCustomExceptionName(String name, String reason, ReadableArray frameArray) {
87 | StackTraceElement[] stackTrace = new StackTraceElement[frameArray.size()];
88 | for (int i = 0; i < frameArray.size(); i++) {
89 | ReadableMap map = frameArray.getMap(i);
90 | String functionName = map.hasKey("functionName") ? map.getString("functionName") : "Unknown Function";
91 | StackTraceElement stack = new StackTraceElement(
92 | "",
93 | functionName,
94 | map.getString("fileName"),
95 | map.hasKey("lineNumber") ? map.getInt("lineNumber") : -1
96 | );
97 | stackTrace[i] = stack;
98 | }
99 | Exception e = new Exception(name + "\n" + reason);
100 | e.setStackTrace(stackTrace);
101 | Crashlytics.logException(e);
102 | }
103 |
104 | private static Number parse(String str) {
105 | Number number = null;
106 |
107 | if (str.contains(".")) {
108 | try {
109 | number = Double.parseDouble(str);
110 | } catch (NumberFormatException e) {
111 | number = Float.parseFloat(str);
112 | }
113 | } else {
114 | try {
115 | number = Integer.parseInt(str);
116 | } catch (NumberFormatException e2) {
117 | try {
118 | number = Long.parseLong(str);
119 | } catch (NumberFormatException e3) {
120 | throw e3;
121 | }
122 | }
123 | }
124 | return number;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/changelog.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const git = require('simple-git');
4 | const changelog = require('generate-changelog');
5 | const fs = require('fs');
6 | const idx = require('idx');
7 | const argv = require('minimist')(process.argv.slice(1));
8 |
9 | git().tags((err, tags) => {
10 | const currentChangelog = fs.readFileSync('./CHANGELOG.md');
11 | const matched = tags.latest.match(/v\d+.\d+.\d+-(\d+)/);
12 | const build = (idx(matched, _ => Number(_[1])) || 0) + 1;
13 |
14 | changelog
15 | .generate({
16 | major: argv.major,
17 | minor: argv.minor,
18 | patch: argv.patch,
19 | })
20 | .then(function(changelog) {
21 | const rxVersion = /\d+\.\d+\.\d+/;
22 | const newVersion = argv.version || idx(changelog.match(rxVersion), _ => _[0]) + `-${build}`;
23 |
24 | changelog = changelog.replace(rxVersion, newVersion) + currentChangelog;
25 | fs.writeFileSync('./CHANGELOG.md', changelog);
26 |
27 | const addFile = c => git().add('CHANGELOG.md', c);
28 | const commit = c => git().commit(`build(change-log): v${newVersion}`, c);
29 | const addTag = c => git().addAnnotatedTag(`v${newVersion}`, `build(tag): v${newVersion}`, c);
30 |
31 | addFile(() => commit(() => addTag()));
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | executorType: docker
3 | jobs:
4 | build:
5 | resource_class: large
6 | environment:
7 | - GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"'
8 | - REACT_NATIVE_MAX_WORKERS: 2
9 | - ANDROID_BUILD_TOOLS_VERSION: "26.0.2"
10 | working_directory: ~/app
11 | docker:
12 | - image: entria/react-native-android:0.1.72
13 | steps:
14 | - checkout
15 | - restore_cache:
16 | keys:
17 | - v1-npm-{{ .Branch }}-{{ checksum "yarn.lock" }}
18 | - v1-npm
19 | - run:
20 | name: Install Dependencies
21 | command: yarn install --ignore-engines
22 | - run:
23 | name: Lint
24 | command: yarn lint
25 | - run:
26 | name: Run Checks
27 | command: |
28 | cd android
29 | chmod +x ./gradlew && ./gradlew check
30 | - save_cache:
31 | key: v1-npm
32 | paths:
33 | - node_modules/
34 | - save_cache:
35 | key: v1-npm-{{ .Branch }}-{{ checksum "yarn.lock" }}
36 | paths:
37 | - node_modules/
38 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | rules: {
3 | 'body-leading-blank': [1, 'always'],
4 | 'footer-leading-blank': [1, 'always'],
5 | 'header-max-length': [2, 'always', 72],
6 | 'scope-case': [2, 'always', 'lower-case'],
7 | 'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
8 | 'subject-empty': [2, 'never'],
9 | 'subject-full-stop': [2, 'never', '.'],
10 | 'type-case': [2, 'always', 'lower-case'],
11 | 'type-empty': [2, 'never'],
12 | 'type-enum': [
13 | 2,
14 | 'always',
15 | [
16 | 'build',
17 | 'chore',
18 | 'ci',
19 | 'docs',
20 | 'feat',
21 | 'fix',
22 | 'perf',
23 | 'refactor',
24 | 'revert',
25 | 'style',
26 | 'test',
27 | ],
28 | ],
29 | },
30 | };
31 |
--------------------------------------------------------------------------------
/example/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["react-native"]
3 | }
4 |
--------------------------------------------------------------------------------
/example/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/example/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | ; We fork some components by platform
3 | .*/*[.]android.js
4 |
5 | ; Ignore "BUCK" generated dirs
6 | /\.buckd/
7 |
8 | ; Ignore unexpected extra "@providesModule"
9 | .*/node_modules/.*/node_modules/fbjs/.*
10 |
11 | ; Ignore duplicate module providers
12 | ; For RN Apps installed via npm, "Libraries" folder is inside
13 | ; "node_modules/react-native" but in the source repo it is in the root
14 | .*/Libraries/react-native/React.js
15 | .*/Libraries/react-native/ReactNative.js
16 |
17 | [include]
18 |
19 | [libs]
20 | node_modules/react-native/Libraries/react-native/react-native-interface.js
21 | node_modules/react-native/flow
22 | flow/
23 |
24 | [options]
25 | emoji=true
26 |
27 | module.system=haste
28 |
29 | experimental.strict_type_args=true
30 |
31 | munge_underscores=true
32 |
33 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
34 |
35 | suppress_type=$FlowIssue
36 | suppress_type=$FlowFixMe
37 | suppress_type=$FixMe
38 |
39 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-2]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
40 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-2]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
41 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
42 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
43 |
44 | unsafe.enable_getters_and_setters=true
45 |
46 | [version]
47 | ^0.42.0
48 |
--------------------------------------------------------------------------------
/example/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/example/.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 | project.xcworkspace
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 |
33 | # node.js
34 | #
35 | node_modules/
36 | npm-debug.log
37 | yarn-error.log
38 |
39 | # BUCK
40 | buck-out/
41 | \.buckd/
42 | *.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://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
50 |
51 | fastlane/report.xml
52 | fastlane/Preview.html
53 | fastlane/screenshots
54 |
--------------------------------------------------------------------------------
/example/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/example/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 | lib_deps = []
12 |
13 | for jarfile in glob(['libs/*.jar']):
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 |
21 | for aarfile in glob(['libs/*.aar']):
22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
23 | lib_deps.append(':' + name)
24 | android_prebuilt_aar(
25 | name = name,
26 | aar = aarfile,
27 | )
28 |
29 | android_library(
30 | name = "all-libs",
31 | exported_deps = lib_deps,
32 | )
33 |
34 | android_library(
35 | name = "app-code",
36 | srcs = glob([
37 | "src/main/java/**/*.java",
38 | ]),
39 | deps = [
40 | ":all-libs",
41 | ":build_config",
42 | ":res",
43 | ],
44 | )
45 |
46 | android_build_config(
47 | name = "build_config",
48 | package = "com.example",
49 | )
50 |
51 | android_resource(
52 | name = "res",
53 | package = "com.example",
54 | res = "src/main/res",
55 | )
56 |
57 | android_binary(
58 | name = "app",
59 | keystore = "//android/keystores:debug",
60 | manifest = "src/main/AndroidManifest.xml",
61 | package_type = "debug",
62 | deps = [
63 | ":app-code",
64 | ],
65 | )
66 |
--------------------------------------------------------------------------------
/example/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 | * // whether to bundle JS and assets in debug mode
22 | * bundleInDebug: false,
23 | *
24 | * // whether to bundle JS and assets in release mode
25 | * bundleInRelease: true,
26 | *
27 | * // whether to bundle JS and assets in another build variant (if configured).
28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
29 | * // The configuration property can be in the following formats
30 | * // 'bundleIn${productFlavor}${buildType}'
31 | * // 'bundleIn${buildType}'
32 | * // bundleInFreeDebug: true,
33 | * // bundleInPaidRelease: true,
34 | * // bundleInBeta: true,
35 | *
36 | * // the root of your project, i.e. where "package.json" lives
37 | * root: "../../",
38 | *
39 | * // where to put the JS bundle asset in debug mode
40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
41 | *
42 | * // where to put the JS bundle asset in release mode
43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
44 | *
45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
46 | * // require('./image.png')), in debug mode
47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
48 | *
49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
50 | * // require('./image.png')), in release mode
51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
52 | *
53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
57 | * // for example, you might want to remove it from here.
58 | * inputExcludes: ["android/**", "ios/**"],
59 | *
60 | * // override which node gets called and with what additional arguments
61 | * nodeExecutableAndArgs: ["node"],
62 | *
63 | * // supply additional arguments to the packager
64 | * extraPackagerArgs: []
65 | * ]
66 | */
67 |
68 | apply from: "../../node_modules/react-native/react.gradle"
69 |
70 | /**
71 | * Set this to true to create two separate APKs instead of one:
72 | * - An APK that only works on ARM devices
73 | * - An APK that only works on x86 devices
74 | * The advantage is the size of the APK is reduced by about 4MB.
75 | * Upload all the APKs to the Play Store and people will download
76 | * the correct one based on the CPU architecture of their device.
77 | */
78 | def enableSeparateBuildPerCPUArchitecture = false
79 |
80 | /**
81 | * Run Proguard to shrink the Java bytecode in release builds.
82 | */
83 | def enableProguardInReleaseBuilds = false
84 |
85 | android {
86 | compileSdkVersion 23
87 | buildToolsVersion "23.0.1"
88 |
89 | defaultConfig {
90 | applicationId "com.example"
91 | minSdkVersion 16
92 | targetSdkVersion 22
93 | versionCode 1
94 | versionName "1.0"
95 | ndk {
96 | abiFilters "armeabi-v7a", "x86"
97 | }
98 | }
99 | splits {
100 | abi {
101 | reset()
102 | enable enableSeparateBuildPerCPUArchitecture
103 | universalApk false // If true, also generate a universal APK
104 | include "armeabi-v7a", "x86"
105 | }
106 | }
107 | buildTypes {
108 | release {
109 | minifyEnabled enableProguardInReleaseBuilds
110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
111 | }
112 | }
113 | // applicationVariants are e.g. debug, release
114 | applicationVariants.all { variant ->
115 | variant.outputs.each { output ->
116 | // For each separate APK per architecture, set a unique version code as described here:
117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
118 | def versionCodes = ["armeabi-v7a":1, "x86":2]
119 | def abi = output.getFilter(OutputFile.ABI)
120 | if (abi != null) { // null for the universal-debug, universal-release variants
121 | output.versionCodeOverride =
122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
123 | }
124 | }
125 | }
126 | }
127 |
128 | dependencies {
129 | compile fileTree(dir: "libs", include: ["*.jar"])
130 | compile "com.android.support:appcompat-v7:23.0.1"
131 | compile "com.facebook.react:react-native:+" // From node_modules
132 | }
133 |
134 | // Run this once to be able to run the application with BUCK
135 | // puts all compile dependencies into folder libs for BUCK to use
136 | task copyDownloadableDepsToLibs(type: Copy) {
137 | from configurations.compile
138 | into 'libs'
139 | }
140 |
--------------------------------------------------------------------------------
/example/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 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Disabling obfuscation is useful if you collect stack traces from production crashes
20 | # (unless you are using a system that supports de-obfuscate the stack traces).
21 | -dontobfuscate
22 |
23 | # React Native
24 |
25 | # Keep our interfaces so they can be used by other ProGuard rules.
26 | # See http://sourceforge.net/p/proguard/bugs/466/
27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
30 |
31 | # Do not strip any method/class that is annotated with @DoNotStrip
32 | -keep @com.facebook.proguard.annotations.DoNotStrip class *
33 | -keep @com.facebook.common.internal.DoNotStrip class *
34 | -keepclassmembers class * {
35 | @com.facebook.proguard.annotations.DoNotStrip *;
36 | @com.facebook.common.internal.DoNotStrip *;
37 | }
38 |
39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
40 | void set*(***);
41 | *** get*();
42 | }
43 |
44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; }
46 | -keepclassmembers,includedescriptorclasses class * { native ; }
47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; }
48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; }
49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; }
50 |
51 | -dontwarn com.facebook.react.**
52 |
53 | # TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
54 | # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
55 | -dontwarn android.text.StaticLayout
56 |
57 | # okhttp
58 |
59 | -keepattributes Signature
60 | -keepattributes *Annotation*
61 | -keep class okhttp3.** { *; }
62 | -keep interface okhttp3.** { *; }
63 | -dontwarn okhttp3.**
64 |
65 | # okio
66 |
67 | -keep class sun.misc.Unsafe { *; }
68 | -dontwarn java.nio.file.*
69 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
70 | -dontwarn okio.**
71 |
--------------------------------------------------------------------------------
/example/android/app/react.gradle:
--------------------------------------------------------------------------------
1 | import org.apache.tools.ant.taskdefs.condition.Os
2 |
3 | def config = project.hasProperty("react") ? project.react : [];
4 |
5 | def bundleAssetName = config.bundleAssetName ?: "index.android.bundle"
6 | def entryFile = config.entryFile ?: "index.android.js"
7 |
8 | // because elvis operator
9 | def elvisFile(thing) {
10 | return thing ? file(thing) : null;
11 | }
12 |
13 | def reactRoot = elvisFile(config.root) ?: file("../../")
14 | def inputExcludes = config.inputExcludes ?: ["android/**", "ios/**"]
15 |
16 | void runBefore(String dependentTaskName, Task task) {
17 | Task dependentTask = tasks.findByPath(dependentTaskName);
18 | if (dependentTask != null) {
19 | dependentTask.dependsOn task
20 | }
21 | }
22 |
23 | gradle.projectsEvaluated {
24 | // Grab all build types and product flavors
25 | def buildTypes = android.buildTypes.collect { type -> type.name }
26 | def productFlavors = android.productFlavors.collect { flavor -> flavor.name }
27 |
28 | // When no product flavors defined, use empty
29 | if (!productFlavors) productFlavors.add('')
30 |
31 | productFlavors.each { productFlavorName ->
32 | buildTypes.each { buildTypeName ->
33 | // Create variant and source names
34 | def sourceName = "${buildTypeName}"
35 | def targetName = "${sourceName.capitalize()}"
36 | if (productFlavorName) {
37 | sourceName = "${productFlavorName}${targetName}"
38 | }
39 |
40 | // React js bundle directories
41 | def jsBundleDirConfigName = "jsBundleDir${targetName}"
42 | def jsBundleDir = elvisFile(config."$jsBundleDirConfigName") ?:
43 | file("$buildDir/intermediates/assets/${sourceName}")
44 |
45 | def resourcesDirConfigName = "jsBundleDir${targetName}"
46 | def resourcesDir = elvisFile(config."${resourcesDirConfigName}") ?:
47 | file("$buildDir/intermediates/res/merged/${sourceName}")
48 | def jsBundleFile = file("$jsBundleDir/$bundleAssetName")
49 |
50 | // Bundle task name for variant
51 | def bundleJsAndAssetsTaskName = "bundle${targetName}JsAndAssets"
52 |
53 | def currentBundleTask = tasks.create(
54 | name: bundleJsAndAssetsTaskName,
55 | type: Exec) {
56 | group = "react"
57 | description = "bundle JS and assets for ${targetName}."
58 |
59 | // Create dirs if they are not there (e.g. the "clean" task just ran)
60 | doFirst {
61 | jsBundleDir.mkdirs()
62 | resourcesDir.mkdirs()
63 | }
64 |
65 | // Set up inputs and outputs so gradle can cache the result
66 | inputs.files fileTree(dir: reactRoot, excludes: inputExcludes)
67 | outputs.dir jsBundleDir
68 | outputs.dir resourcesDir
69 |
70 | // Set up the call to the react-native cli
71 | workingDir reactRoot
72 |
73 | // Set up dev mode
74 | def devEnabled = !targetName.toLowerCase().contains("release")
75 | if (Os.isFamily(Os.FAMILY_WINDOWS)) {
76 | commandLine "cmd", "/c", "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}",
77 | "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
78 | } else {
79 | commandLine "react-native", "bundle", "--platform", "android", "--dev", "${devEnabled}",
80 | "--entry-file", entryFile, "--bundle-output", jsBundleFile, "--assets-dest", resourcesDir
81 | }
82 |
83 | enabled config."bundleIn${targetName}" ?: targetName.toLowerCase().contains("release")
84 | }
85 |
86 | // Hook bundle${productFlavor}${buildType}JsAndAssets into the android build process
87 | currentBundleTask.dependsOn("merge${targetName}Resources")
88 | currentBundleTask.dependsOn("merge${targetName}Assets")
89 |
90 | runBefore("processArmeabi-v7a${targetName}Resources", currentBundleTask)
91 | runBefore("processX86${targetName}Resources", currentBundleTask)
92 | runBefore("processUniversal${targetName}Resources", currentBundleTask)
93 | runBefore("process${targetName}Resources", currentBundleTask)
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
19 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.example;
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.
9 | * This is used to schedule rendering of the component.
10 | */
11 | @Override
12 | protected String getMainComponentName() {
13 | return "example";
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/example/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import android.app.Application;
4 |
5 | import com.facebook.react.ReactApplication;
6 | import com.facebook.react.ReactNativeHost;
7 | import com.facebook.react.ReactPackage;
8 | import com.facebook.react.shell.MainReactPackage;
9 | import com.facebook.soloader.SoLoader;
10 |
11 | import java.util.Arrays;
12 | import java.util.List;
13 |
14 | public class MainApplication extends Application implements ReactApplication {
15 |
16 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
17 | @Override
18 | public boolean getUseDeveloperSupport() {
19 | return BuildConfig.DEBUG;
20 | }
21 |
22 | @Override
23 | protected List getPackages() {
24 | return Arrays.asList(
25 | new MainReactPackage()
26 | );
27 | }
28 | };
29 |
30 | @Override
31 | public ReactNativeHost getReactNativeHost() {
32 | return mReactNativeHost;
33 | }
34 |
35 | @Override
36 | public void onCreate() {
37 | super.onCreate();
38 | SoLoader.init(this, /* native exopackage */ false);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | example
3 |
4 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | mavenLocal()
18 | jcenter()
19 | maven {
20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21 | url "$rootDir/../node_modules/react-native/android"
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/example/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 | android.useDeprecatedNdk=true
21 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
6 |
--------------------------------------------------------------------------------
/example/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/example/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/example/android/keystores/BUCK:
--------------------------------------------------------------------------------
1 | keystore(
2 | name = "debug",
3 | properties = "debug.keystore.properties",
4 | store = "debug.keystore",
5 | visibility = [
6 | "PUBLIC",
7 | ],
8 | )
9 |
--------------------------------------------------------------------------------
/example/android/keystores/debug.keystore.properties:
--------------------------------------------------------------------------------
1 | key.store=debug.keystore
2 | key.alias=androiddebugkey
3 | key.store.password=android
4 | key.alias.password=android
5 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'example'
2 |
3 | include ':app'
4 |
--------------------------------------------------------------------------------
/example/index.android.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample React Native App
3 | * https://github.com/facebook/react-native
4 | * @flow
5 | */
6 |
7 | import React, { Component } from 'react';
8 | import {
9 | AppRegistry,
10 | StyleSheet,
11 | Text,
12 | View
13 | } from 'react-native';
14 |
15 | export default class example extends Component {
16 | render() {
17 | return (
18 |
19 |
20 | Welcome to React Native!
21 |
22 |
23 | To get started, edit index.android.js
24 |
25 |
26 | Double tap R on your keyboard to reload,{'\n'}
27 | Shake or press menu button for dev menu
28 |
29 |
30 | );
31 | }
32 | }
33 |
34 | const styles = StyleSheet.create({
35 | container: {
36 | flex: 1,
37 | justifyContent: 'center',
38 | alignItems: 'center',
39 | backgroundColor: '#F5FCFF',
40 | },
41 | welcome: {
42 | fontSize: 20,
43 | textAlign: 'center',
44 | margin: 10,
45 | },
46 | instructions: {
47 | textAlign: 'center',
48 | color: '#333333',
49 | marginBottom: 5,
50 | },
51 | });
52 |
53 | AppRegistry.registerComponent('example', () => example);
54 |
--------------------------------------------------------------------------------
/example/index.ios.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample React Native App
3 | * https://github.com/facebook/react-native
4 | * @flow
5 | */
6 |
7 | import React, { Component } from 'react';
8 | import {
9 | AppRegistry,
10 | StyleSheet,
11 | Text,
12 | View
13 | } from 'react-native';
14 |
15 | import { Crashlytics } from 'react-native-fabric';
16 |
17 | export default class example extends Component {
18 |
19 | onPress() {
20 | // just a string
21 | Crashlytics.recordError("IT BROKED!");
22 |
23 | // a domain
24 | Crashlytics.recordError({
25 | domain: "somedomain",
26 | message: "something broke",
27 | });
28 |
29 | // a code
30 | Crashlytics.recordError({
31 | code: "123",
32 | message: "it broke again",
33 | });
34 |
35 | // a bunch of stuff
36 | Crashlytics.recordError({
37 | code: "123",
38 | domain: "somedomain",
39 | message: "help please",
40 | stack: `someMethod@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:82410:46
41 | anotherMethod@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:82451:34
42 | wrappedResolvedCallback@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64615:32
43 | resolve@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64553:33
44 | wrappedResolvedCallback@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64630:22
45 | resolve@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64553:33
46 | wrappedResolvedCallback@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64630:22
47 | resolve@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64553:33
48 | http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64625:22
49 | wrappedResolvedCallback@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64615:32
50 | http://localhost:8081/index.ios.bundle?platform=ios&dev=true:64681:30
51 | http://localhost:8081/index.ios.bundle?platform=ios&dev=true:4670:18
52 | callTimer@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:4292:9
53 | forEach@[native code]
54 | callTimers@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:4315:17
55 | __callFunction@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:3702:28
56 | http://localhost:8081/index.ios.bundle?platform=ios&dev=true:3606:22
57 | guard@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:3560:3
58 | callFunctionReturnFlushedQueue@http://localhost:8081/index.ios.bundle?platform=ios&dev=true:3605:6
59 | callFunctionReturnFlushedQueue@[native code]
60 | apply@[native code]`,
61 | });
62 | }
63 |
64 | render() {
65 | return (
66 |
67 |
68 | Welcome to React Native!
69 |
70 |
71 | To get started, edit index.ios.js
72 |
73 |
74 | Press Cmd+R to reload,{'\n'}
75 | Cmd+D or shake for dev menu
76 |
77 |
78 | );
79 | }
80 | }
81 |
82 | const styles = StyleSheet.create({
83 | container: {
84 | flex: 1,
85 | justifyContent: 'center',
86 | alignItems: 'center',
87 | backgroundColor: '#F5FCFF',
88 | },
89 | welcome: {
90 | fontSize: 20,
91 | textAlign: 'center',
92 | margin: 10,
93 | },
94 | instructions: {
95 | textAlign: 'center',
96 | color: '#333333',
97 | marginBottom: 5,
98 | },
99 | });
100 |
101 | AppRegistry.registerComponent('example', () => example);
102 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Crashlytics:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/ios/Crashlytics.framework/Crashlytics
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Headers/ANSCompatibility.h:
--------------------------------------------------------------------------------
1 | //
2 | // ANSCompatibility.h
3 | // AnswersKit
4 | //
5 | // Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
6 | //
7 |
8 | #pragma once
9 |
10 | #if !__has_feature(nullability)
11 | #define nonnull
12 | #define nullable
13 | #define _Nullable
14 | #define _Nonnull
15 | #endif
16 |
17 | #ifndef NS_ASSUME_NONNULL_BEGIN
18 | #define NS_ASSUME_NONNULL_BEGIN
19 | #endif
20 |
21 | #ifndef NS_ASSUME_NONNULL_END
22 | #define NS_ASSUME_NONNULL_END
23 | #endif
24 |
25 | #if __has_feature(objc_generics)
26 | #define ANS_GENERIC_NSARRAY(type) NSArray
27 | #define ANS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary
28 | #else
29 | #define ANS_GENERIC_NSARRAY(type) NSArray
30 | #define ANS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary
31 | #endif
32 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Headers/Answers.h:
--------------------------------------------------------------------------------
1 | //
2 | // Answers.h
3 | // Crashlytics
4 | //
5 | // Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
6 | //
7 |
8 | #import
9 | #import "ANSCompatibility.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | /**
14 | * This class exposes the Answers Events API, allowing you to track key
15 | * user user actions and metrics in your app.
16 | */
17 | @interface Answers : NSObject
18 |
19 | /**
20 | * Log a Sign Up event to see users signing up for your app in real-time, understand how
21 | * many users are signing up with different methods and their success rate signing up.
22 | *
23 | * @param signUpMethodOrNil The method by which a user logged in, e.g. Twitter or Digits.
24 | * @param signUpSucceededOrNil The ultimate success or failure of the login
25 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
26 | */
27 | + (void)logSignUpWithMethod:(nullable NSString *)signUpMethodOrNil
28 | success:(nullable NSNumber *)signUpSucceededOrNil
29 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
30 |
31 | /**
32 | * Log an Log In event to see users logging into your app in real-time, understand how many
33 | * users are logging in with different methods and their success rate logging into your app.
34 | *
35 | * @param loginMethodOrNil The method by which a user logged in, e.g. email, Twitter or Digits.
36 | * @param loginSucceededOrNil The ultimate success or failure of the login
37 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
38 | */
39 | + (void)logLoginWithMethod:(nullable NSString *)loginMethodOrNil
40 | success:(nullable NSNumber *)loginSucceededOrNil
41 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
42 |
43 | /**
44 | * Log a Share event to see users sharing from your app in real-time, letting you
45 | * understand what content they're sharing from the type or genre down to the specific id.
46 | *
47 | * @param shareMethodOrNil The method by which a user shared, e.g. email, Twitter, SMS.
48 | * @param contentNameOrNil The human readable name for this piece of content.
49 | * @param contentTypeOrNil The type of content shared.
50 | * @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item.
51 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
52 | */
53 | + (void)logShareWithMethod:(nullable NSString *)shareMethodOrNil
54 | contentName:(nullable NSString *)contentNameOrNil
55 | contentType:(nullable NSString *)contentTypeOrNil
56 | contentId:(nullable NSString *)contentIdOrNil
57 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
58 |
59 | /**
60 | * Log an Invite Event to track how users are inviting other users into
61 | * your application.
62 | *
63 | * @param inviteMethodOrNil The method of invitation, e.g. GameCenter, Twitter, email.
64 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
65 | */
66 | + (void)logInviteWithMethod:(nullable NSString *)inviteMethodOrNil
67 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
68 |
69 | /**
70 | * Log a Purchase event to see your revenue in real-time, understand how many users are making purchases, see which
71 | * items are most popular, and track plenty of other important purchase-related metrics.
72 | *
73 | * @param itemPriceOrNil The purchased item's price.
74 | * @param currencyOrNil The ISO4217 currency code. Example: USD
75 | * @param purchaseSucceededOrNil Was the purchase succesful or unsuccesful
76 | * @param itemNameOrNil The human-readable form of the item's name. Example:
77 | * @param itemTypeOrNil The type, or genre of the item. Example: Song
78 | * @param itemIdOrNil The machine-readable, unique item identifier Example: SKU
79 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this purchase.
80 | */
81 | + (void)logPurchaseWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil
82 | currency:(nullable NSString *)currencyOrNil
83 | success:(nullable NSNumber *)purchaseSucceededOrNil
84 | itemName:(nullable NSString *)itemNameOrNil
85 | itemType:(nullable NSString *)itemTypeOrNil
86 | itemId:(nullable NSString *)itemIdOrNil
87 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
88 |
89 | /**
90 | * Log a Level Start Event to track where users are in your game.
91 | *
92 | * @param levelNameOrNil The level name
93 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this level start event.
94 | */
95 | + (void)logLevelStart:(nullable NSString *)levelNameOrNil
96 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
97 |
98 | /**
99 | * Log a Level End event to track how users are completing levels in your game.
100 | *
101 | * @param levelNameOrNil The name of the level completed, E.G. "1" or "Training"
102 | * @param scoreOrNil The score the user completed the level with.
103 | * @param levelCompletedSuccesfullyOrNil A boolean representing whether or not the level was completed succesfully.
104 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
105 | */
106 | + (void)logLevelEnd:(nullable NSString *)levelNameOrNil
107 | score:(nullable NSNumber *)scoreOrNil
108 | success:(nullable NSNumber *)levelCompletedSuccesfullyOrNil
109 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
110 |
111 | /**
112 | * Log an Add to Cart event to see users adding items to a shopping cart in real-time, understand how
113 | * many users start the purchase flow, see which items are most popular, and track plenty of other important
114 | * purchase-related metrics.
115 | *
116 | * @param itemPriceOrNil The purchased item's price.
117 | * @param currencyOrNil The ISO4217 currency code. Example: USD
118 | * @param itemNameOrNil The human-readable form of the item's name. Example:
119 | * @param itemTypeOrNil The type, or genre of the item. Example: Song
120 | * @param itemIdOrNil The machine-readable, unique item identifier Example: SKU
121 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
122 | */
123 | + (void)logAddToCartWithPrice:(nullable NSDecimalNumber *)itemPriceOrNil
124 | currency:(nullable NSString *)currencyOrNil
125 | itemName:(nullable NSString *)itemNameOrNil
126 | itemType:(nullable NSString *)itemTypeOrNil
127 | itemId:(nullable NSString *)itemIdOrNil
128 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
129 |
130 | /**
131 | * Log a Start Checkout event to see users moving through the purchase funnel in real-time, understand how many
132 | * users are doing this and how much they're spending per checkout, and see how it related to other important
133 | * purchase-related metrics.
134 | *
135 | * @param totalPriceOrNil The total price of the cart.
136 | * @param currencyOrNil The ISO4217 currency code. Example: USD
137 | * @param itemCountOrNil The number of items in the cart.
138 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
139 | */
140 | + (void)logStartCheckoutWithPrice:(nullable NSDecimalNumber *)totalPriceOrNil
141 | currency:(nullable NSString *)currencyOrNil
142 | itemCount:(nullable NSNumber *)itemCountOrNil
143 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
144 |
145 | /**
146 | * Log a Rating event to see users rating content within your app in real-time and understand what
147 | * content is most engaging, from the type or genre down to the specific id.
148 | *
149 | * @param ratingOrNil The integer rating given by the user.
150 | * @param contentNameOrNil The human readable name for this piece of content.
151 | * @param contentTypeOrNil The type of content shared.
152 | * @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item.
153 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
154 | */
155 | + (void)logRating:(nullable NSNumber *)ratingOrNil
156 | contentName:(nullable NSString *)contentNameOrNil
157 | contentType:(nullable NSString *)contentTypeOrNil
158 | contentId:(nullable NSString *)contentIdOrNil
159 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
160 |
161 | /**
162 | * Log a Content View event to see users viewing content within your app in real-time and
163 | * understand what content is most engaging, from the type or genre down to the specific id.
164 | *
165 | * @param contentNameOrNil The human readable name for this piece of content.
166 | * @param contentTypeOrNil The type of content shared.
167 | * @param contentIdOrNil The unique identifier for this piece of content. Useful for finding the top shared item.
168 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
169 | */
170 | + (void)logContentViewWithName:(nullable NSString *)contentNameOrNil
171 | contentType:(nullable NSString *)contentTypeOrNil
172 | contentId:(nullable NSString *)contentIdOrNil
173 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
174 |
175 | /**
176 | * Log a Search event allows you to see users searching within your app in real-time and understand
177 | * exactly what they're searching for.
178 | *
179 | * @param queryOrNil The user's query.
180 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event.
181 | */
182 | + (void)logSearchWithQuery:(nullable NSString *)queryOrNil
183 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
184 |
185 | /**
186 | * Log a Custom Event to see user actions that are uniquely important for your app in real-time, to see how often
187 | * they're performing these actions with breakdowns by different categories you add. Use a human-readable name for
188 | * the name of the event, since this is how the event will appear in Answers.
189 | *
190 | * @param eventName The human-readable name for the event.
191 | * @param customAttributesOrNil A dictionary of custom attributes to associate with this event. Attribute keys
192 | * must be NSString
and and values must be NSNumber
or NSString
.
193 | * @discussion How we treat NSNumbers
:
194 | * We will provide information about the distribution of values over time.
195 | *
196 | * How we treat NSStrings
:
197 | * NSStrings are used as categorical data, allowing comparison across different category values.
198 | * Strings are limited to a maximum length of 100 characters, attributes over this length will be
199 | * truncated.
200 | *
201 | * When tracking the Tweet views to better understand user engagement, sending the tweet's length
202 | * and the type of media present in the tweet allows you to track how tweet length and the type of media influence
203 | * engagement.
204 | */
205 | + (void)logCustomEventWithName:(NSString *)eventName
206 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil;
207 |
208 | @end
209 |
210 | NS_ASSUME_NONNULL_END
211 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Headers/CLSAttributes.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLSAttributes.h
3 | // Crashlytics
4 | //
5 | // Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
6 | //
7 |
8 | #pragma once
9 |
10 | #define CLS_DEPRECATED(x) __attribute__ ((deprecated(x)))
11 |
12 | #if !__has_feature(nullability)
13 | #define nonnull
14 | #define nullable
15 | #define _Nullable
16 | #define _Nonnull
17 | #endif
18 |
19 | #ifndef NS_ASSUME_NONNULL_BEGIN
20 | #define NS_ASSUME_NONNULL_BEGIN
21 | #endif
22 |
23 | #ifndef NS_ASSUME_NONNULL_END
24 | #define NS_ASSUME_NONNULL_END
25 | #endif
26 |
27 | #if __has_feature(objc_generics)
28 | #define CLS_GENERIC_NSARRAY(type) NSArray
29 | #define CLS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary
30 | #else
31 | #define CLS_GENERIC_NSARRAY(type) NSArray
32 | #define CLS_GENERIC_NSDICTIONARY(key_type,object_key) NSDictionary
33 | #endif
34 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Headers/CLSLogging.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLSLogging.h
3 | // Crashlytics
4 | //
5 | // Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
6 | //
7 | #ifdef __OBJC__
8 | #import "CLSAttributes.h"
9 | #import
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 | #endif
13 |
14 |
15 |
16 | /**
17 | *
18 | * The CLS_LOG macro provides as easy way to gather more information in your log messages that are
19 | * sent with your crash data. CLS_LOG prepends your custom log message with the function name and
20 | * line number where the macro was used. If your app was built with the DEBUG preprocessor macro
21 | * defined CLS_LOG uses the CLSNSLog function which forwards your log message to NSLog and CLSLog.
22 | * If the DEBUG preprocessor macro is not defined CLS_LOG uses CLSLog only.
23 | *
24 | * Example output:
25 | * -[AppDelegate login:] line 134 $ login start
26 | *
27 | * If you would like to change this macro, create a new header file, unset our define and then define
28 | * your own version. Make sure this new header file is imported after the Crashlytics header file.
29 | *
30 | * #undef CLS_LOG
31 | * #define CLS_LOG(__FORMAT__, ...) CLSNSLog...
32 | *
33 | **/
34 | #ifdef __OBJC__
35 | #ifdef DEBUG
36 | #define CLS_LOG(__FORMAT__, ...) CLSNSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
37 | #else
38 | #define CLS_LOG(__FORMAT__, ...) CLSLog((@"%s line %d $ " __FORMAT__), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
39 | #endif
40 | #endif
41 |
42 | /**
43 | *
44 | * Add logging that will be sent with your crash data. This logging will not show up in the system.log
45 | * and will only be visible in your Crashlytics dashboard.
46 | *
47 | **/
48 |
49 | #ifdef __OBJC__
50 | OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
51 | OBJC_EXTERN void CLSLogv(NSString *format, va_list ap) NS_FORMAT_FUNCTION(1,0);
52 |
53 | /**
54 | *
55 | * Add logging that will be sent with your crash data. This logging will show up in the system.log
56 | * and your Crashlytics dashboard. It is not recommended for Release builds.
57 | *
58 | **/
59 | OBJC_EXTERN void CLSNSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
60 | OBJC_EXTERN void CLSNSLogv(NSString *format, va_list ap) NS_FORMAT_FUNCTION(1,0);
61 |
62 |
63 | NS_ASSUME_NONNULL_END
64 | #endif
65 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Headers/CLSReport.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLSReport.h
3 | // Crashlytics
4 | //
5 | // Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
6 | //
7 |
8 | #import
9 | #import "CLSAttributes.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | /**
14 | * The CLSCrashReport protocol is deprecated. See the CLSReport class and the CrashyticsDelegate changes for details.
15 | **/
16 | @protocol CLSCrashReport
17 |
18 | @property (nonatomic, copy, readonly) NSString *identifier;
19 | @property (nonatomic, copy, readonly) NSDictionary *customKeys;
20 | @property (nonatomic, copy, readonly) NSString *bundleVersion;
21 | @property (nonatomic, copy, readonly) NSString *bundleShortVersionString;
22 | @property (nonatomic, readonly, nullable) NSDate *crashedOnDate;
23 | @property (nonatomic, copy, readonly) NSString *OSVersion;
24 | @property (nonatomic, copy, readonly) NSString *OSBuildVersion;
25 |
26 | @end
27 |
28 | /**
29 | * The CLSReport exposes an interface to the phsyical report that Crashlytics has created. You can
30 | * use this class to get information about the event, and can also set some values after the
31 | * event has occured.
32 | **/
33 | @interface CLSReport : NSObject
34 |
35 | - (instancetype)init NS_UNAVAILABLE;
36 | + (instancetype)new NS_UNAVAILABLE;
37 |
38 | /**
39 | * Returns the session identifier for the report.
40 | **/
41 | @property (nonatomic, copy, readonly) NSString *identifier;
42 |
43 | /**
44 | * Returns the custom key value data for the report.
45 | **/
46 | @property (nonatomic, copy, readonly) NSDictionary *customKeys;
47 |
48 | /**
49 | * Returns the CFBundleVersion of the application that generated the report.
50 | **/
51 | @property (nonatomic, copy, readonly) NSString *bundleVersion;
52 |
53 | /**
54 | * Returns the CFBundleShortVersionString of the application that generated the report.
55 | **/
56 | @property (nonatomic, copy, readonly) NSString *bundleShortVersionString;
57 |
58 | /**
59 | * Returns the date that the report was created.
60 | **/
61 | @property (nonatomic, copy, readonly) NSDate *dateCreated;
62 |
63 | /**
64 | * Returns the os version that the application crashed on.
65 | **/
66 | @property (nonatomic, copy, readonly) NSString *OSVersion;
67 |
68 | /**
69 | * Returns the os build version that the application crashed on.
70 | **/
71 | @property (nonatomic, copy, readonly) NSString *OSBuildVersion;
72 |
73 | /**
74 | * Returns YES if the report contains any crash information, otherwise returns NO.
75 | **/
76 | @property (nonatomic, assign, readonly) BOOL isCrash;
77 |
78 | /**
79 | * You can use this method to set, after the event, additional custom keys. The rules
80 | * and semantics for this method are the same as those documented in Crashlytics.h. Be aware
81 | * that the maximum size and count of custom keys is still enforced, and you can overwrite keys
82 | * and/or cause excess keys to be deleted by using this method.
83 | **/
84 | - (void)setObjectValue:(nullable id)value forKey:(NSString *)key;
85 |
86 | /**
87 | * Record an application-specific user identifier. See Crashlytics.h for details.
88 | **/
89 | @property (nonatomic, copy, nullable) NSString * userIdentifier;
90 |
91 | /**
92 | * Record a user name. See Crashlytics.h for details.
93 | **/
94 | @property (nonatomic, copy, nullable) NSString * userName;
95 |
96 | /**
97 | * Record a user email. See Crashlytics.h for details.
98 | **/
99 | @property (nonatomic, copy, nullable) NSString * userEmail;
100 |
101 | @end
102 |
103 | NS_ASSUME_NONNULL_END
104 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Headers/CLSStackFrame.h:
--------------------------------------------------------------------------------
1 | //
2 | // CLSStackFrame.h
3 | // Crashlytics
4 | //
5 | // Copyright 2015 Crashlytics, Inc. All rights reserved.
6 | //
7 |
8 | #import
9 | #import "CLSAttributes.h"
10 |
11 | NS_ASSUME_NONNULL_BEGIN
12 |
13 | /**
14 | *
15 | * This class is used in conjunction with -[Crashlytics recordCustomExceptionName:reason:frameArray:] to
16 | * record information about non-ObjC/C++ exceptions. All information included here will be displayed
17 | * in the Crashlytics UI, and can influence crash grouping. Be particularly careful with the use of the
18 | * address property. If set, Crashlytics will attempt symbolication and could overwrite other properities
19 | * in the process.
20 | *
21 | **/
22 | @interface CLSStackFrame : NSObject
23 |
24 | + (instancetype)stackFrame;
25 | + (instancetype)stackFrameWithAddress:(NSUInteger)address;
26 | + (instancetype)stackFrameWithSymbol:(NSString *)symbol;
27 |
28 | @property (nonatomic, copy, nullable) NSString *symbol;
29 | @property (nonatomic, copy, nullable) NSString *rawSymbol;
30 | @property (nonatomic, copy, nullable) NSString *library;
31 | @property (nonatomic, copy, nullable) NSString *fileName;
32 | @property (nonatomic, assign) uint32_t lineNumber;
33 | @property (nonatomic, assign) uint64_t offset;
34 | @property (nonatomic, assign) uint64_t address;
35 |
36 | @end
37 |
38 | NS_ASSUME_NONNULL_END
39 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Headers/Crashlytics.h:
--------------------------------------------------------------------------------
1 | //
2 | // Crashlytics.h
3 | // Crashlytics
4 | //
5 | // Copyright (c) 2015 Crashlytics, Inc. All rights reserved.
6 | //
7 |
8 | #import
9 |
10 | #import "CLSAttributes.h"
11 | #import "CLSLogging.h"
12 | #import "CLSReport.h"
13 | #import "CLSStackFrame.h"
14 | #import "Answers.h"
15 |
16 | NS_ASSUME_NONNULL_BEGIN
17 |
18 | @protocol CrashlyticsDelegate;
19 |
20 | /**
21 | * Crashlytics. Handles configuration and initialization of Crashlytics.
22 | *
23 | * Note: The Crashlytics class cannot be subclassed. If this is causing you pain for
24 | * testing, we suggest using either a wrapper class or a protocol extension.
25 | */
26 | @interface Crashlytics : NSObject
27 |
28 | @property (nonatomic, readonly, copy) NSString *APIKey;
29 | @property (nonatomic, readonly, copy) NSString *version;
30 | @property (nonatomic, assign) BOOL debugMode;
31 |
32 | /**
33 | *
34 | * The delegate can be used to influence decisions on reporting and behavior, as well as reacting
35 | * to previous crashes.
36 | *
37 | * Make certain that the delegate is setup before starting Crashlytics with startWithAPIKey:... or
38 | * via +[Fabric with:...]. Failure to do will result in missing any delegate callbacks that occur
39 | * synchronously during start.
40 | *
41 | **/
42 | @property (nonatomic, assign, nullable) id delegate;
43 |
44 | /**
45 | * The recommended way to install Crashlytics into your application is to place a call to +startWithAPIKey:
46 | * in your -application:didFinishLaunchingWithOptions: or -applicationDidFinishLaunching:
47 | * method.
48 | *
49 | * Note: Starting with 3.0, the submission process has been significantly improved. The delay parameter
50 | * is no longer required to throttle submissions on launch, performance will be great without it.
51 | *
52 | * @param apiKey The Crashlytics API Key for this app
53 | *
54 | * @return The singleton Crashlytics instance
55 | */
56 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey;
57 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey afterDelay:(NSTimeInterval)delay CLS_DEPRECATED("Crashlytics no longer needs or uses the delay parameter. Please use +startWithAPIKey: instead.");
58 |
59 | /**
60 | * If you need the functionality provided by the CrashlyticsDelegate protocol, you can use
61 | * these convenience methods to activate the framework and set the delegate in one call.
62 | *
63 | * @param apiKey The Crashlytics API Key for this app
64 | * @param delegate A delegate object which conforms to CrashlyticsDelegate.
65 | *
66 | * @return The singleton Crashlytics instance
67 | */
68 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(nullable id)delegate;
69 | + (Crashlytics *)startWithAPIKey:(NSString *)apiKey delegate:(nullable id)delegate afterDelay:(NSTimeInterval)delay CLS_DEPRECATED("Crashlytics no longer needs or uses the delay parameter. Please use +startWithAPIKey:delegate: instead.");
70 |
71 | /**
72 | * Access the singleton Crashlytics instance.
73 | *
74 | * @return The singleton Crashlytics instance
75 | */
76 | + (Crashlytics *)sharedInstance;
77 |
78 | /**
79 | * The easiest way to cause a crash - great for testing!
80 | */
81 | - (void)crash;
82 |
83 | /**
84 | * The easiest way to cause a crash with an exception - great for testing.
85 | */
86 | - (void)throwException;
87 |
88 | /**
89 | * Specify a user identifier which will be visible in the Crashlytics UI.
90 | *
91 | * Many of our customers have requested the ability to tie crashes to specific end-users of their
92 | * application in order to facilitate responses to support requests or permit the ability to reach
93 | * out for more information. We allow you to specify up to three separate values for display within
94 | * the Crashlytics UI - but please be mindful of your end-user's privacy.
95 | *
96 | * We recommend specifying a user identifier - an arbitrary string that ties an end-user to a record
97 | * in your system. This could be a database id, hash, or other value that is meaningless to a
98 | * third-party observer but can be indexed and queried by you.
99 | *
100 | * Optionally, you may also specify the end-user's name or username, as well as email address if you
101 | * do not have a system that works well with obscured identifiers.
102 | *
103 | * Pursuant to our EULA, this data is transferred securely throughout our system and we will not
104 | * disseminate end-user data unless required to by law. That said, if you choose to provide end-user
105 | * contact information, we strongly recommend that you disclose this in your application's privacy
106 | * policy. Data privacy is of our utmost concern.
107 | *
108 | * @param identifier An arbitrary user identifier string which ties an end-user to a record in your system.
109 | */
110 | - (void)setUserIdentifier:(nullable NSString *)identifier;
111 |
112 | /**
113 | * Specify a user name which will be visible in the Crashlytics UI.
114 | * Please be mindful of your end-user's privacy and see if setUserIdentifier: can fulfil your needs.
115 | * @see setUserIdentifier:
116 | *
117 | * @param name An end user's name.
118 | */
119 | - (void)setUserName:(nullable NSString *)name;
120 |
121 | /**
122 | * Specify a user email which will be visible in the Crashlytics UI.
123 | * Please be mindful of your end-user's privacy and see if setUserIdentifier: can fulfil your needs.
124 | *
125 | * @see setUserIdentifier:
126 | *
127 | * @param email An end user's email address.
128 | */
129 | - (void)setUserEmail:(nullable NSString *)email;
130 |
131 | + (void)setUserIdentifier:(nullable NSString *)identifier CLS_DEPRECATED("Please access this method via +sharedInstance");
132 | + (void)setUserName:(nullable NSString *)name CLS_DEPRECATED("Please access this method via +sharedInstance");
133 | + (void)setUserEmail:(nullable NSString *)email CLS_DEPRECATED("Please access this method via +sharedInstance");
134 |
135 | /**
136 | * Set a value for a for a key to be associated with your crash data which will be visible in the Crashlytics UI.
137 | * When setting an object value, the object is converted to a string. This is typically done by calling
138 | * -[NSObject description].
139 | *
140 | * @param value The object to be associated with the key
141 | * @param key The key with which to associate the value
142 | */
143 | - (void)setObjectValue:(nullable id)value forKey:(NSString *)key;
144 |
145 | /**
146 | * Set an int value for a key to be associated with your crash data which will be visible in the Crashlytics UI.
147 | *
148 | * @param value The integer value to be set
149 | * @param key The key with which to associate the value
150 | */
151 | - (void)setIntValue:(int)value forKey:(NSString *)key;
152 |
153 | /**
154 | * Set an BOOL value for a key to be associated with your crash data which will be visible in the Crashlytics UI.
155 | *
156 | * @param value The BOOL value to be set
157 | * @param key The key with which to associate the value
158 | */
159 | - (void)setBoolValue:(BOOL)value forKey:(NSString *)key;
160 |
161 | /**
162 | * Set an float value for a key to be associated with your crash data which will be visible in the Crashlytics UI.
163 | *
164 | * @param value The float value to be set
165 | * @param key The key with which to associate the value
166 | */
167 | - (void)setFloatValue:(float)value forKey:(NSString *)key;
168 |
169 | + (void)setObjectValue:(nullable id)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
170 | + (void)setIntValue:(int)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
171 | + (void)setBoolValue:(BOOL)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
172 | + (void)setFloatValue:(float)value forKey:(NSString *)key CLS_DEPRECATED("Please access this method via +sharedInstance");
173 |
174 | /**
175 | * This method can be used to record a single exception structure in a report. This is particularly useful
176 | * when your code interacts with non-native languages like Lua, C#, or Javascript. This call can be
177 | * expensive and should only be used shortly before process termination. This API is not intended be to used
178 | * to log NSException objects. All safely-reportable NSExceptions are automatically captured by
179 | * Crashlytics.
180 | *
181 | * @param name The name of the custom exception
182 | * @param reason The reason this exception occured
183 | * @param frameArray An array of CLSStackFrame objects
184 | */
185 | - (void)recordCustomExceptionName:(NSString *)name reason:(nullable NSString *)reason frameArray:(CLS_GENERIC_NSARRAY(CLSStackFrame *) *)frameArray;
186 |
187 | /**
188 | *
189 | * This allows you to record a non-fatal event, described by an NSError object. These events will be grouped and
190 | * displayed similarly to crashes. Keep in mind that this method can be expensive. Also, the total number of
191 | * NSErrors that can be recorded during your app's life-cycle is limited by a fixed-size circular buffer. If the
192 | * buffer is overrun, the oldest data is dropped. Errors are relayed to Crashlytics on a subsequent launch
193 | * of your application.
194 | *
195 | * You can also use the -recordError:withAdditionalUserInfo: to include additional context not represented
196 | * by the NSError instance itself.
197 | *
198 | **/
199 | - (void)recordError:(NSError *)error;
200 | - (void)recordError:(NSError *)error withAdditionalUserInfo:(nullable CLS_GENERIC_NSDICTIONARY(NSString *, id) *)userInfo;
201 |
202 | - (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
203 | - (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
204 | + (void)logEvent:(NSString *)eventName CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
205 | + (void)logEvent:(NSString *)eventName attributes:(nullable NSDictionary *) attributes CLS_DEPRECATED("Please refer to Answers +logCustomEventWithName:");
206 |
207 | @end
208 |
209 | /**
210 | *
211 | * The CrashlyticsDelegate protocol provides a mechanism for your application to take
212 | * action on events that occur in the Crashlytics crash reporting system. You can make
213 | * use of these calls by assigning an object to the Crashlytics' delegate property directly,
214 | * or through the convenience +startWithAPIKey:delegate: method.
215 | *
216 | */
217 | @protocol CrashlyticsDelegate
218 | @optional
219 |
220 |
221 | - (void)crashlyticsDidDetectCrashDuringPreviousExecution:(Crashlytics *)crashlytics CLS_DEPRECATED("Please refer to -crashlyticsDidDetectReportForLastExecution:");
222 | - (void)crashlytics:(Crashlytics *)crashlytics didDetectCrashDuringPreviousExecution:(id )crash CLS_DEPRECATED("Please refer to -crashlyticsDidDetectReportForLastExecution:");
223 |
224 | /**
225 | *
226 | * Called when a Crashlytics instance has determined that the last execution of the
227 | * application resulted in a saved report. This is called synchronously on Crashlytics
228 | * initialization. Your delegate must invoke the completionHandler, but does not need to do so
229 | * synchronously, or even on the main thread. Invoking completionHandler with NO will cause the
230 | * detected report to be deleted and not submitted to Crashlytics. This is useful for
231 | * implementing permission prompts, or other more-complex forms of logic around submitting crashes.
232 | *
233 | * Instead of using this method, you should try to make use of -crashlyticsDidDetectReportForLastExecution:
234 | * if you can.
235 | *
236 | * @warning Failure to invoke the completionHandler will prevent submissions from being reported. Watch out.
237 | *
238 | * @warning Just implementing this delegate method will disable all forms of synchronous report submission. This can
239 | * impact the reliability of reporting crashes very early in application launch.
240 | *
241 | * @param report The CLSReport object representing the last detected report
242 | * @param completionHandler The completion handler to call when your logic has completed.
243 | *
244 | */
245 | - (void)crashlyticsDidDetectReportForLastExecution:(CLSReport *)report completionHandler:(void (^)(BOOL submit))completionHandler;
246 |
247 | /**
248 | *
249 | * Called when a Crashlytics instance has determined that the last execution of the
250 | * application resulted in a saved report. This method differs from
251 | * -crashlyticsDidDetectReportForLastExecution:completionHandler: in three important ways:
252 | *
253 | * - it is not called synchronously during initialization
254 | * - it does not give you the ability to prevent the report from being submitted
255 | * - the report object itself is immutable
256 | *
257 | * Thanks to these limitations, making use of this method does not impact reporting
258 | * reliabilty in any way.
259 | *
260 | * @param report The read-only CLSReport object representing the last detected report
261 | *
262 | */
263 |
264 | - (void)crashlyticsDidDetectReportForLastExecution:(CLSReport *)report;
265 |
266 | /**
267 | * If your app is running on an OS that supports it (OS X 10.9+, iOS 7.0+), Crashlytics will submit
268 | * most reports using out-of-process background networking operations. This results in a significant
269 | * improvement in reliability of reporting, as well as power and performance wins for your users.
270 | * If you don't want this functionality, you can disable by returning NO from this method.
271 | *
272 | * @warning Background submission is not supported for extensions on iOS or OS X.
273 | *
274 | * @param crashlytics The Crashlytics singleton instance
275 | *
276 | * @return Return NO if you don't want out-of-process background network operations.
277 | *
278 | */
279 | - (BOOL)crashlyticsCanUseBackgroundSessions:(Crashlytics *)crashlytics;
280 |
281 | @end
282 |
283 | /**
284 | * `CrashlyticsKit` can be used as a parameter to `[Fabric with:@[CrashlyticsKit]];` in Objective-C. In Swift, use Crashlytics.sharedInstance()
285 | */
286 | #define CrashlyticsKit [Crashlytics sharedInstance]
287 |
288 | NS_ASSUME_NONNULL_END
289 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/ios/Crashlytics.framework/Info.plist
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module Crashlytics {
2 | header "Crashlytics.h"
3 | header "Answers.h"
4 | header "ANSCompatibility.h"
5 | header "CLSLogging.h"
6 | header "CLSReport.h"
7 | header "CLSStackFrame.h"
8 | header "CLSAttributes.h"
9 |
10 | export *
11 |
12 | link "z"
13 | link "c++"
14 | }
15 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/run:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # run
4 | #
5 | # Copyright (c) 2015 Crashlytics. All rights reserved.
6 |
7 | # Figure out where we're being called from
8 | DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
9 |
10 | # Quote path in case of spaces or special chars
11 | DIR="\"${DIR}"
12 |
13 | PATH_SEP="/"
14 | VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
15 | UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
16 |
17 | # Ensure params are as expected, run in sync mode to validate
18 | eval $DIR$PATH_SEP$VALIDATE_COMMAND
19 | return_code=$?
20 |
21 | if [[ $return_code != 0 ]]; then
22 | exit $return_code
23 | fi
24 |
25 | # Verification passed, upload dSYM in background to prevent Xcode from waiting
26 | # Note: Validation is performed again before upload.
27 | # Output can still be found in Console.app
28 | eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 &
29 |
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/submit:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/ios/Crashlytics.framework/submit
--------------------------------------------------------------------------------
/example/ios/Crashlytics.framework/uploadDSYM:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/ios/Crashlytics.framework/uploadDSYM
--------------------------------------------------------------------------------
/example/ios/Fabric.framework/Fabric:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/ios/Fabric.framework/Fabric
--------------------------------------------------------------------------------
/example/ios/Fabric.framework/Headers/FABAttributes.h:
--------------------------------------------------------------------------------
1 | //
2 | // FABAttributes.h
3 | // Fabric
4 | //
5 | // Copyright (C) 2015 Twitter, Inc.
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #pragma once
21 |
22 | #define FAB_UNAVAILABLE(x) __attribute__((unavailable(x)))
23 |
24 | #if !__has_feature(nullability)
25 | #define nonnull
26 | #define nullable
27 | #define _Nullable
28 | #define _Nonnull
29 | #endif
30 |
31 | #ifndef NS_ASSUME_NONNULL_BEGIN
32 | #define NS_ASSUME_NONNULL_BEGIN
33 | #endif
34 |
35 | #ifndef NS_ASSUME_NONNULL_END
36 | #define NS_ASSUME_NONNULL_END
37 | #endif
38 |
39 |
40 | /**
41 | * The following macros are defined here to provide
42 | * backwards compatability. If you are still using
43 | * them you should migrate to the native nullability
44 | * macros.
45 | */
46 | #define fab_nullable nullable
47 | #define fab_nonnull nonnull
48 | #define FAB_NONNULL __fab_nonnull
49 | #define FAB_NULLABLE __fab_nullable
50 | #define FAB_START_NONNULL NS_ASSUME_NONNULL_BEGIN
51 | #define FAB_END_NONNULL NS_ASSUME_NONNULL_END
52 |
--------------------------------------------------------------------------------
/example/ios/Fabric.framework/Headers/Fabric.h:
--------------------------------------------------------------------------------
1 | //
2 | // Fabric.h
3 | // Fabric
4 | //
5 | // Copyright (C) 2015 Twitter, Inc.
6 | //
7 | // Licensed under the Apache License, Version 2.0 (the "License");
8 | // you may not use this file except in compliance with the License.
9 | // You may obtain a copy of the License at
10 | //
11 | // http://www.apache.org/licenses/LICENSE-2.0
12 | //
13 | // Unless required by applicable law or agreed to in writing, software
14 | // distributed under the License is distributed on an "AS IS" BASIS,
15 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | // See the License for the specific language governing permissions and
17 | // limitations under the License.
18 | //
19 |
20 | #import
21 | #import "FABAttributes.h"
22 |
23 | NS_ASSUME_NONNULL_BEGIN
24 |
25 | #if TARGET_OS_IPHONE
26 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
27 | #error "Fabric's minimum iOS version is 6.0"
28 | #endif
29 | #else
30 | #if __MAC_OS_X_VERSION_MIN_REQUIRED < 1070
31 | #error "Fabric's minimum OS X version is 10.7"
32 | #endif
33 | #endif
34 |
35 | /**
36 | * Fabric Base. Coordinates configuration and starts all provided kits.
37 | */
38 | @interface Fabric : NSObject
39 |
40 | /**
41 | * Initialize Fabric and all provided kits. Call this method within your App Delegate's `application:didFinishLaunchingWithOptions:` and provide the kits you wish to use.
42 | *
43 | * For example, in Objective-C:
44 | *
45 | * `[Fabric with:@[[Crashlytics class], [Twitter class], [Digits class], [MoPub class]]];`
46 | *
47 | * Swift:
48 | *
49 | * `Fabric.with([Crashlytics.self(), Twitter.self(), Digits.self(), MoPub.self()])`
50 | *
51 | * Only the first call to this method is honored. Subsequent calls are no-ops.
52 | *
53 | * @param kitClasses An array of kit Class objects
54 | *
55 | * @return Returns the shared Fabric instance. In most cases this can be ignored.
56 | */
57 | + (instancetype)with:(NSArray *)kitClasses;
58 |
59 | /**
60 | * Returns the Fabric singleton object.
61 | */
62 | + (instancetype)sharedSDK;
63 |
64 | /**
65 | * This BOOL enables or disables debug logging, such as kit version information. The default value is NO.
66 | */
67 | @property (nonatomic, assign) BOOL debug;
68 |
69 | /**
70 | * Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance.
71 | */
72 | - (id)init FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance.");
73 |
74 | /**
75 | * Unavailable. Use `+sharedSDK` to retrieve the shared Fabric instance.
76 | */
77 | + (instancetype)new FAB_UNAVAILABLE("Use +sharedSDK to retrieve the shared Fabric instance.");
78 |
79 | @end
80 |
81 | NS_ASSUME_NONNULL_END
82 |
83 |
--------------------------------------------------------------------------------
/example/ios/Fabric.framework/Info.plist:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/ios/Fabric.framework/Info.plist
--------------------------------------------------------------------------------
/example/ios/Fabric.framework/Modules/module.modulemap:
--------------------------------------------------------------------------------
1 | framework module Fabric {
2 | umbrella header "Fabric.h"
3 |
4 | export *
5 | module * { export * }
6 | }
--------------------------------------------------------------------------------
/example/ios/Fabric.framework/run:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # run
4 | #
5 | # Copyright (c) 2015 Crashlytics. All rights reserved.
6 |
7 | # Figure out where we're being called from
8 | DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
9 |
10 | # Quote path in case of spaces or special chars
11 | DIR="\"${DIR}"
12 |
13 | PATH_SEP="/"
14 | VALIDATE_COMMAND="uploadDSYM\" $@ validate run-script"
15 | UPLOAD_COMMAND="uploadDSYM\" $@ run-script"
16 |
17 | # Ensure params are as expected, run in sync mode to validate
18 | eval $DIR$PATH_SEP$VALIDATE_COMMAND
19 | return_code=$?
20 |
21 | if [[ $return_code != 0 ]]; then
22 | exit $return_code
23 | fi
24 |
25 | # Verification passed, upload dSYM in background to prevent Xcode from waiting
26 | # Note: Validation is performed again before upload.
27 | # Output can still be found in Console.app
28 | eval $DIR$PATH_SEP$UPLOAD_COMMAND > /dev/null 2>&1 &
29 |
--------------------------------------------------------------------------------
/example/ios/Fabric.framework/uploadDSYM:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/corymsmith/react-native-fabric/37758d10714b3453f1c65f43d7dd23eec2d65501/example/ios/Fabric.framework/uploadDSYM
--------------------------------------------------------------------------------
/example/ios/example-tvOS/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 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UIViewControllerBasedStatusBarAppearance
38 |
39 | NSLocationWhenInUseUsageDescription
40 |
41 | NSAppTransportSecurity
42 |
43 |
44 | NSExceptionDomains
45 |
46 | localhost
47 |
48 | NSExceptionAllowsInsecureHTTPLoads
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/example/ios/example-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 |
--------------------------------------------------------------------------------
/example/ios/example.xcodeproj/xcshareddata/xcschemes/example-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 |
--------------------------------------------------------------------------------
/example/ios/example.xcodeproj/xcshareddata/xcschemes/example.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 |
--------------------------------------------------------------------------------
/example/ios/example/AppDelegate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (nonatomic, strong) UIWindow *window;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/example/ios/example/AppDelegate.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import "AppDelegate.h"
11 |
12 | #import
13 | #import
14 |
15 | #import
16 | #import
17 |
18 | @implementation AppDelegate
19 |
20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
21 | {
22 | NSURL *jsCodeLocation;
23 |
24 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
25 |
26 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
27 | moduleName:@"example"
28 | initialProperties:nil
29 | launchOptions:launchOptions];
30 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
31 |
32 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
33 | UIViewController *rootViewController = [UIViewController new];
34 | rootViewController.view = rootView;
35 | self.window.rootViewController = rootViewController;
36 | [self.window makeKeyAndVisible];
37 |
38 | [Fabric with:@[[Crashlytics class]]];
39 |
40 | return YES;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/example/ios/example/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 |
--------------------------------------------------------------------------------
/example/ios/example/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 | }
--------------------------------------------------------------------------------
/example/ios/example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | example
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
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 | Fabric
26 |
27 | APIKey
28 | 51004ea69706d8c9321895a424bff3e5d7be7032
29 | Kits
30 |
31 |
32 | KitInfo
33 |
34 | KitName
35 | Crashlytics
36 |
37 |
38 |
39 | LSRequiresIPhoneOS
40 |
41 | NSLocationWhenInUseUsageDescription
42 |
43 | UILaunchStoryboardName
44 | LaunchScreen
45 | UIRequiredDeviceCapabilities
46 |
47 | armv7
48 |
49 | UISupportedInterfaceOrientations
50 |
51 | UIInterfaceOrientationPortrait
52 | UIInterfaceOrientationLandscapeLeft
53 | UIInterfaceOrientationLandscapeRight
54 |
55 | UIViewControllerBasedStatusBarAppearance
56 |
57 | NSAppTransportSecurity
58 |
59 | NSExceptionDomains
60 |
61 | localhost
62 |
63 | NSExceptionAllowsInsecureHTTPLoads
64 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/example/ios/example/main.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 |
12 | #import "AppDelegate.h"
13 |
14 | int main(int argc, char * argv[]) {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/example/ios/exampleTests/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 |
--------------------------------------------------------------------------------
/example/ios/exampleTests/exampleTests.m:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2015-present, Facebook, Inc.
3 | * All rights reserved.
4 | *
5 | * This source code is licensed under the BSD-style license found in the
6 | * LICENSE file in the root directory of this source tree. An additional grant
7 | * of patent rights can be found in the PATENTS file in the same directory.
8 | */
9 |
10 | #import
11 | #import
12 |
13 | #import
14 | #import
15 |
16 | #define TIMEOUT_SECONDS 600
17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18 |
19 | @interface exampleTests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation exampleTests
24 |
25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test
26 | {
27 | if (test(view)) {
28 | return YES;
29 | }
30 | for (UIView *subview in [view subviews]) {
31 | if ([self findSubviewInView:subview matching:test]) {
32 | return YES;
33 | }
34 | }
35 | return NO;
36 | }
37 |
38 | - (void)testRendersWelcomeScreen
39 | {
40 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController];
41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS];
42 | BOOL foundElement = NO;
43 |
44 | __block NSString *redboxError = nil;
45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) {
46 | if (level >= RCTLogLevelError) {
47 | redboxError = message;
48 | }
49 | });
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 | RCTSetLogFunction(RCTDefaultLogFunction);
64 |
65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError);
66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS);
67 | }
68 |
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "node node_modules/react-native/local-cli/cli.js start",
7 | "test": "jest"
8 | },
9 | "dependencies": {
10 | "react": "16.0.0-alpha.6",
11 | "react-native": "0.44.1",
12 | "react-native-fabric": "file:../"
13 | },
14 | "devDependencies": {
15 | "babel-jest": "20.0.3",
16 | "babel-preset-react-native": "1.9.2",
17 | "jest": "20.0.4",
18 | "react-test-renderer": "16.0.0-alpha.6"
19 | },
20 | "jest": {
21 | "preset": "react-native"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/SMXCrashlytics.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6463C8551EBA12CB0095B8CD /* SMXAnswers.m in Sources */ = {isa = PBXBuildFile; fileRef = D87A76C01C86A251004ABB23 /* SMXAnswers.m */; };
11 | 6463C8561EBA12CB0095B8CD /* SMXCrashlytics.m in Sources */ = {isa = PBXBuildFile; fileRef = D87A76C21C86A251004ABB23 /* SMXCrashlytics.m */; };
12 | D87A76C31C86A251004ABB23 /* SMXAnswers.m in Sources */ = {isa = PBXBuildFile; fileRef = D87A76C01C86A251004ABB23 /* SMXAnswers.m */; };
13 | D87A76C41C86A251004ABB23 /* SMXCrashlytics.m in Sources */ = {isa = PBXBuildFile; fileRef = D87A76C21C86A251004ABB23 /* SMXCrashlytics.m */; };
14 | /* End PBXBuildFile section */
15 |
16 | /* Begin PBXCopyFilesBuildPhase section */
17 | 6463C84A1EBA12A60095B8CD /* CopyFiles */ = {
18 | isa = PBXCopyFilesBuildPhase;
19 | buildActionMask = 2147483647;
20 | dstPath = "include/$(PRODUCT_NAME)";
21 | dstSubfolderSpec = 16;
22 | files = (
23 | );
24 | runOnlyForDeploymentPostprocessing = 0;
25 | };
26 | D8D9DB811C6D03DB009FBC0E /* CopyFiles */ = {
27 | isa = PBXCopyFilesBuildPhase;
28 | buildActionMask = 2147483647;
29 | dstPath = "include/$(PRODUCT_NAME)";
30 | dstSubfolderSpec = 16;
31 | files = (
32 | );
33 | runOnlyForDeploymentPostprocessing = 0;
34 | };
35 | /* End PBXCopyFilesBuildPhase section */
36 |
37 | /* Begin PBXFileReference section */
38 | 6463C84C1EBA12A60095B8CD /* libSMXCrashlytics.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSMXCrashlytics.a; sourceTree = BUILT_PRODUCTS_DIR; };
39 | D87A76BF1C86A251004ABB23 /* SMXAnswers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SMXAnswers.h; path = SMXCrashlytics/SMXAnswers.h; sourceTree = ""; };
40 | D87A76C01C86A251004ABB23 /* SMXAnswers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SMXAnswers.m; path = SMXCrashlytics/SMXAnswers.m; sourceTree = ""; };
41 | D87A76C11C86A251004ABB23 /* SMXCrashlytics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SMXCrashlytics.h; path = SMXCrashlytics/SMXCrashlytics.h; sourceTree = ""; };
42 | D87A76C21C86A251004ABB23 /* SMXCrashlytics.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SMXCrashlytics.m; path = SMXCrashlytics/SMXCrashlytics.m; sourceTree = ""; };
43 | D8D9DB831C6D03DB009FBC0E /* libSMXCrashlytics.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSMXCrashlytics.a; sourceTree = BUILT_PRODUCTS_DIR; };
44 | /* End PBXFileReference section */
45 |
46 | /* Begin PBXFrameworksBuildPhase section */
47 | 6463C8491EBA12A60095B8CD /* Frameworks */ = {
48 | isa = PBXFrameworksBuildPhase;
49 | buildActionMask = 2147483647;
50 | files = (
51 | );
52 | runOnlyForDeploymentPostprocessing = 0;
53 | };
54 | D8D9DB801C6D03DB009FBC0E /* Frameworks */ = {
55 | isa = PBXFrameworksBuildPhase;
56 | buildActionMask = 2147483647;
57 | files = (
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | /* End PBXFrameworksBuildPhase section */
62 |
63 | /* Begin PBXGroup section */
64 | D8D9DB5B1C6D01F4009FBC0E = {
65 | isa = PBXGroup;
66 | children = (
67 | D87A76BF1C86A251004ABB23 /* SMXAnswers.h */,
68 | D87A76C01C86A251004ABB23 /* SMXAnswers.m */,
69 | D87A76C11C86A251004ABB23 /* SMXCrashlytics.h */,
70 | D87A76C21C86A251004ABB23 /* SMXCrashlytics.m */,
71 | D8D9DB661C6D01F4009FBC0E /* Products */,
72 | );
73 | sourceTree = "";
74 | };
75 | D8D9DB661C6D01F4009FBC0E /* Products */ = {
76 | isa = PBXGroup;
77 | children = (
78 | D8D9DB831C6D03DB009FBC0E /* libSMXCrashlytics.a */,
79 | 6463C84C1EBA12A60095B8CD /* libSMXCrashlytics.a */,
80 | );
81 | name = Products;
82 | sourceTree = "";
83 | };
84 | /* End PBXGroup section */
85 |
86 | /* Begin PBXNativeTarget section */
87 | 6463C84B1EBA12A60095B8CD /* SMXCrashlytics-tvOS */ = {
88 | isa = PBXNativeTarget;
89 | buildConfigurationList = 6463C8541EBA12A60095B8CD /* Build configuration list for PBXNativeTarget "SMXCrashlytics-tvOS" */;
90 | buildPhases = (
91 | 6463C8481EBA12A60095B8CD /* Sources */,
92 | 6463C8491EBA12A60095B8CD /* Frameworks */,
93 | 6463C84A1EBA12A60095B8CD /* CopyFiles */,
94 | );
95 | buildRules = (
96 | );
97 | dependencies = (
98 | );
99 | name = "SMXCrashlytics-tvOS";
100 | productName = "SMXCrashlytics-tvOS";
101 | productReference = 6463C84C1EBA12A60095B8CD /* libSMXCrashlytics.a */;
102 | productType = "com.apple.product-type.library.static";
103 | };
104 | D8D9DB821C6D03DB009FBC0E /* SMXCrashlytics */ = {
105 | isa = PBXNativeTarget;
106 | buildConfigurationList = D8D9DB891C6D03DB009FBC0E /* Build configuration list for PBXNativeTarget "SMXCrashlytics" */;
107 | buildPhases = (
108 | D8D9DB7F1C6D03DB009FBC0E /* Sources */,
109 | D8D9DB801C6D03DB009FBC0E /* Frameworks */,
110 | D8D9DB811C6D03DB009FBC0E /* CopyFiles */,
111 | );
112 | buildRules = (
113 | );
114 | dependencies = (
115 | );
116 | name = SMXCrashlytics;
117 | productName = SMXCrashlytics;
118 | productReference = D8D9DB831C6D03DB009FBC0E /* libSMXCrashlytics.a */;
119 | productType = "com.apple.product-type.library.static";
120 | };
121 | /* End PBXNativeTarget section */
122 |
123 | /* Begin PBXProject section */
124 | D8D9DB5C1C6D01F4009FBC0E /* Project object */ = {
125 | isa = PBXProject;
126 | attributes = {
127 | LastUpgradeCheck = 0830;
128 | ORGANIZATIONNAME = "Lane Rettig";
129 | TargetAttributes = {
130 | 6463C84B1EBA12A60095B8CD = {
131 | CreatedOnToolsVersion = 8.3.2;
132 | ProvisioningStyle = Automatic;
133 | };
134 | D8D9DB821C6D03DB009FBC0E = {
135 | CreatedOnToolsVersion = 7.2.1;
136 | };
137 | };
138 | };
139 | buildConfigurationList = D8D9DB5F1C6D01F4009FBC0E /* Build configuration list for PBXProject "SMXCrashlytics" */;
140 | compatibilityVersion = "Xcode 3.2";
141 | developmentRegion = English;
142 | hasScannedForEncodings = 0;
143 | knownRegions = (
144 | en,
145 | );
146 | mainGroup = D8D9DB5B1C6D01F4009FBC0E;
147 | productRefGroup = D8D9DB661C6D01F4009FBC0E /* Products */;
148 | projectDirPath = "";
149 | projectRoot = "";
150 | targets = (
151 | D8D9DB821C6D03DB009FBC0E /* SMXCrashlytics */,
152 | 6463C84B1EBA12A60095B8CD /* SMXCrashlytics-tvOS */,
153 | );
154 | };
155 | /* End PBXProject section */
156 |
157 | /* Begin PBXSourcesBuildPhase section */
158 | 6463C8481EBA12A60095B8CD /* Sources */ = {
159 | isa = PBXSourcesBuildPhase;
160 | buildActionMask = 2147483647;
161 | files = (
162 | 6463C8551EBA12CB0095B8CD /* SMXAnswers.m in Sources */,
163 | 6463C8561EBA12CB0095B8CD /* SMXCrashlytics.m in Sources */,
164 | );
165 | runOnlyForDeploymentPostprocessing = 0;
166 | };
167 | D8D9DB7F1C6D03DB009FBC0E /* Sources */ = {
168 | isa = PBXSourcesBuildPhase;
169 | buildActionMask = 2147483647;
170 | files = (
171 | D87A76C41C86A251004ABB23 /* SMXCrashlytics.m in Sources */,
172 | D87A76C31C86A251004ABB23 /* SMXAnswers.m in Sources */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXSourcesBuildPhase section */
177 |
178 | /* Begin XCBuildConfiguration section */
179 | 6463C8521EBA12A60095B8CD /* Debug */ = {
180 | isa = XCBuildConfiguration;
181 | buildSettings = {
182 | CLANG_ANALYZER_NONNULL = YES;
183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
184 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
185 | CLANG_WARN_INFINITE_RECURSION = YES;
186 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
187 | OTHER_LDFLAGS = "-ObjC";
188 | PRODUCT_NAME = SMXCrashlytics;
189 | SDKROOT = appletvos;
190 | SKIP_INSTALL = YES;
191 | TVOS_DEPLOYMENT_TARGET = 10.2;
192 | };
193 | name = Debug;
194 | };
195 | 6463C8531EBA12A60095B8CD /* Release */ = {
196 | isa = XCBuildConfiguration;
197 | buildSettings = {
198 | CLANG_ANALYZER_NONNULL = YES;
199 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
200 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
201 | CLANG_WARN_INFINITE_RECURSION = YES;
202 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
203 | OTHER_LDFLAGS = "-ObjC";
204 | PRODUCT_NAME = SMXCrashlytics;
205 | SDKROOT = appletvos;
206 | SKIP_INSTALL = YES;
207 | TVOS_DEPLOYMENT_TARGET = 10.2;
208 | };
209 | name = Release;
210 | };
211 | D8D9DB6B1C6D01F4009FBC0E /* Debug */ = {
212 | isa = XCBuildConfiguration;
213 | buildSettings = {
214 | ALWAYS_SEARCH_USER_PATHS = NO;
215 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
216 | CLANG_CXX_LIBRARY = "libc++";
217 | CLANG_ENABLE_MODULES = YES;
218 | CLANG_ENABLE_OBJC_ARC = YES;
219 | CLANG_WARN_BOOL_CONVERSION = YES;
220 | CLANG_WARN_CONSTANT_CONVERSION = YES;
221 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
222 | CLANG_WARN_EMPTY_BODY = YES;
223 | CLANG_WARN_ENUM_CONVERSION = YES;
224 | CLANG_WARN_INFINITE_RECURSION = YES;
225 | CLANG_WARN_INT_CONVERSION = YES;
226 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
227 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
228 | CLANG_WARN_UNREACHABLE_CODE = YES;
229 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
230 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
231 | COPY_PHASE_STRIP = NO;
232 | CURRENT_PROJECT_VERSION = 1;
233 | DEBUG_INFORMATION_FORMAT = dwarf;
234 | ENABLE_STRICT_OBJC_MSGSEND = YES;
235 | ENABLE_TESTABILITY = YES;
236 | FRAMEWORK_SEARCH_PATHS = (
237 | "$(SRCROOT)/../example/ios",
238 | "$(SRCROOT)/../../../ios",
239 | "$(SRCROOT)/../../../",
240 | );
241 | GCC_C_LANGUAGE_STANDARD = gnu99;
242 | GCC_DYNAMIC_NO_PIC = NO;
243 | GCC_NO_COMMON_BLOCKS = YES;
244 | GCC_OPTIMIZATION_LEVEL = 0;
245 | GCC_PREPROCESSOR_DEFINITIONS = (
246 | "DEBUG=1",
247 | "$(inherited)",
248 | );
249 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
250 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
251 | GCC_WARN_UNDECLARED_SELECTOR = YES;
252 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
253 | GCC_WARN_UNUSED_FUNCTION = YES;
254 | GCC_WARN_UNUSED_VARIABLE = YES;
255 | HEADER_SEARCH_PATHS = "";
256 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
257 | MTL_ENABLE_DEBUG_INFO = YES;
258 | ONLY_ACTIVE_ARCH = YES;
259 | SDKROOT = iphoneos;
260 | TARGETED_DEVICE_FAMILY = "1,2";
261 | VERSIONING_SYSTEM = "apple-generic";
262 | VERSION_INFO_PREFIX = "";
263 | };
264 | name = Debug;
265 | };
266 | D8D9DB6C1C6D01F4009FBC0E /* Release */ = {
267 | isa = XCBuildConfiguration;
268 | buildSettings = {
269 | ALWAYS_SEARCH_USER_PATHS = NO;
270 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
271 | CLANG_CXX_LIBRARY = "libc++";
272 | CLANG_ENABLE_MODULES = YES;
273 | CLANG_ENABLE_OBJC_ARC = YES;
274 | CLANG_WARN_BOOL_CONVERSION = YES;
275 | CLANG_WARN_CONSTANT_CONVERSION = YES;
276 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
277 | CLANG_WARN_EMPTY_BODY = YES;
278 | CLANG_WARN_ENUM_CONVERSION = YES;
279 | CLANG_WARN_INFINITE_RECURSION = YES;
280 | CLANG_WARN_INT_CONVERSION = YES;
281 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
282 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
283 | CLANG_WARN_UNREACHABLE_CODE = YES;
284 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
285 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
286 | COPY_PHASE_STRIP = NO;
287 | CURRENT_PROJECT_VERSION = 1;
288 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
289 | ENABLE_NS_ASSERTIONS = NO;
290 | ENABLE_STRICT_OBJC_MSGSEND = YES;
291 | FRAMEWORK_SEARCH_PATHS = (
292 | "$(SRCROOT)/../example/ios",
293 | "$(SRCROOT)/../../../ios",
294 | "$(SRCROOT)/../../../",
295 | );
296 | GCC_C_LANGUAGE_STANDARD = gnu99;
297 | GCC_NO_COMMON_BLOCKS = YES;
298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
300 | GCC_WARN_UNDECLARED_SELECTOR = YES;
301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
302 | GCC_WARN_UNUSED_FUNCTION = YES;
303 | GCC_WARN_UNUSED_VARIABLE = YES;
304 | HEADER_SEARCH_PATHS = "";
305 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
306 | MTL_ENABLE_DEBUG_INFO = NO;
307 | SDKROOT = iphoneos;
308 | TARGETED_DEVICE_FAMILY = "1,2";
309 | VALIDATE_PRODUCT = YES;
310 | VERSIONING_SYSTEM = "apple-generic";
311 | VERSION_INFO_PREFIX = "";
312 | };
313 | name = Release;
314 | };
315 | D8D9DB8A1C6D03DB009FBC0E /* Debug */ = {
316 | isa = XCBuildConfiguration;
317 | buildSettings = {
318 | FRAMEWORK_SEARCH_PATHS = (
319 | "$(inherited)",
320 | "$(PROJECT_DIR)",
321 | "$(SRCROOT)/../../../ios/Crashlytics",
322 | "$(SRCROOT)/../../../ios/Pods/Crashlytics/iOS",
323 | );
324 | HEADER_SEARCH_PATHS = (
325 | "$(inherited)",
326 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
327 | "$(SRCROOT)/../../../ios/Pods/Headers/Public/Crashlytics",
328 | "$(SRCROOT)/../../../ios/Crashlytics/**",
329 | "$(SRCROOT)/../../../ios/**",
330 | );
331 | OTHER_LDFLAGS = "-ObjC";
332 | PRODUCT_NAME = "$(TARGET_NAME)";
333 | SKIP_INSTALL = YES;
334 | };
335 | name = Debug;
336 | };
337 | D8D9DB8B1C6D03DB009FBC0E /* Release */ = {
338 | isa = XCBuildConfiguration;
339 | buildSettings = {
340 | FRAMEWORK_SEARCH_PATHS = (
341 | "$(inherited)",
342 | "$(PROJECT_DIR)",
343 | "$(SRCROOT)/../../../ios/Crashlytics",
344 | "$(SRCROOT)/../../../ios/Pods/Crashlytics/iOS",
345 | );
346 | HEADER_SEARCH_PATHS = (
347 | "$(inherited)",
348 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
349 | "$(SRCROOT)/../../../ios/Pods/Headers/Public/Crashlytics",
350 | "$(SRCROOT)/../../../ios/Crashlytics/**",
351 | "$(SRCROOT)/../../../ios/**",
352 | );
353 | OTHER_LDFLAGS = "-ObjC";
354 | PRODUCT_NAME = "$(TARGET_NAME)";
355 | SKIP_INSTALL = YES;
356 | };
357 | name = Release;
358 | };
359 | /* End XCBuildConfiguration section */
360 |
361 | /* Begin XCConfigurationList section */
362 | 6463C8541EBA12A60095B8CD /* Build configuration list for PBXNativeTarget "SMXCrashlytics-tvOS" */ = {
363 | isa = XCConfigurationList;
364 | buildConfigurations = (
365 | 6463C8521EBA12A60095B8CD /* Debug */,
366 | 6463C8531EBA12A60095B8CD /* Release */,
367 | );
368 | defaultConfigurationIsVisible = 0;
369 | defaultConfigurationName = Release;
370 | };
371 | D8D9DB5F1C6D01F4009FBC0E /* Build configuration list for PBXProject "SMXCrashlytics" */ = {
372 | isa = XCConfigurationList;
373 | buildConfigurations = (
374 | D8D9DB6B1C6D01F4009FBC0E /* Debug */,
375 | D8D9DB6C1C6D01F4009FBC0E /* Release */,
376 | );
377 | defaultConfigurationIsVisible = 0;
378 | defaultConfigurationName = Release;
379 | };
380 | D8D9DB891C6D03DB009FBC0E /* Build configuration list for PBXNativeTarget "SMXCrashlytics" */ = {
381 | isa = XCConfigurationList;
382 | buildConfigurations = (
383 | D8D9DB8A1C6D03DB009FBC0E /* Debug */,
384 | D8D9DB8B1C6D03DB009FBC0E /* Release */,
385 | );
386 | defaultConfigurationIsVisible = 0;
387 | defaultConfigurationName = Release;
388 | };
389 | /* End XCConfigurationList section */
390 | };
391 | rootObject = D8D9DB5C1C6D01F4009FBC0E /* Project object */;
392 | }
393 |
--------------------------------------------------------------------------------
/ios/SMXCrashlytics/SMXAnswers.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface SMXAnswers : NSObject
5 |
6 | @end
7 |
8 |
--------------------------------------------------------------------------------
/ios/SMXCrashlytics/SMXAnswers.m:
--------------------------------------------------------------------------------
1 | #import "SMXAnswers.h"
2 | #import
3 | #import
4 | #import
5 | #import
6 |
7 | @implementation SMXAnswers
8 | @synthesize bridge = _bridge;
9 |
10 | RCT_EXPORT_MODULE();
11 |
12 | - (dispatch_queue_t)methodQueue
13 | {
14 | return dispatch_get_main_queue();
15 | }
16 |
17 |
18 | RCT_EXPORT_METHOD(logSignUp:(NSString *)signUpMethod
19 | success:(BOOL)succeeded
20 | customAttributes:(NSDictionary *)customAttributes)
21 | {
22 | [Answers logSignUpWithMethod:signUpMethod success:[NSNumber numberWithBool:succeeded] customAttributes:customAttributes];
23 | }
24 |
25 | RCT_EXPORT_METHOD(logLogin:(NSString *)loginMethod
26 | success:(BOOL)succeeded
27 | customAttributes:(NSDictionary *)customAttributes)
28 | {
29 | [Answers logLoginWithMethod:loginMethod success:[NSNumber numberWithBool:succeeded] customAttributes:customAttributes];
30 | }
31 |
32 | RCT_EXPORT_METHOD(logShare:(nullable NSString *)shareMethodOrNil
33 | contentName:(nullable NSString *)contentNameOrNil
34 | contentType:(nullable NSString *)contentTypeOrNil
35 | contentId:(nullable NSString *)contentIdOrNil
36 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil) {
37 | [Answers logShareWithMethod:shareMethodOrNil contentName:contentNameOrNil contentType:contentTypeOrNil contentId:contentIdOrNil customAttributes:customAttributesOrNil];
38 | }
39 |
40 | RCT_EXPORT_METHOD(logInvite:(nullable NSString *)inviteMethodOrNil
41 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
42 | [Answers logInviteWithMethod:inviteMethodOrNil customAttributes:customAttributesOrNil];
43 | }
44 |
45 | RCT_EXPORT_METHOD(logPurchase:(nullable NSString *)itemPriceOrNil
46 | currency:(nullable NSString *)currencyOrNil
47 | success:(BOOL)purchaseSucceeded
48 | itemName:(nullable NSString *)itemNameOrNil
49 | itemType:(nullable NSString *)itemTypeOrNil
50 | itemId:(nullable NSString *)itemIdOrNil
51 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
52 | [Answers logPurchaseWithPrice:[self getDecimalFromString:itemPriceOrNil] currency:currencyOrNil success:[NSNumber numberWithBool:purchaseSucceeded] itemName:itemNameOrNil itemType:itemTypeOrNil itemId:itemIdOrNil customAttributes:customAttributesOrNil];
53 | }
54 |
55 | RCT_EXPORT_METHOD(logLevelStart:(nullable NSString *)levelNameOrNil
56 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
57 | [Answers logLevelStart:levelNameOrNil customAttributes:customAttributesOrNil];
58 | }
59 |
60 | RCT_EXPORT_METHOD(logLevelEnd:(nullable NSString *)levelNameOrNil
61 | score:(nullable NSString *)scoreOrNil
62 | success:(BOOL)levelCompletedSuccesfully
63 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
64 | [Answers logLevelEnd:levelNameOrNil score:[self getDecimalFromString:scoreOrNil] success:[NSNumber numberWithBool:levelCompletedSuccesfully] customAttributes:customAttributesOrNil];
65 | }
66 |
67 | RCT_EXPORT_METHOD(logAddToCart:(nullable NSString *)itemPriceOrNil
68 | currency:(nullable NSString *)currencyOrNil
69 | itemName:(nullable NSString *)itemNameOrNil
70 | itemType:(nullable NSString *)itemTypeOrNil
71 | itemId:(nullable NSString *)itemIdOrNil
72 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
73 |
74 | [Answers logAddToCartWithPrice:[self getDecimalFromString:itemPriceOrNil] currency:currencyOrNil itemName:itemNameOrNil itemType:itemTypeOrNil itemId:itemIdOrNil customAttributes:customAttributesOrNil];
75 | }
76 |
77 | RCT_EXPORT_METHOD(logStartCheckout:(nullable NSString *)totalPriceOrNil
78 | currency:(nullable NSString *)currencyOrNil
79 | itemCount:(nullable NSString *)itemCountOrNil
80 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
81 | [Answers logStartCheckoutWithPrice:[self getDecimalFromString:totalPriceOrNil] currency:currencyOrNil itemCount:[self getIntegerFromString:itemCountOrNil] customAttributes:customAttributesOrNil];
82 | }
83 |
84 | RCT_EXPORT_METHOD(logRating:(nullable NSString *)ratingOrNil
85 | contentName:(nullable NSString *)contentNameOrNil
86 | contentType:(nullable NSString *)contentTypeOrNil
87 | contentId:(nullable NSString *)contentIdOrNil
88 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
89 | [Answers logRating:[self getDecimalFromString:ratingOrNil] contentName:contentNameOrNil contentType:contentTypeOrNil contentId:contentIdOrNil customAttributes:customAttributesOrNil];
90 | }
91 |
92 | RCT_EXPORT_METHOD(logContentView:(nullable NSString *)contentNameOrNil
93 | contentType:(nullable NSString *)contentTypeOrNil
94 | contentId:(nullable NSString *)contentIdOrNil
95 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
96 | [Answers logContentViewWithName:contentNameOrNil contentType:contentTypeOrNil contentId:contentIdOrNil customAttributes:customAttributesOrNil];
97 | }
98 |
99 | RCT_EXPORT_METHOD(logSearch:(nullable NSString *)queryOrNil
100 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
101 | [Answers logSearchWithQuery:queryOrNil customAttributes:customAttributesOrNil];
102 | }
103 |
104 | RCT_EXPORT_METHOD(logCustom:(NSString *)eventName
105 | customAttributes:(nullable ANS_GENERIC_NSDICTIONARY(NSString *, id) *)customAttributesOrNil){
106 | [Answers logCustomEventWithName:eventName customAttributes:customAttributesOrNil];
107 | }
108 |
109 | - (NSDecimalNumber *)getDecimalFromString:(NSString *)stringValue {
110 | if(stringValue != nil) {
111 | return [NSDecimalNumber decimalNumberWithString:stringValue];
112 | }
113 | return nil;
114 | }
115 |
116 | - (NSNumber *)getIntegerFromString:(NSString *)stringValue {
117 | if(stringValue != nil) {
118 | return [NSNumber numberWithInteger:[stringValue integerValue]];
119 | }
120 | return nil;
121 | }
122 |
123 | @end
124 |
--------------------------------------------------------------------------------
/ios/SMXCrashlytics/SMXCrashlytics.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface SMXCrashlytics : NSObject
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/SMXCrashlytics/SMXCrashlytics.m:
--------------------------------------------------------------------------------
1 | #import "SMXCrashlytics.h"
2 | #import
3 |
4 | @implementation SMXCrashlytics
5 | @synthesize bridge = _bridge;
6 |
7 | NSString *const DefaultDomain = @"com.smixx.fabric.SMXCrashlytics";
8 | NSInteger const DefaultCode = 100;
9 |
10 | RCT_EXPORT_MODULE();
11 |
12 | - (dispatch_queue_t)methodQueue
13 | {
14 | return dispatch_get_main_queue();
15 | }
16 |
17 | RCT_EXPORT_METHOD(log:(NSString *)message)
18 | {
19 | CLS_LOG(@"%@", message);
20 | }
21 |
22 | RCT_EXPORT_METHOD(recordError:(NSDictionary *)error)
23 | {
24 | NSInteger code;
25 | NSString *domain;
26 | NSObject *codeObject = [error objectForKey:@"code"];
27 | if (codeObject && [codeObject isKindOfClass:NSNumber.class])
28 | code = [(NSNumber *)codeObject intValue];
29 | else
30 | code = DefaultCode;
31 | if ([error objectForKey:@"domain"])
32 | domain = [error valueForKey:@"domain"];
33 | else
34 | domain = DefaultDomain;
35 |
36 | NSError *error2 = [NSError errorWithDomain:domain code:code userInfo:error];
37 | [[Crashlytics sharedInstance] recordError:error2];
38 | }
39 |
40 | RCT_EXPORT_METHOD(crash)
41 | {
42 | [[Crashlytics sharedInstance] crash];
43 | }
44 |
45 | RCT_EXPORT_METHOD(throwException)
46 | {
47 | [[Crashlytics sharedInstance] throwException];
48 | }
49 |
50 | RCT_EXPORT_METHOD(setUserIdentifier:(NSString *)userIdentifier)
51 | {
52 | [[Crashlytics sharedInstance] setUserIdentifier:userIdentifier];
53 | }
54 |
55 | RCT_EXPORT_METHOD(setUserName:(NSString *)userName)
56 | {
57 | [[Crashlytics sharedInstance] setUserName:userName];
58 | }
59 |
60 | RCT_EXPORT_METHOD(setUserEmail:(NSString *)email)
61 | {
62 | [[Crashlytics sharedInstance] setUserEmail:email];
63 | }
64 |
65 | RCT_EXPORT_METHOD(setBool:(NSString *)key value:(BOOL)boolValue)
66 | {
67 | [[Crashlytics sharedInstance] setBoolValue:boolValue forKey:key];
68 | }
69 |
70 | RCT_EXPORT_METHOD(setString:(NSString *)key value:(NSString *)stringValue)
71 | {
72 | [[Crashlytics sharedInstance] setObjectValue:stringValue forKey:key];
73 | }
74 |
75 | RCT_EXPORT_METHOD(setNumber:(NSString *)key value:(nonnull NSNumber *)numberValue)
76 | {
77 | if(numberValue) {
78 | const char *objCType = [numberValue objCType];
79 | if(KWObjCTypeIsFloatingPoint(objCType)) {
80 | [[Crashlytics sharedInstance] setFloatValue:[numberValue floatValue] forKey:key];
81 | } else if(KWObjCTypeIsIntegral(objCType)) {
82 | [[Crashlytics sharedInstance] setIntValue:[numberValue intValue] forKey:key];
83 | }
84 | }
85 | }
86 |
87 | RCT_EXPORT_METHOD(recordCustomExceptionName:(nonnull NSString *)name reason:(NSString *)reason frameArray:(nonnull NSArray *)frameArray)
88 | {
89 | NSMutableArray *clsFrames = [[NSMutableArray alloc] init];
90 | if(frameArray) {
91 | for (NSDictionary *dict in frameArray) {
92 | CLSStackFrame *frame = [CLSStackFrame stackFrame];
93 | [frame setFileName: dict[@"fileName"]];
94 | [frame setLineNumber: [dict[@"lineNumber"] intValue]];
95 | [frame setOffset: [dict[@"columnNumber"] intValue]];
96 | [frame setSymbol: dict[@"functionName"]];
97 | [clsFrames addObject: frame];
98 | }
99 | [[Crashlytics sharedInstance] recordCustomExceptionName:name reason:reason frameArray:clsFrames];
100 | }
101 | }
102 |
103 | // These functions are borrowed from https://github.com/joecannatti/Objective-C-Koans
104 | BOOL KWObjCTypeIsFloatingPoint(const char *objCType) {
105 | return strcmp(objCType, @encode(float)) == 0 || strcmp(objCType, @encode(double)) == 0;
106 | }
107 |
108 | BOOL KWObjCTypeIsIntegral(const char *objCType) {
109 | return KWObjCTypeIsSignedIntegral(objCType) || KWObjCTypeIsUnsignedIntegral(objCType);
110 | }
111 |
112 | BOOL KWObjCTypeIsSignedIntegral(const char *objCType) {
113 | return strcmp(objCType, @encode(char)) == 0 ||
114 | strcmp(objCType, @encode(int)) == 0 ||
115 | strcmp(objCType, @encode(short)) == 0 ||
116 | strcmp(objCType, @encode(long)) == 0 ||
117 | strcmp(objCType, @encode(long long)) == 0;
118 | }
119 |
120 | BOOL KWObjCTypeIsUnsignedIntegral(const char *objCType) {
121 | return strcmp(objCType, @encode(unsigned char)) == 0 ||
122 | strcmp(objCType, @encode(unsigned int)) == 0 ||
123 | strcmp(objCType, @encode(unsigned short)) == 0 ||
124 | strcmp(objCType, @encode(unsigned long)) == 0 ||
125 | strcmp(objCType, @encode(unsigned long long)) == 0;
126 | }
127 |
128 | //RCT_EXPORT_METHOD(setInt:(NSString *)key value:(int)integer)
129 | //{
130 | // [[Crashlytics sharedInstance] setIntValue:integer forKey:key];
131 | //}
132 |
133 | //RCT_EXPORT_METHOD(setFloat:(NSString *)key value:(float)floatValue)
134 | //{
135 | // [[Crashlytics sharedInstance] setFloatValue:floatValue forKey:key];
136 | //}
137 |
138 | //RCT_EXPORT_METHOD(setObject:(NSString *)key value:(NSDictionary *)obj)
139 | //{
140 | // [[Crashlytics sharedInstance] setObjectValue:obj forKey:key];
141 | //}
142 |
143 | @end
144 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-fabric",
3 | "description": "A React Native library for Fabric, Crashlytics and Answers",
4 | "version": "0.5.2",
5 | "author": {
6 | "name": "Cory Smith",
7 | "email": "cory.m.smith@gmail.com"
8 | },
9 | "bugs": {
10 | "url": "https://github.com/corymsmith/react-native-fabric/issues"
11 | },
12 | "devDependencies": {
13 | "@commitlint/cli": "^7.0.0",
14 | "@commitlint/config-conventional": "^7.0.1",
15 | "babel-eslint": "^8.2.6",
16 | "eslint": "^5.3.0",
17 | "eslint-plugin-flowtype": "^2.50.0",
18 | "eslint-plugin-import": "^2.13.0",
19 | "eslint-plugin-react": "^7.10.0",
20 | "eslint-plugin-react-native": "^3.2.1",
21 | "flow-bin": "^0.81.0",
22 | "generate-changelog": "^1.7.1",
23 | "husky": "^0.14.3",
24 | "idx": "^2.4.0",
25 | "minimist": "^1.2.0",
26 | "pre-commit": "^1.2.2",
27 | "prettier": "^1.14.3",
28 | "simple-git": "^1.102.0",
29 | "lint-staged": "^7.2.0",
30 | "react": "16.8.6",
31 | "react-native": "^0.60.0"
32 | },
33 | "homepage": "https://github.com/corymsmith/react-native-fabric",
34 | "keywords": [
35 | "android",
36 | "answers",
37 | "crashlytics",
38 | "fabric",
39 | "ios",
40 | "mobile",
41 | "react",
42 | "react-component",
43 | "react-native",
44 | "react-native-component"
45 | ],
46 | "license": "MIT",
47 | "lint-staged": {
48 | "*.js": [
49 | "yarn prettier",
50 | "eslint --fix",
51 | "git add"
52 | ]
53 | },
54 | "main": "src/index.js",
55 | "nativePackage": true,
56 | "pre-commit": "lint:staged",
57 | "repository": {
58 | "type": "git",
59 | "url": "git://github.com/corymsmith/react-native-fabric.git"
60 | },
61 | "scripts": {
62 | "commitmsg": "commitlint -e $GIT_PARAMS",
63 | "lint": "eslint src",
64 | "lint:staged": "lint-staged",
65 | "prettier": "prettier --write --single-quote true --trailing-comma all --print-width 100",
66 | "release:major": "node ./changelog --major && npm version major && git push origin && git push origin --follow-tags",
67 | "release:minor": "node ./changelog --minor && npm version minor && git push origin && git push origin --follow-tags",
68 | "release:patch": "node ./changelog --patch && npm version patch && git push origin && git push origin --follow-tags",
69 | "test": "flow"
70 | },
71 | "typings": "typings/react-native-fabric.d.ts"
72 | }
73 |
--------------------------------------------------------------------------------
/react-native.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | project: {
3 | android: {
4 | packageInstance: "new FabricPackage()"
5 | },
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/src/Answers.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @providesModule Answers
3 | */
4 | // @flow
5 |
6 | import { NativeModules } from 'react-native';
7 | const SMXAnswers = NativeModules.SMXAnswers;
8 |
9 | function getAsStringOrNull(value: number): string {
10 | if (value == null) return value;
11 | return value + '';
12 | }
13 |
14 | export const Answers = {
15 | logCustom: function(eventName: string, customAttributes?: Object) {
16 | SMXAnswers.logCustom(eventName, customAttributes);
17 | },
18 | logAddToCart: function(
19 | itemPrice: number,
20 | currency: string,
21 | itemName: string,
22 | itemType: string,
23 | itemId: string,
24 | customAttributes?: Object,
25 | ) {
26 | SMXAnswers.logAddToCart(
27 | getAsStringOrNull(itemPrice),
28 | currency,
29 | itemName,
30 | itemType,
31 | itemId,
32 | customAttributes,
33 | );
34 | },
35 |
36 | logContentView: function(
37 | contentName: string,
38 | contentType?: string,
39 | contentId?: string,
40 | customAttributes?: Object,
41 | ) {
42 | SMXAnswers.logContentView(contentName, contentType, contentId, customAttributes);
43 | },
44 |
45 | logInvite: function(method: string, customAttributes?: Object) {
46 | SMXAnswers.logInvite(method, customAttributes);
47 | },
48 |
49 | logLevelStart: function(levelName: string, customAttributes?: Object) {
50 | SMXAnswers.logLevelStart(levelName, customAttributes);
51 | },
52 |
53 | logLevelEnd: function(
54 | levelName: string,
55 | score: number,
56 | success: boolean,
57 | customAttributes?: Object,
58 | ) {
59 | SMXAnswers.logLevelEnd(levelName, getAsStringOrNull(score), success, customAttributes);
60 | },
61 |
62 | logLogin: function(method: string, success: boolean, customAttributes?: Object) {
63 | SMXAnswers.logLogin(method, success, customAttributes);
64 | },
65 |
66 | logPurchase: function(
67 | itemPrice: number,
68 | currency: string,
69 | success: boolean,
70 | itemName: string,
71 | itemType: string,
72 | itemId: string,
73 | customAttributes?: Object,
74 | ) {
75 | SMXAnswers.logPurchase(
76 | getAsStringOrNull(itemPrice),
77 | currency,
78 | success,
79 | itemName,
80 | itemType,
81 | itemId,
82 | customAttributes,
83 | );
84 | },
85 |
86 | logRating: function(
87 | rating: number,
88 | contentId: string,
89 | contentType: string,
90 | contentName: string,
91 | customAttributes?: Object,
92 | ) {
93 | SMXAnswers.logRating(
94 | getAsStringOrNull(rating),
95 | contentId,
96 | contentType,
97 | contentName,
98 | customAttributes,
99 | );
100 | },
101 |
102 | logSearch: function(query: string, customAttributes?: Object) {
103 | SMXAnswers.logSearch(query, customAttributes);
104 | },
105 |
106 | logShare: function(
107 | method: string,
108 | contentName: string,
109 | contentType: string,
110 | contentId: string,
111 | customAttributes?: Object,
112 | ) {
113 | SMXAnswers.logShare(method, contentName, contentType, contentId, customAttributes);
114 | },
115 |
116 | logSignUp: function(method: string, success: boolean, customAttributes?: Object) {
117 | SMXAnswers.logSignUp(method, success, customAttributes);
118 | },
119 |
120 | logStartCheckout: function(
121 | totalPrice: number,
122 | count: number,
123 | currency: string,
124 | customAttributes?: Object,
125 | ) {
126 | SMXAnswers.logStartCheckout(
127 | getAsStringOrNull(totalPrice),
128 | getAsStringOrNull(count),
129 | currency,
130 | customAttributes,
131 | );
132 | },
133 | };
134 |
--------------------------------------------------------------------------------
/src/Crashlytics.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @providesModule Crashlytics
3 | */
4 | // @flow
5 |
6 | import { NativeModules, Platform } from 'react-native';
7 | const SMXCrashlytics = NativeModules.SMXCrashlytics;
8 |
9 | export const Crashlytics = {
10 | crash: SMXCrashlytics.crash,
11 | throwException: SMXCrashlytics.throwException,
12 |
13 | /**
14 | * Convert error into something the native code knows what to do with.
15 | * Attempts to be flexible and accept error objects in different formats.
16 | * We need to be careful which data types we send to the native layer.
17 | * Could do something much fancier here, e.g., deep, recursive serialization
18 | * (or "flattening") but keep it simple for now.
19 | * @param error
20 | */
21 | recordError: function(error: mixed) {
22 | var newError;
23 |
24 | if (typeof error === 'string' || error instanceof String) {
25 | newError = { domain: error };
26 | } else if (typeof error === 'number') {
27 | newError = { code: error };
28 | } else if (typeof error === 'object') {
29 | newError = {};
30 |
31 | // Pass everything in as a string or number to be safe
32 | for (var k in error) {
33 | if (error.hasOwnProperty(k)) {
34 | if (
35 | typeof error[k] !== 'number' &&
36 | typeof error[k] !== 'string' &&
37 | !(error[k] instanceof String)
38 | ) {
39 | newError[k] = JSON.stringify(error[k]);
40 | } else {
41 | newError[k] = error[k];
42 | }
43 | }
44 | }
45 | } else {
46 | // Array?
47 | // Fall back on JSON
48 | newError = {
49 | json: JSON.stringify(error),
50 | };
51 | }
52 | SMXCrashlytics.recordError(newError);
53 | },
54 |
55 | logException: function(value: string) {
56 | SMXCrashlytics.logException(value);
57 | },
58 |
59 | log: function(message: string) {
60 | SMXCrashlytics.log(message);
61 | },
62 |
63 | setUserEmail: function(email: string | null) {
64 | SMXCrashlytics.setUserEmail(email);
65 | },
66 |
67 | setUserIdentifier: function(userIdentifier: string | null) {
68 | SMXCrashlytics.setUserIdentifier(userIdentifier);
69 | },
70 |
71 | setUserName: function(userName: string | null) {
72 | SMXCrashlytics.setUserName(userName);
73 | },
74 |
75 | setBool: function(key: string, value: boolean) {
76 | SMXCrashlytics.setBool(key, value);
77 | },
78 |
79 | setNumber: function(key: string, value: number) {
80 | // This is a hack but allows us to have a standard API for both platforms
81 | if (Platform.OS === 'android') SMXCrashlytics.setNumber(key, value + '');
82 | else SMXCrashlytics.setNumber(key, value);
83 | },
84 |
85 | setString: function(key: string, value: string) {
86 | SMXCrashlytics.setString(key, value);
87 | },
88 |
89 | recordCustomExceptionName: function(name: string, reason: string, stack?: Object[]) {
90 | SMXCrashlytics.recordCustomExceptionName(name, reason, stack || []);
91 | },
92 | };
93 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | export { Crashlytics } from './Crashlytics';
4 | export { Answers } from './Answers';
5 |
--------------------------------------------------------------------------------
/typings/react-native-fabric.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * react-native-fabric.d.ts
3 | *
4 | * Type definition file for the react native fabric package
5 | */
6 |
7 | declare module 'react-native-fabric' {
8 | interface Fabric {
9 |
10 | /**
11 | * API for interacting with the Crashlytics kit.
12 | *
13 | * https://docs.fabric.io/ios/crashlytics/index.html
14 | */
15 | Crashlytics: {
16 | crash(): void;
17 | throwException(): void;
18 | recordError(error: string | number | Object): void;
19 |
20 | logException(value: string): void;
21 | log(message: string): void;
22 | setUserEmail(email: string): void;
23 | setUserIdentifier(userIdentifier: string): void;
24 | setUserName(userName: string): void;
25 | setBool(key: string, value: boolean): void;
26 | setNumber(key: string, value: number): void;
27 | setString(key: string, value: string): void;
28 | recordCustomExceptionName(name: string, reason: string, frameArray: Array