├── README.md ├── example ├── .buckconfig ├── .flowconfig ├── .gitignore ├── .watchmanconfig ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── MainActivity.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 ├── app │ ├── fetch.js │ └── realm.js ├── index.android.js ├── index.ios.js ├── ios │ ├── example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── 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 ├── package.json └── src ├── index.js └── storages ├── fetch.js └── realm.js /README.md: -------------------------------------------------------------------------------- 1 | # react-native-backbone 2 | 3 | As react native does not support Node.js HTTP module, react-native-backbone helps you to connect to your REST api or localStorage much easier using the same concept of Backbone models and collections. 4 | * You can simply call "save", "fetch", "destroy" method on each model to sycn them to your REST api. 5 | * "fetch" collections from REST api. 6 | * Using model.get() to retrieve data from model 7 | * Add an extra layer of the fetch method to check if the status API returns is not 200. Returns an json file instead of response object. 8 | 9 | To do: 10 | * syncronize with localStorage 11 | 12 | ### Table of content 13 | * [Setup](#install) 14 | * [RNBackbone.Model](#rnbackbonemodel) 15 | * [RNBackbone.Collection](#rnbackbonecollection) 16 | * [RNBackbone.Storage](#storage) 17 | * [fetchStorage](#fetchstorage) 18 | * [realmStorage](#realm) 19 | 20 | ## Install 21 | 22 | The easiest way to install: `npm install react-native-backbone` 23 | 24 | And require it in your React Native app: `var RNBackbone = require('react-native-backbone');` or ES6: `import RNBackbone from 'react-native-backbone'`; 25 | 26 | ## RNBackbone.Model 27 | RNBackbone.Model is extended from backbone. The usages is almost the same as Backbone.Model, but some methods might be differnt. 28 | 29 | #### Create a model class 30 | ``` 31 | var Car = RNBackbone.Model.extend({ 32 | rootUrl: "http://www.your-domain.com/car" 33 | //More options to be added 34 | }); 35 | ``` 36 | rootUrl: the root url where this model connects to. 37 | * value: `String` or `function`. If its a function it should return a string. 38 | 39 | #### Create an instance 40 | ``` 41 | var bmw = new Car({ 42 | "make": "BMW", 43 | "model": "428i", 44 | "year": 2014 45 | }) 46 | ``` 47 | You can create a model using the `new` keyword. You can pass an object as the initial value of the model, you can also create an empty model. 48 | 49 | #### Model methods: 50 | ##### set(): 51 | ``` 52 | bmw.set('mpg', '23') 53 | ``` 54 | this will set the atrribute mpg to 23. 55 | * If the attribute does not exist, this attribute will be added to the model. 56 | * If the attribute does exist, the value will be replaced. 57 | 58 | You can also pass a json object as the argument: 59 | ``` 60 | bmw.set({ 61 | "mpg": 23, 62 | "color": "white" 63 | }) 64 | ``` 65 | 66 | ##### unset(): 67 | ``` 68 | bmw.unset('mpg', '23') 69 | ``` 70 | The attribute "mpg" will be deleted 71 | * Unset does not take json object or array as argument. 72 | 73 | ##### isNew(): 74 | ``` 75 | bmw.isNew(); 76 | ``` 77 | This will return ture if "id" attribute does not exist 78 | 79 | ##### save(): 80 | ``` 81 | var option = { 82 | headers:{ 83 | "Authentication":"Bearer SOME_TOKEN" 84 | } 85 | } 86 | 87 | bmw.save(option, function(error){ 88 | if(error) console.log(error); 89 | console.log(people); 90 | }); 91 | ``` 92 | Save this model to the server, this is POST for new model and PUT for existing model 93 | * option: (optional) 94 | ** option.headers: the headers to be added to the HTTP request 95 | 96 | ##### fetch(): 97 | ``` 98 | bmw = new Car({ 99 | id: 1 100 | }); 101 | 102 | bmw.fetch(function(error){ 103 | if(error) console.log(error); 104 | console.log(people); 105 | }); 106 | ``` 107 | Fetch this model from the server, this is GET request 108 | * To fetch an model, ID has to be set. 109 | * option: (optional) 110 | ** option.headers: the headers to be added to the HTTP request 111 | 112 | ##### delete(): 113 | ``` 114 | bmw.delete(option, function(error){ 115 | if(error) console.log(error); 116 | }); 117 | ``` 118 | Delete this model to the server, this is DELETE method 119 | * To delete an model, ID has to be set. 120 | * option: (optional) 121 | ** option.headers: the headers to be added to the HTTP request 122 | 123 | ## RNBackbone.Collection 124 | There is only one sync method supported for collection: fetch 125 | ``` 126 | var Cars = RNBackbone.Colletion.extend({ 127 | model: Car, 128 | url: 'https://YOUR_URL/cars 129 | }); 130 | var cars = new Cars(); 131 | cars.fetch({ 132 | success: ()=>{ 133 | console.log(cars); 134 | } 135 | }) 136 | ``` 137 | 138 | ## Storage 139 | As of react-native-backbone 0.1.0, we provides two different storage connectors. 140 | 141 | ### fetchStorage 142 | fetchStorage is the default storage connectors used by RNBackbone. It uses the built-in "fetch" method of React-Native 143 | 144 | #### fetchStorage.globalOption.headers 145 | If you want to send some headers in every request, you can set it up here. 146 | ``` 147 | import fetchStorage from 'react-native-backbone/src/storages/fetch' 148 | fetchStorage.globalOption.headers:{ 149 | "Authentiacation":"Bearer SOME_TOKEN" 150 | } 151 | ``` 152 | 153 | #### fetchStorage.send() 154 | Send simple HTTP request 155 | This is based on the React Native fetch method. It has a simple error checking to check if the response status is not between 200-208 or 226. 156 | The returned object is a json instead of a response object 157 | 158 | ``` 159 | //Set up request object 160 | var request = { 161 | method: 'post', 162 | headers: { 163 | 'Accept': 'application/json', 164 | 'Content-Type': 'application/json' 165 | }, 166 | body: JSON.stringify({ 167 | "app":"FM Business", 168 | "platform":"iOS" 169 | }) 170 | } 171 | 172 | var url = 'https://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA'; 173 | 174 | fetchStorage.send(url, request, function(error, json){ 175 | if(error) 176 | console.log("encountered error: ", error); 177 | console.log(json); 178 | }); 179 | ``` 180 | request object: the same object used for fetch() 181 | 182 | ### Realm 183 | React Native's "asycnStorage" is a key-value pair storage, which is not ideal for the backbone concept. 184 | react native backbone uses a JavaScript library [Realm](https://realm.io/products/react-native/) for local storage 185 | 186 | #### Setting up Realm 187 | * RNBackbone has declared Realm as its dependency. But if you plan to use Realm in your project, you have to set it up using [rnpm](https://github.com/rnpm/rnpm): 188 | `rpm link realm` 189 | * Then you have to config RNBackbone to use Realm: 190 | ``` 191 | import RNBackbone from 'react-native-backbone'; 192 | import realmStorage from 'react-native-backbone/src/storages/realm'; 193 | RNBackbone.storage = realmStroage; 194 | ``` 195 | * Realm requires you to declare the schema of each Models before using them: 196 | ``` 197 | const CarSchema = { 198 | name: 'Car', 199 | properties: { 200 | make: 'string', 201 | model: 'string', 202 | miles: {type: 'int', default: 0}, 203 | } 204 | }; 205 | ``` 206 | _Realm doc about models: https://realm.io/docs/react-native/latest/#models_ 207 | 208 | * Initialize realmStorage: 209 | * Realm requires to provide **ALL** schemas before using it. 210 | * realmStorage connector's `init()` methods allows RNBackbone to create a Realm instance using your schemas. 211 | ``` 212 | realmStorage.init({ 213 | models: [Car, People] 214 | }); 215 | ``` 216 | _Realm doc about models: https://realm.io/docs/react-native/latest/#models_ 217 | 218 | Now you can start using RNBackbone as normal 219 | 220 | #### Realm Filter 221 | If you are fetching a collection and you want to filter the objects, you can pass the filter option to the fetch method: 222 | ``` 223 | var Cars = RNBackbone.Colletion.extend({ 224 | model: Car, 225 | url: 'https://YOUR_URL/cars 226 | }); 227 | var cars = new Cars(); 228 | cars.fetch({ 229 | filters: { 230 | make: 'bmw' 231 | }, 232 | success: ()=>{ 233 | console.log(cars); 234 | } 235 | }) 236 | -------------------------------------------------------------------------------- /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 | 3 | # We fork some components by platform. 4 | .*/*.web.js 5 | .*/*.android.js 6 | 7 | # Some modules have their own node_modules with overlap 8 | .*/node_modules/node-haste/.* 9 | 10 | # Ugh 11 | .*/node_modules/babel.* 12 | .*/node_modules/babylon.* 13 | .*/node_modules/invariant.* 14 | 15 | # Ignore react and fbjs where there are overlaps, but don't ignore 16 | # anything that react-native relies on 17 | .*/node_modules/fbjs/lib/Map.js 18 | .*/node_modules/fbjs/lib/ErrorUtils.js 19 | 20 | # Flow has a built-in definition for the 'react' module which we prefer to use 21 | # over the currently-untyped source 22 | .*/node_modules/react/react.js 23 | .*/node_modules/react/lib/React.js 24 | .*/node_modules/react/lib/ReactDOM.js 25 | 26 | .*/__mocks__/.* 27 | .*/__tests__/.* 28 | 29 | .*/commoner/test/source/widget/share.js 30 | 31 | # Ignore commoner tests 32 | .*/node_modules/commoner/test/.* 33 | 34 | # See https://github.com/facebook/flow/issues/442 35 | .*/react-tools/node_modules/commoner/lib/reader.js 36 | 37 | # Ignore jest 38 | .*/node_modules/jest-cli/.* 39 | 40 | # Ignore Website 41 | .*/website/.* 42 | 43 | # Ignore generators 44 | .*/local-cli/generator.* 45 | 46 | # Ignore BUCK generated folders 47 | .*\.buckd/ 48 | 49 | # Ignore RNPM 50 | .*/local-cli/rnpm/.* 51 | 52 | .*/node_modules/is-my-json-valid/test/.*\.json 53 | .*/node_modules/iconv-lite/encodings/tables/.*\.json 54 | .*/node_modules/y18n/test/.*\.json 55 | .*/node_modules/spdx-license-ids/spdx-license-ids.json 56 | .*/node_modules/spdx-exceptions/index.json 57 | .*/node_modules/resolve/test/subdirs/node_modules/a/b/c/x.json 58 | .*/node_modules/resolve/lib/core.json 59 | .*/node_modules/jsonparse/samplejson/.*\.json 60 | .*/node_modules/json5/test/.*\.json 61 | .*/node_modules/ua-parser-js/test/.*\.json 62 | .*/node_modules/builtin-modules/builtin-modules.json 63 | .*/node_modules/binary-extensions/binary-extensions.json 64 | .*/node_modules/url-regex/tlds.json 65 | .*/node_modules/joi/.*\.json 66 | .*/node_modules/isemail/.*\.json 67 | .*/node_modules/tr46/.*\.json 68 | 69 | 70 | [include] 71 | 72 | [libs] 73 | node_modules/react-native/Libraries/react-native/react-native-interface.js 74 | node_modules/react-native/flow 75 | flow/ 76 | 77 | [options] 78 | module.system=haste 79 | 80 | esproposal.class_static_fields=enable 81 | esproposal.class_instance_fields=enable 82 | 83 | munge_underscores=true 84 | 85 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' 86 | 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' 87 | 88 | suppress_type=$FlowIssue 89 | suppress_type=$FlowFixMe 90 | suppress_type=$FixMe 91 | 92 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-5]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 93 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-5]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 94 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 95 | 96 | [version] 97 | ^0.25.0 98 | -------------------------------------------------------------------------------- /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/IJ 26 | # 27 | .idea 28 | .gradle 29 | local.properties 30 | 31 | # node.js 32 | # 33 | node_modules/ 34 | npm-debug.log 35 | 36 | # BUCK 37 | buck-out/ 38 | \.buckd/ 39 | android/app/libs 40 | android/keystores/debug.keystore 41 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /example/android/app/BUCK: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # To learn about Buck see [Docs](https://buckbuild.com/). 4 | # To run your application with Buck: 5 | # - install Buck 6 | # - `npm start` - to start the packager 7 | # - `cd android` 8 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US` 9 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 10 | # - `buck install -r android/app` - compile, install and run application 11 | # 12 | 13 | lib_deps = [] 14 | for jarfile in glob(['libs/*.jar']): 15 | name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) 16 | lib_deps.append(':' + name) 17 | prebuilt_jar( 18 | name = name, 19 | binary_jar = jarfile, 20 | ) 21 | 22 | for aarfile in glob(['libs/*.aar']): 23 | name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) 24 | lib_deps.append(':' + name) 25 | android_prebuilt_aar( 26 | name = name, 27 | aar = aarfile, 28 | ) 29 | 30 | android_library( 31 | name = 'all-libs', 32 | exported_deps = lib_deps 33 | ) 34 | 35 | android_library( 36 | name = 'app-code', 37 | srcs = glob([ 38 | 'src/main/java/**/*.java', 39 | ]), 40 | deps = [ 41 | ':all-libs', 42 | ':build_config', 43 | ':res', 44 | ], 45 | ) 46 | 47 | android_build_config( 48 | name = 'build_config', 49 | package = 'com.example', 50 | ) 51 | 52 | android_resource( 53 | name = 'res', 54 | res = 'src/main/res', 55 | package = 'com.example', 56 | ) 57 | 58 | android_binary( 59 | name = 'app', 60 | package_type = 'debug', 61 | manifest = 'src/main/AndroidManifest.xml', 62 | keystore = '//android/keystores:debug', 63 | deps = [ 64 | ':app-code', 65 | ], 66 | ) 67 | -------------------------------------------------------------------------------- /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 | */ 61 | 62 | apply from: "../../node_modules/react-native/react.gradle" 63 | 64 | /** 65 | * Set this to true to create two separate APKs instead of one: 66 | * - An APK that only works on ARM devices 67 | * - An APK that only works on x86 devices 68 | * The advantage is the size of the APK is reduced by about 4MB. 69 | * Upload all the APKs to the Play Store and people will download 70 | * the correct one based on the CPU architecture of their device. 71 | */ 72 | def enableSeparateBuildPerCPUArchitecture = false 73 | 74 | /** 75 | * Run Proguard to shrink the Java bytecode in release builds. 76 | */ 77 | def enableProguardInReleaseBuilds = false 78 | 79 | android { 80 | compileSdkVersion 23 81 | buildToolsVersion "23.0.1" 82 | 83 | defaultConfig { 84 | applicationId "com.example" 85 | minSdkVersion 16 86 | targetSdkVersion 22 87 | versionCode 1 88 | versionName "1.0" 89 | ndk { 90 | abiFilters "armeabi-v7a", "x86" 91 | } 92 | } 93 | splits { 94 | abi { 95 | reset() 96 | enable enableSeparateBuildPerCPUArchitecture 97 | universalApk false // If true, also generate a universal APK 98 | include "armeabi-v7a", "x86" 99 | } 100 | } 101 | buildTypes { 102 | release { 103 | minifyEnabled enableProguardInReleaseBuilds 104 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 105 | } 106 | } 107 | // applicationVariants are e.g. debug, release 108 | applicationVariants.all { variant -> 109 | variant.outputs.each { output -> 110 | // For each separate APK per architecture, set a unique version code as described here: 111 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 112 | def versionCodes = ["armeabi-v7a":1, "x86":2] 113 | def abi = output.getFilter(OutputFile.ABI) 114 | if (abi != null) { // null for the universal-debug, universal-release variants 115 | output.versionCodeOverride = 116 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 117 | } 118 | } 119 | } 120 | } 121 | 122 | dependencies { 123 | compile project(':realm') 124 | compile fileTree(dir: "libs", include: ["*.jar"]) 125 | compile "com.android.support:appcompat-v7:23.0.1" 126 | compile "com.facebook.react:react-native:+" // From node_modules 127 | } 128 | 129 | // Run this once to be able to run the application with BUCK 130 | // puts all compile dependencies into folder libs for BUCK to use 131 | task copyDownloadableDepsToLibs(type: Copy) { 132 | from configurations.compile 133 | into 'libs' 134 | } 135 | -------------------------------------------------------------------------------- /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 | 30 | # Do not strip any method/class that is annotated with @DoNotStrip 31 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 32 | -keepclassmembers class * { 33 | @com.facebook.proguard.annotations.DoNotStrip *; 34 | } 35 | 36 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 37 | void set*(***); 38 | *** get*(); 39 | } 40 | 41 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 42 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 43 | -keepclassmembers,includedescriptorclasses class * { native ; } 44 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 45 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 46 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 47 | 48 | -dontwarn com.facebook.react.** 49 | 50 | # okhttp 51 | 52 | -keepattributes Signature 53 | -keepattributes *Annotation* 54 | -keep class okhttp3.** { *; } 55 | -keep interface okhttp3.** { *; } 56 | -dontwarn okhttp3.** 57 | 58 | # okio 59 | 60 | -keep class sun.misc.Unsafe { *; } 61 | -dontwarn java.nio.file.* 62 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 63 | -dontwarn okio.** 64 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import io.realm.react.RealmReactPackage; 5 | import com.facebook.react.ReactPackage; 6 | import com.facebook.react.shell.MainReactPackage; 7 | 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class MainActivity extends ReactActivity { 12 | 13 | /** 14 | * Returns the name of the main component registered from JavaScript. 15 | * This is used to schedule rendering of the component. 16 | */ 17 | @Override 18 | protected String getMainComponentName() { 19 | return "example"; 20 | } 21 | 22 | /** 23 | * Returns whether dev mode should be enabled. 24 | * This enables e.g. the dev menu. 25 | */ 26 | @Override 27 | protected boolean getUseDeveloperSupport() { 28 | return BuildConfig.DEBUG; 29 | } 30 | 31 | /** 32 | * A list of packages used by the app. If the app uses additional views 33 | * or modules besides the default ones, add more packages here. 34 | */ 35 | @Override 36 | protected List getPackages() { 37 | return Arrays.asList( 38 | new MainReactPackage(), 39 | new RealmReactPackage() 40 | ); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peter4k/react-native-backbone/9806212487027aa10a0592a3b3ceb0b992de4454/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/peter4k/react-native-backbone/9806212487027aa10a0592a3b3ceb0b992de4454/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/peter4k/react-native-backbone/9806212487027aa10a0592a3b3ceb0b992de4454/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/peter4k/react-native-backbone/9806212487027aa10a0592a3b3ceb0b992de4454/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | example 4 | 5 | -------------------------------------------------------------------------------- /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:1.3.1' 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 "$projectDir/../../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/peter4k/react-native-backbone/9806212487027aa10a0592a3b3ceb0b992de4454/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.4-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 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 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 | include ':realm' 5 | project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android') 6 | -------------------------------------------------------------------------------- /example/app/fetch.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { 3 | Text, 4 | View 5 | } from 'react-native'; 6 | import RNBackbone from 'react-native-backbone'; 7 | import fetchStorage from 'react-native-backbone/src/storages/fetch'; 8 | 9 | class FetchStorageExample extends Component { 10 | 11 | constructor() { 12 | super(); 13 | this.state = { 14 | isLoading: true 15 | }; 16 | 17 | fetchStorage.globalOptions.headers = { 18 | "Authorization": "Bearer AUTH_TOKEN" 19 | }; 20 | 21 | var Businesses = RNBackbone.Collection.extend({ 22 | url: 'http://YOUR_URL/business' 23 | }); 24 | 25 | var businesses = this.business = new Businesses(); 26 | 27 | businesses.fetch({ 28 | success: () => { 29 | this.setState({isLoading: false}); 30 | }, 31 | error: (model, error) => { 32 | console.log(error); 33 | } 34 | }); 35 | } 36 | 37 | render() { 38 | if (this.state.isLoading) { 39 | return ( 40 | 41 | Fetching from API, please wait... 42 | 43 | ) 44 | } else { 45 | return ( 46 | 47 | Successfully fetched {this.business.length} models from REST api 48 | 49 | ) 50 | } 51 | } 52 | } 53 | 54 | export default FetchStorageExample; -------------------------------------------------------------------------------- /example/app/realm.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { 3 | Text, 4 | View 5 | } from 'react-native'; 6 | import RNBackbone from 'react-native-backbone'; 7 | import realmStorage from 'react-native-backbone/src/storages/realm'; 8 | 9 | //Config RNBackbone to use Realm as storage 10 | RNBackbone.storage = realmStorage; 11 | 12 | var Business = RNBackbone.Model.extend({ 13 | realmSchema:{ 14 | name: 'Business', 15 | properties: { 16 | name: 'string' 17 | } 18 | } 19 | }); 20 | 21 | var Businesses = RNBackbone.Collection.extend({ 22 | model: Business 23 | }); 24 | 25 | //It is very important to initialize Realm with all your models before using RNBackbone 26 | realmStorage.init({ 27 | models: [Business] 28 | }); 29 | 30 | class RealmStorageExample extends Component { 31 | 32 | constructor() { 33 | super(); 34 | this.state = { 35 | isLoading: true 36 | }; 37 | } 38 | 39 | componentDidMount() { 40 | var business = new Business({ 41 | name: 'some company' 42 | }); 43 | 44 | var businesses = this.businesses = new Businesses(); 45 | business.save(null, { 46 | success: () =>{ 47 | businesses.fetch({ 48 | success: () => { 49 | this.setState({ 50 | isLoading: false 51 | }) 52 | } 53 | }) 54 | } 55 | }); 56 | } 57 | 58 | render() { 59 | if (this.state.isLoading) { 60 | return ( 61 | 62 | Fetching from localStorage, please wait... 63 | 64 | ) 65 | } else { 66 | return ( 67 | 68 | Successfully fetched {this.businesses.length} models from REST api 69 | This example is creating a new object each time you reload it... 70 | 71 | ) 72 | } 73 | } 74 | } 75 | 76 | export default RealmStorageExample; 77 | -------------------------------------------------------------------------------- /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 | import Example from './app/fetch'; //Example using Fetch 15 | // import Example from './app/realm'; //Example using Realm 16 | 17 | class example extends Component { 18 | render() { 19 | return ( 20 | 21 | 22 | Welcome to React Native Backbone! 23 | 24 | 25 | You can comment out FetchStorage and try using Realm for local storage 26 | 27 | 28 | 29 | ); 30 | } 31 | } 32 | 33 | const styles = StyleSheet.create({ 34 | container: { 35 | flex: 1, 36 | justifyContent: 'center', 37 | alignItems: 'center', 38 | backgroundColor: '#F5FCFF', 39 | }, 40 | welcome: { 41 | fontSize: 20, 42 | textAlign: 'center', 43 | margin: 10, 44 | }, 45 | instructions: { 46 | textAlign: 'center', 47 | color: '#333333', 48 | marginBottom: 20, 49 | }, 50 | }); 51 | 52 | AppRegistry.registerComponent('example', () => example); 53 | -------------------------------------------------------------------------------- /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 | class example extends Component { 16 | render() { 17 | return ( 18 | 19 | 20 | Welcome to React Native! 21 | 22 | 23 | To get started, edit index.ios.js 24 | 25 | 26 | Press Cmd+R to reload,{'\n'} 27 | Cmd+D or shake 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/ios/example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | /* Begin PBXBuildFile section */ 9 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 10 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 11 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; }; 12 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; }; 13 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 14 | 00E356F31AD99517003FC87E /* exampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* exampleTests.m */; }; 15 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; 16 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 17 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; }; 18 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 19 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 20 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 21 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 22 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; 23 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; 24 | B23555F6702F4D92A9AC113D /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 73FCF332A9F240F6B1BC9A94 /* libRealmReact.a */; }; 25 | D57C98C5384F497A9C1D0E26 /* libc++.tbd in Resources */ = {isa = PBXBuildFile; fileRef = E2B42559B54740E88A6F2D1A /* libc++.tbd */; }; 26 | 476980E0C7E44A53B7A8202A /* libz.tbd in Resources */ = {isa = PBXBuildFile; fileRef = 0F84B00D9EE742E4B65AE5C6 /* libz.tbd */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 33 | proxyType = 2; 34 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 35 | remoteInfo = RCTActionSheet; 36 | }; 37 | 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 40 | proxyType = 2; 41 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 42 | remoteInfo = RCTGeolocation; 43 | }; 44 | 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */ = { 45 | isa = PBXContainerItemProxy; 46 | containerPortal = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 47 | proxyType = 2; 48 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676; 49 | remoteInfo = RCTImage; 50 | }; 51 | 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */ = { 52 | isa = PBXContainerItemProxy; 53 | containerPortal = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 54 | proxyType = 2; 55 | remoteGlobalIDString = 58B511DB1A9E6C8500147676; 56 | remoteInfo = RCTNetwork; 57 | }; 58 | 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 61 | proxyType = 2; 62 | remoteGlobalIDString = 832C81801AAF6DEF007FA2F7; 63 | remoteInfo = RCTVibration; 64 | }; 65 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { 66 | isa = PBXContainerItemProxy; 67 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 68 | proxyType = 1; 69 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A; 70 | remoteInfo = example; 71 | }; 72 | 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { 73 | isa = PBXContainerItemProxy; 74 | containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 75 | proxyType = 2; 76 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 77 | remoteInfo = RCTSettings; 78 | }; 79 | 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */ = { 80 | isa = PBXContainerItemProxy; 81 | containerPortal = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 82 | proxyType = 2; 83 | remoteGlobalIDString = 3C86DF461ADF2C930047B81A; 84 | remoteInfo = RCTWebSocket; 85 | }; 86 | 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { 87 | isa = PBXContainerItemProxy; 88 | containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; 89 | proxyType = 2; 90 | remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192; 91 | remoteInfo = React; 92 | }; 93 | 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */ = { 94 | isa = PBXContainerItemProxy; 95 | containerPortal = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 96 | proxyType = 2; 97 | remoteGlobalIDString = 134814201AA4EA6300B7C361; 98 | remoteInfo = RCTLinking; 99 | }; 100 | 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { 101 | isa = PBXContainerItemProxy; 102 | containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 103 | proxyType = 2; 104 | remoteGlobalIDString = 58B5119B1A9E6C1200147676; 105 | remoteInfo = RCTText; 106 | }; 107 | /* End PBXContainerItemProxy section */ 108 | 109 | /* Begin PBXFileReference section */ 110 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = main.jsbundle; sourceTree = ""; }; 111 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = ../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; }; 112 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = ../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = ""; }; 113 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = ../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj; sourceTree = ""; }; 114 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = ../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj; sourceTree = ""; }; 115 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = ../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = ""; }; 116 | 00E356EE1AD99517003FC87E /* exampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = exampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 117 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 118 | 00E356F21AD99517003FC87E /* exampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = exampleTests.m; sourceTree = ""; }; 119 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj; sourceTree = ""; }; 120 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = ../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = ""; }; 121 | 13B07F961A680F5B00A75B9A /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 122 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = example/AppDelegate.h; sourceTree = ""; }; 123 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = example/AppDelegate.m; sourceTree = ""; }; 124 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 125 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = example/Images.xcassets; sourceTree = ""; }; 126 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = example/Info.plist; sourceTree = ""; }; 127 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = example/main.m; sourceTree = ""; }; 128 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = ../node_modules/react-native/React/React.xcodeproj; sourceTree = ""; }; 129 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = ../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = ""; }; 130 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = ../node_modules/react-native/Libraries/Text/RCTText.xcodeproj; sourceTree = ""; }; 131 | 4311964B4B6B4849BB28D9BF /* RealmReact.xcodeproj */ = {isa = PBXFileReference; name = "RealmReact.xcodeproj"; path = "../node_modules/realm/react-native/ios/RealmReact.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; }; 132 | 73FCF332A9F240F6B1BC9A94 /* libRealmReact.a */ = {isa = PBXFileReference; name = "libRealmReact.a"; path = "libRealmReact.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; }; 133 | E2B42559B54740E88A6F2D1A /* libc++.tbd */ = {isa = PBXFileReference; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; }; 134 | 0F84B00D9EE742E4B65AE5C6 /* libz.tbd */ = {isa = PBXFileReference; name = "libz.tbd"; path = "usr/lib/libz.tbd"; sourceTree = SDKROOT; fileEncoding = undefined; lastKnownFileType = sourcecode.text-based-dylib-definition; explicitFileType = undefined; includeInIndex = 0; }; 135 | /* End PBXFileReference section */ 136 | 137 | /* Begin PBXFrameworksBuildPhase section */ 138 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 139 | isa = PBXFrameworksBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | ); 143 | runOnlyForDeploymentPostprocessing = 0; 144 | }; 145 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 146 | isa = PBXFrameworksBuildPhase; 147 | buildActionMask = 2147483647; 148 | files = ( 149 | 146834051AC3E58100842450 /* libReact.a in Frameworks */, 150 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 151 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */, 152 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */, 153 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */, 154 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */, 155 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 156 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 157 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 158 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, 159 | B23555F6702F4D92A9AC113D /* libRealmReact.a in Frameworks */, 160 | D57C98C5384F497A9C1D0E26 /* libc++.tbd in Resources */, 161 | 476980E0C7E44A53B7A8202A /* libz.tbd in Resources */, 162 | ); 163 | runOnlyForDeploymentPostprocessing = 0; 164 | }; 165 | /* End PBXFrameworksBuildPhase section */ 166 | 167 | /* Begin PBXGroup section */ 168 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */, 172 | ); 173 | name = Products; 174 | sourceTree = ""; 175 | }; 176 | 00C302B61ABCB90400DB3ED1 /* Products */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */, 180 | ); 181 | name = Products; 182 | sourceTree = ""; 183 | }; 184 | 00C302BC1ABCB91800DB3ED1 /* Products */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */, 188 | ); 189 | name = Products; 190 | sourceTree = ""; 191 | }; 192 | 00C302D41ABCB9D200DB3ED1 /* Products */ = { 193 | isa = PBXGroup; 194 | children = ( 195 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */, 196 | ); 197 | name = Products; 198 | sourceTree = ""; 199 | }; 200 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */, 204 | ); 205 | name = Products; 206 | sourceTree = ""; 207 | }; 208 | 00E356EF1AD99517003FC87E /* exampleTests */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 00E356F21AD99517003FC87E /* exampleTests.m */, 212 | 00E356F01AD99517003FC87E /* Supporting Files */, 213 | ); 214 | path = exampleTests; 215 | sourceTree = ""; 216 | }; 217 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | 00E356F11AD99517003FC87E /* Info.plist */, 221 | ); 222 | name = "Supporting Files"; 223 | sourceTree = ""; 224 | }; 225 | 139105B71AF99BAD00B5F7CC /* Products */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, 229 | ); 230 | name = Products; 231 | sourceTree = ""; 232 | }; 233 | 139FDEE71B06529A00C62182 /* Products */ = { 234 | isa = PBXGroup; 235 | children = ( 236 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */, 237 | ); 238 | name = Products; 239 | sourceTree = ""; 240 | }; 241 | 13B07FAE1A68108700A75B9A /* example */ = { 242 | isa = PBXGroup; 243 | children = ( 244 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */, 245 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 246 | 13B07FB01A68108700A75B9A /* AppDelegate.m */, 247 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 248 | 13B07FB61A68108700A75B9A /* Info.plist */, 249 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, 250 | 13B07FB71A68108700A75B9A /* main.m */, 251 | ); 252 | name = example; 253 | sourceTree = ""; 254 | }; 255 | 146834001AC3E56700842450 /* Products */ = { 256 | isa = PBXGroup; 257 | children = ( 258 | 146834041AC3E56700842450 /* libReact.a */, 259 | ); 260 | name = Products; 261 | sourceTree = ""; 262 | }; 263 | 78C398B11ACF4ADC00677621 /* Products */ = { 264 | isa = PBXGroup; 265 | children = ( 266 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */, 267 | ); 268 | name = Products; 269 | sourceTree = ""; 270 | }; 271 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 272 | isa = PBXGroup; 273 | children = ( 274 | 146833FF1AC3E56700842450 /* React.xcodeproj */, 275 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 276 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 277 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, 278 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 279 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, 280 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, 281 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 282 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 283 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */, 284 | 4311964B4B6B4849BB28D9BF /* RealmReact.xcodeproj */, 285 | ); 286 | name = Libraries; 287 | sourceTree = ""; 288 | }; 289 | 832341B11AAA6A8300B99B32 /* Products */ = { 290 | isa = PBXGroup; 291 | children = ( 292 | 832341B51AAA6A8300B99B32 /* libRCTText.a */, 293 | ); 294 | name = Products; 295 | sourceTree = ""; 296 | }; 297 | 83CBB9F61A601CBA00E9B192 = { 298 | isa = PBXGroup; 299 | children = ( 300 | 13B07FAE1A68108700A75B9A /* example */, 301 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 302 | 00E356EF1AD99517003FC87E /* exampleTests */, 303 | 83CBBA001A601CBA00E9B192 /* Products */, 304 | 997BC647A44447099BBAF6A9 /* Frameworks */, 305 | ); 306 | indentWidth = 2; 307 | sourceTree = ""; 308 | tabWidth = 2; 309 | }; 310 | 83CBBA001A601CBA00E9B192 /* Products */ = { 311 | isa = PBXGroup; 312 | children = ( 313 | 13B07F961A680F5B00A75B9A /* example.app */, 314 | 00E356EE1AD99517003FC87E /* exampleTests.xctest */, 315 | ); 316 | name = Products; 317 | sourceTree = ""; 318 | }; 319 | 997BC647A44447099BBAF6A9 /* Frameworks */ = { 320 | isa = PBXGroup; 321 | children = ( 322 | E2B42559B54740E88A6F2D1A /* libc++.tbd */, 323 | 0F84B00D9EE742E4B65AE5C6 /* libz.tbd */, 324 | ); 325 | name = Frameworks; 326 | path = ""; 327 | sourceTree = ""; 328 | }; 329 | /* End PBXGroup section */ 330 | 331 | /* Begin PBXNativeTarget section */ 332 | 00E356ED1AD99517003FC87E /* exampleTests */ = { 333 | isa = PBXNativeTarget; 334 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "exampleTests" */; 335 | buildPhases = ( 336 | 00E356EA1AD99517003FC87E /* Sources */, 337 | 00E356EB1AD99517003FC87E /* Frameworks */, 338 | 00E356EC1AD99517003FC87E /* Resources */, 339 | ); 340 | buildRules = ( 341 | ); 342 | dependencies = ( 343 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 344 | ); 345 | name = exampleTests; 346 | productName = exampleTests; 347 | productReference = 00E356EE1AD99517003FC87E /* exampleTests.xctest */; 348 | productType = "com.apple.product-type.bundle.unit-test"; 349 | }; 350 | 13B07F861A680F5B00A75B9A /* example */ = { 351 | isa = PBXNativeTarget; 352 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */; 353 | buildPhases = ( 354 | 13B07F871A680F5B00A75B9A /* Sources */, 355 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 356 | 13B07F8E1A680F5B00A75B9A /* Resources */, 357 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 358 | ); 359 | buildRules = ( 360 | ); 361 | dependencies = ( 362 | ); 363 | name = example; 364 | productName = "Hello World"; 365 | productReference = 13B07F961A680F5B00A75B9A /* example.app */; 366 | productType = "com.apple.product-type.application"; 367 | }; 368 | /* End PBXNativeTarget section */ 369 | 370 | /* Begin PBXProject section */ 371 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 372 | isa = PBXProject; 373 | attributes = { 374 | LastUpgradeCheck = 610; 375 | ORGANIZATIONNAME = Facebook; 376 | TargetAttributes = { 377 | 00E356ED1AD99517003FC87E = { 378 | CreatedOnToolsVersion = 6.2; 379 | TestTargetID = 13B07F861A680F5B00A75B9A; 380 | }; 381 | }; 382 | }; 383 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */; 384 | compatibilityVersion = "Xcode 3.2"; 385 | developmentRegion = English; 386 | hasScannedForEncodings = 0; 387 | knownRegions = ( 388 | en, 389 | Base, 390 | ); 391 | mainGroup = 83CBB9F61A601CBA00E9B192; 392 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 393 | projectDirPath = ""; 394 | projectReferences = ( 395 | { 396 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; 397 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; 398 | }, 399 | { 400 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */; 401 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */; 402 | }, 403 | { 404 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */; 405 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */; 406 | }, 407 | { 408 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */; 409 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */; 410 | }, 411 | { 412 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; 413 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; 414 | }, 415 | { 416 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; 417 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; 418 | }, 419 | { 420 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; 421 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; 422 | }, 423 | { 424 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */; 425 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */; 426 | }, 427 | { 428 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */; 429 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */; 430 | }, 431 | { 432 | ProductGroup = 146834001AC3E56700842450 /* Products */; 433 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */; 434 | }, 435 | ); 436 | projectRoot = ""; 437 | targets = ( 438 | 13B07F861A680F5B00A75B9A /* example */, 439 | 00E356ED1AD99517003FC87E /* exampleTests */, 440 | ); 441 | }; 442 | /* End PBXProject section */ 443 | 444 | /* Begin PBXReferenceProxy section */ 445 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = { 446 | isa = PBXReferenceProxy; 447 | fileType = archive.ar; 448 | path = libRCTActionSheet.a; 449 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */; 450 | sourceTree = BUILT_PRODUCTS_DIR; 451 | }; 452 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = { 453 | isa = PBXReferenceProxy; 454 | fileType = archive.ar; 455 | path = libRCTGeolocation.a; 456 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */; 457 | sourceTree = BUILT_PRODUCTS_DIR; 458 | }; 459 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = { 460 | isa = PBXReferenceProxy; 461 | fileType = archive.ar; 462 | path = libRCTImage.a; 463 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */; 464 | sourceTree = BUILT_PRODUCTS_DIR; 465 | }; 466 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = { 467 | isa = PBXReferenceProxy; 468 | fileType = archive.ar; 469 | path = libRCTNetwork.a; 470 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */; 471 | sourceTree = BUILT_PRODUCTS_DIR; 472 | }; 473 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = { 474 | isa = PBXReferenceProxy; 475 | fileType = archive.ar; 476 | path = libRCTVibration.a; 477 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; 478 | sourceTree = BUILT_PRODUCTS_DIR; 479 | }; 480 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { 481 | isa = PBXReferenceProxy; 482 | fileType = archive.ar; 483 | path = libRCTSettings.a; 484 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; 485 | sourceTree = BUILT_PRODUCTS_DIR; 486 | }; 487 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = { 488 | isa = PBXReferenceProxy; 489 | fileType = archive.ar; 490 | path = libRCTWebSocket.a; 491 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */; 492 | sourceTree = BUILT_PRODUCTS_DIR; 493 | }; 494 | 146834041AC3E56700842450 /* libReact.a */ = { 495 | isa = PBXReferenceProxy; 496 | fileType = archive.ar; 497 | path = libReact.a; 498 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */; 499 | sourceTree = BUILT_PRODUCTS_DIR; 500 | }; 501 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = { 502 | isa = PBXReferenceProxy; 503 | fileType = archive.ar; 504 | path = libRCTLinking.a; 505 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; 506 | sourceTree = BUILT_PRODUCTS_DIR; 507 | }; 508 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { 509 | isa = PBXReferenceProxy; 510 | fileType = archive.ar; 511 | path = libRCTText.a; 512 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */; 513 | sourceTree = BUILT_PRODUCTS_DIR; 514 | }; 515 | /* End PBXReferenceProxy section */ 516 | 517 | /* Begin PBXResourcesBuildPhase section */ 518 | 00E356EC1AD99517003FC87E /* Resources */ = { 519 | isa = PBXResourcesBuildPhase; 520 | buildActionMask = 2147483647; 521 | files = ( 522 | ); 523 | runOnlyForDeploymentPostprocessing = 0; 524 | }; 525 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 526 | isa = PBXResourcesBuildPhase; 527 | buildActionMask = 2147483647; 528 | files = ( 529 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 530 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, 531 | ); 532 | runOnlyForDeploymentPostprocessing = 0; 533 | }; 534 | /* End PBXResourcesBuildPhase section */ 535 | 536 | /* Begin PBXShellScriptBuildPhase section */ 537 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 538 | isa = PBXShellScriptBuildPhase; 539 | buildActionMask = 2147483647; 540 | files = ( 541 | ); 542 | inputPaths = ( 543 | ); 544 | name = "Bundle React Native code and images"; 545 | outputPaths = ( 546 | ); 547 | runOnlyForDeploymentPostprocessing = 0; 548 | shellPath = /bin/sh; 549 | shellScript = "export NODE_BINARY=node\n../node_modules/react-native/packager/react-native-xcode.sh"; 550 | showEnvVarsInLog = 1; 551 | }; 552 | /* End PBXShellScriptBuildPhase section */ 553 | 554 | /* Begin PBXSourcesBuildPhase section */ 555 | 00E356EA1AD99517003FC87E /* Sources */ = { 556 | isa = PBXSourcesBuildPhase; 557 | buildActionMask = 2147483647; 558 | files = ( 559 | 00E356F31AD99517003FC87E /* exampleTests.m in Sources */, 560 | ); 561 | runOnlyForDeploymentPostprocessing = 0; 562 | }; 563 | 13B07F871A680F5B00A75B9A /* Sources */ = { 564 | isa = PBXSourcesBuildPhase; 565 | buildActionMask = 2147483647; 566 | files = ( 567 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, 568 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 569 | ); 570 | runOnlyForDeploymentPostprocessing = 0; 571 | }; 572 | /* End PBXSourcesBuildPhase section */ 573 | 574 | /* Begin PBXTargetDependency section */ 575 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 576 | isa = PBXTargetDependency; 577 | target = 13B07F861A680F5B00A75B9A /* example */; 578 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 579 | }; 580 | /* End PBXTargetDependency section */ 581 | 582 | /* Begin PBXVariantGroup section */ 583 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { 584 | isa = PBXVariantGroup; 585 | children = ( 586 | 13B07FB21A68108700A75B9A /* Base */, 587 | ); 588 | name = LaunchScreen.xib; 589 | path = example; 590 | sourceTree = ""; 591 | }; 592 | /* End PBXVariantGroup section */ 593 | 594 | /* Begin XCBuildConfiguration section */ 595 | 00E356F61AD99517003FC87E /* Debug */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | BUNDLE_LOADER = "$(TEST_HOST)"; 599 | GCC_PREPROCESSOR_DEFINITIONS = ( 600 | "DEBUG=1", 601 | "$(inherited)", 602 | ); 603 | INFOPLIST_FILE = exampleTests/Info.plist; 604 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 605 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 606 | PRODUCT_NAME = "$(TARGET_NAME)"; 607 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/example"; 608 | LIBRARY_SEARCH_PATHS = ( 609 | "$(inherited)", 610 | "\"$(SRCROOT)/$(TARGET_NAME)\"", 611 | ); 612 | }; 613 | name = Debug; 614 | }; 615 | 00E356F71AD99517003FC87E /* Release */ = { 616 | isa = XCBuildConfiguration; 617 | buildSettings = { 618 | BUNDLE_LOADER = "$(TEST_HOST)"; 619 | COPY_PHASE_STRIP = NO; 620 | INFOPLIST_FILE = exampleTests/Info.plist; 621 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 622 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 623 | PRODUCT_NAME = "$(TARGET_NAME)"; 624 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/example.app/example"; 625 | LIBRARY_SEARCH_PATHS = ( 626 | "$(inherited)", 627 | "\"$(SRCROOT)/$(TARGET_NAME)\"", 628 | ); 629 | }; 630 | name = Release; 631 | }; 632 | 13B07F941A680F5B00A75B9A /* Debug */ = { 633 | isa = XCBuildConfiguration; 634 | buildSettings = { 635 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 636 | DEAD_CODE_STRIPPING = NO; 637 | HEADER_SEARCH_PATHS = ( 638 | "$(inherited)", 639 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 640 | "$(SRCROOT)/../node_modules/react-native/React/**", 641 | "$(SRCROOT)/../node_modules/realm/src/**", 642 | ); 643 | INFOPLIST_FILE = "example/Info.plist"; 644 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 645 | OTHER_LDFLAGS = ( 646 | "-ObjC", 647 | "-lc++", 648 | ); 649 | PRODUCT_NAME = example; 650 | }; 651 | name = Debug; 652 | }; 653 | 13B07F951A680F5B00A75B9A /* Release */ = { 654 | isa = XCBuildConfiguration; 655 | buildSettings = { 656 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 657 | HEADER_SEARCH_PATHS = ( 658 | "$(inherited)", 659 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 660 | "$(SRCROOT)/../node_modules/react-native/React/**", 661 | "$(SRCROOT)/../node_modules/realm/src/**", 662 | ); 663 | INFOPLIST_FILE = "example/Info.plist"; 664 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 665 | OTHER_LDFLAGS = ( 666 | "-ObjC", 667 | "-lc++", 668 | ); 669 | PRODUCT_NAME = example; 670 | }; 671 | name = Release; 672 | }; 673 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 674 | isa = XCBuildConfiguration; 675 | buildSettings = { 676 | ALWAYS_SEARCH_USER_PATHS = NO; 677 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 678 | CLANG_CXX_LIBRARY = "libc++"; 679 | CLANG_ENABLE_MODULES = YES; 680 | CLANG_ENABLE_OBJC_ARC = YES; 681 | CLANG_WARN_BOOL_CONVERSION = YES; 682 | CLANG_WARN_CONSTANT_CONVERSION = YES; 683 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 684 | CLANG_WARN_EMPTY_BODY = YES; 685 | CLANG_WARN_ENUM_CONVERSION = YES; 686 | CLANG_WARN_INT_CONVERSION = YES; 687 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 688 | CLANG_WARN_UNREACHABLE_CODE = YES; 689 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 690 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 691 | COPY_PHASE_STRIP = NO; 692 | ENABLE_STRICT_OBJC_MSGSEND = YES; 693 | GCC_C_LANGUAGE_STANDARD = gnu99; 694 | GCC_DYNAMIC_NO_PIC = NO; 695 | GCC_OPTIMIZATION_LEVEL = 0; 696 | GCC_PREPROCESSOR_DEFINITIONS = ( 697 | "DEBUG=1", 698 | "$(inherited)", 699 | ); 700 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 701 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 702 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 703 | GCC_WARN_UNDECLARED_SELECTOR = YES; 704 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 705 | GCC_WARN_UNUSED_FUNCTION = YES; 706 | GCC_WARN_UNUSED_VARIABLE = YES; 707 | HEADER_SEARCH_PATHS = ( 708 | "$(inherited)", 709 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 710 | "$(SRCROOT)/../node_modules/react-native/React/**", 711 | "$(SRCROOT)/../node_modules/realm/src/**", 712 | ); 713 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 714 | MTL_ENABLE_DEBUG_INFO = YES; 715 | ONLY_ACTIVE_ARCH = YES; 716 | SDKROOT = iphoneos; 717 | }; 718 | name = Debug; 719 | }; 720 | 83CBBA211A601CBA00E9B192 /* Release */ = { 721 | isa = XCBuildConfiguration; 722 | buildSettings = { 723 | ALWAYS_SEARCH_USER_PATHS = NO; 724 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 725 | CLANG_CXX_LIBRARY = "libc++"; 726 | CLANG_ENABLE_MODULES = YES; 727 | CLANG_ENABLE_OBJC_ARC = YES; 728 | CLANG_WARN_BOOL_CONVERSION = YES; 729 | CLANG_WARN_CONSTANT_CONVERSION = YES; 730 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 731 | CLANG_WARN_EMPTY_BODY = YES; 732 | CLANG_WARN_ENUM_CONVERSION = YES; 733 | CLANG_WARN_INT_CONVERSION = YES; 734 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 735 | CLANG_WARN_UNREACHABLE_CODE = YES; 736 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 737 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 738 | COPY_PHASE_STRIP = YES; 739 | ENABLE_NS_ASSERTIONS = NO; 740 | ENABLE_STRICT_OBJC_MSGSEND = YES; 741 | GCC_C_LANGUAGE_STANDARD = gnu99; 742 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 743 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 744 | GCC_WARN_UNDECLARED_SELECTOR = YES; 745 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 746 | GCC_WARN_UNUSED_FUNCTION = YES; 747 | GCC_WARN_UNUSED_VARIABLE = YES; 748 | HEADER_SEARCH_PATHS = ( 749 | "$(inherited)", 750 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 751 | "$(SRCROOT)/../node_modules/react-native/React/**", 752 | "$(SRCROOT)/../node_modules/realm/src/**", 753 | ); 754 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 755 | MTL_ENABLE_DEBUG_INFO = NO; 756 | SDKROOT = iphoneos; 757 | VALIDATE_PRODUCT = YES; 758 | }; 759 | name = Release; 760 | }; 761 | /* End XCBuildConfiguration section */ 762 | 763 | /* Begin XCConfigurationList section */ 764 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "exampleTests" */ = { 765 | isa = XCConfigurationList; 766 | buildConfigurations = ( 767 | 00E356F61AD99517003FC87E /* Debug */, 768 | 00E356F71AD99517003FC87E /* Release */, 769 | ); 770 | defaultConfigurationIsVisible = 0; 771 | defaultConfigurationName = Release; 772 | }; 773 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "example" */ = { 774 | isa = XCConfigurationList; 775 | buildConfigurations = ( 776 | 13B07F941A680F5B00A75B9A /* Debug */, 777 | 13B07F951A680F5B00A75B9A /* Release */, 778 | ); 779 | defaultConfigurationIsVisible = 0; 780 | defaultConfigurationName = Release; 781 | }; 782 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "example" */ = { 783 | isa = XCConfigurationList; 784 | buildConfigurations = ( 785 | 83CBBA201A601CBA00E9B192 /* Debug */, 786 | 83CBBA211A601CBA00E9B192 /* Release */, 787 | ); 788 | defaultConfigurationIsVisible = 0; 789 | defaultConfigurationName = Release; 790 | }; 791 | /* End XCConfigurationList section */ 792 | }; 793 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 794 | } 795 | -------------------------------------------------------------------------------- /example/ios/example.xcodeproj/xcshareddata/xcschemes/example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 77 | 83 | 84 | 85 | 86 | 87 | 88 | 94 | 96 | 102 | 103 | 104 | 105 | 107 | 108 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /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 "RCTRootView.h" 13 | 14 | @implementation AppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | NSURL *jsCodeLocation; 19 | 20 | /** 21 | * Loading JavaScript code - uncomment the one you want. 22 | * 23 | * OPTION 1 24 | * Load from development server. Start the server from the repository root: 25 | * 26 | * $ npm start 27 | * 28 | * To run on device, change `localhost` to the IP address of your computer 29 | * (you can get this by typing `ifconfig` into the terminal and selecting the 30 | * `inet` value under `en0:`) and make sure your computer and iOS device are 31 | * on the same Wi-Fi network. 32 | */ 33 | 34 | jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"]; 35 | 36 | /** 37 | * OPTION 2 38 | * Load from pre-bundled file on disk. The static bundle is automatically 39 | * generated by the "Bundle React Native code and images" build step when 40 | * running the project on an actual device or running the project on the 41 | * simulator in the "Release" build configuration. 42 | */ 43 | 44 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 45 | 46 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 47 | moduleName:@"example" 48 | initialProperties:nil 49 | launchOptions:launchOptions]; 50 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 51 | 52 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 53 | UIViewController *rootViewController = [UIViewController new]; 54 | rootViewController.view = rootView; 55 | self.window.rootViewController = rootViewController; 56 | [self.window makeKeyAndVisible]; 57 | return YES; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /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 | 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 | NSAllowsArbitraryLoads 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /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 "RCTLog.h" 14 | #import "RCTRootView.h" 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 = [[[[UIApplication sharedApplication] 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.1.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start" 7 | }, 8 | "dependencies": { 9 | "react": ">5.1.0", 10 | "react-native": ">0.27.2", 11 | "react-native-backbone": "0.1.1" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-backbone", 3 | "version": "0.1.1", 4 | "description": "A React Native RESTful API kit that use the fetch method", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+ssh://git@github.com/peter4k/react-native-backbone.git" 12 | }, 13 | "keywords": [ 14 | "backbone", 15 | "react-native", 16 | "http", 17 | "rest" 18 | ], 19 | "author": "Yi Wang ", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/peter4k/react-native-backbone/issues" 23 | }, 24 | "homepage": "https://github.com/peter4k/react-native-backbone#readme", 25 | "dependencies" : { 26 | "backbone": ">=1.3.3", 27 | "realm": ">0.13.2", 28 | "shortid": ">2.2.6", 29 | "underscore": ">1.8.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Backbone from 'backbone'; 2 | import fetchStorage from './storages/fetch'; 3 | 4 | //Set the default storage to be Fetch 5 | var RNBackbone = { 6 | storage: fetchStorage 7 | }; 8 | 9 | //Override sync methods for Model and Collections 10 | 11 | RNBackbone.Model = Backbone.Model.extend({ 12 | addDelegate(delegate){ 13 | this.on('change', function () { 14 | delegate.forceUpdate(); 15 | }) 16 | }, 17 | sync: function () { 18 | return RNBackbone.sync.apply(this, arguments); 19 | } 20 | }); 21 | 22 | RNBackbone.Collection = Backbone.Collection.extend({ 23 | addDelegate(delegate){ 24 | this.on('change', function () { 25 | delegate.forceUpdate(); 26 | }) 27 | }, 28 | sync: function () { 29 | return RNBackbone.sync.apply(this, arguments); 30 | } 31 | }); 32 | 33 | RNBackbone.sync = function () { 34 | if (!RNBackbone.storage) { 35 | throw 'A storage must be specified before using RNBackbone models or collections'; 36 | } 37 | //Using the sync method provided by RNBackbone 38 | return RNBackbone.storage.sync.apply(this, arguments); 39 | }; 40 | 41 | export default RNBackbone; -------------------------------------------------------------------------------- /src/storages/fetch.js: -------------------------------------------------------------------------------- 1 | import _ from 'underscore'; 2 | 3 | var fetchStorage = {}; 4 | 5 | fetchStorage.globalOptions = {}; 6 | 7 | var methodMap = { 8 | 'create': 'POST', 9 | 'update': 'PUT', 10 | 'patch': 'PATCH', 11 | 'delete': 'DELETE', 12 | 'read': 'GET' 13 | }; 14 | 15 | fetchStorage.sync = function (method, model, options) { 16 | 17 | var type = methodMap[method]; 18 | 19 | if (typeof options === 'function') { 20 | callback = options; 21 | options = null; 22 | } 23 | options = options || {}; 24 | 25 | var request = { 26 | method: type, 27 | headers: { 28 | 'Accept': 'application/json', 29 | 'Content-Type': 'application/json' 30 | } 31 | }; 32 | 33 | if (type != 'GET' && type != 'HEAD') { 34 | request['body'] = JSON.stringify(options.attrs || model.toJSON(options)); 35 | } 36 | 37 | if (fetchStorage.globalOptions.headers) { 38 | for (header in fetchStorage.globalOptions.headers) { 39 | request.headers[header] = fetchStorage.globalOptions.headers[header]; 40 | } 41 | } 42 | 43 | if (options.headers) { 44 | for (header in options.headers) { 45 | request.headers[header] = options.headers[header]; 46 | } 47 | } 48 | 49 | var url; 50 | 51 | if (!options.url) { 52 | url = _.result(model, 'url') || urlError(); 53 | } 54 | 55 | if (fetchStorage.globalOptions.baseUrl) { 56 | var base = fetchStorage.globalOptions.baseUrl; 57 | if (base[base.length - 1] === "/") { 58 | base = base.slice(0, -1); 59 | } 60 | url = base + url; 61 | } 62 | 63 | if (options.data) { 64 | var params = []; 65 | for (key in options.data) { 66 | params.push(key + '=' + encodeURIComponent(options.data[key])); 67 | } 68 | if (params.length) { 69 | url = url + '?' + params.join('&'); 70 | } 71 | } 72 | 73 | model.trigger('request', model, request, options); 74 | 75 | fetchStorage.send(url, request, function (error, json) { 76 | if (error) { 77 | options.error(error); 78 | } else { 79 | options.success(json); 80 | } 81 | }) 82 | }; 83 | 84 | fetchStorage.send = async function (url, req, callback) { 85 | if (callback) { 86 | _send(url, req, callback); 87 | } else { 88 | try { 89 | await _sendAsync(url, req); 90 | } catch (e) { 91 | throw e; 92 | } 93 | } 94 | }; 95 | 96 | const _send = async function (url, req, callback) { 97 | var error, json; 98 | try { 99 | json = await _sendAsync(url, req); 100 | } catch (_error) { 101 | error = _error; 102 | } 103 | callback(error, json); 104 | }; 105 | 106 | const _sendAsync = async function (url, req) { 107 | try { 108 | var response = await fetch(url, req); 109 | if((response.status >= 200 && response.status <= 208) || (response.status === 226)) { 110 | var responseText = await response.text(); 111 | try { 112 | return JSON.parse(responseText); 113 | } catch (e) { 114 | return responseText; 115 | } 116 | } else { 117 | var error; 118 | try { 119 | var errorText = await response.text(); 120 | var errorJSON = JSON.parse(errorText); 121 | error = errorJSON["error-message"] || errorText; 122 | } catch (e) { 123 | error = errorText || ""; 124 | } 125 | throw { 126 | error: new Error(error), 127 | status: response.status, 128 | code: 104 129 | } 130 | } 131 | } catch (e) { 132 | throw e; 133 | } 134 | }; 135 | 136 | var urlError = function () { 137 | throw new Error('A "url" property or function must be specified'); 138 | }; 139 | 140 | export default fetchStorage; 141 | -------------------------------------------------------------------------------- /src/storages/realm.js: -------------------------------------------------------------------------------- 1 | import _Realm from 'realm'; 2 | import _ from 'underscore'; 3 | import Backbone from 'backbone'; 4 | import ShortId from 'shortid'; 5 | 6 | var realm = { 7 | type: 'realm', 8 | 9 | /** 10 | * Initialize a realm instance for the use of RNBackbone 11 | */ 12 | init: function (options) { 13 | var schemas = []; 14 | _.each(options.models, (model, key) => { 15 | 16 | var schema = model.prototype.realmSchema; 17 | if (!schema) { 18 | throw '"realmSchema" must be specified for every model when using Realm as storage'; 19 | } 20 | 21 | //realm does not auto-generate primaryKey, add the idAttribute as primaryKey to the realm schema 22 | var primaryKey = schema.primaryKey = schema.primaryKey || this.idAttribute || 'id'; 23 | schema.properties[primaryKey] = 'string'; 24 | 25 | var _schema = JSON.parse(JSON.stringify(schema)); 26 | _.each(_schema.properties, (value, key) => { 27 | if (value == 'object') _schema.properties[key] = 'string'; 28 | else if (value.type == 'object') value.type = 'string'; 29 | }); 30 | schemas.push(_schema); 31 | }); 32 | options.schema = schemas; 33 | realm._realm = new _Realm(options); 34 | }, 35 | 36 | sync: function (method, model, options) { 37 | if (model instanceof Backbone.Collection) { 38 | realm.syncCollection(method, model, options); 39 | } else { 40 | realm.syncModel(method, model, options); 41 | } 42 | }, 43 | 44 | syncModel: function (method, model, options) { 45 | 46 | var schema = model.realmSchema, 47 | primaryKeyAttr = schema.primaryKey, 48 | name = schema.name; 49 | 50 | var methodMap = { 51 | 'create': function () { 52 | 53 | //For realm models, generate a shortid as primary key; 54 | if (!model.get(primaryKeyAttr)) { 55 | model.set(primaryKeyAttr, ShortId.generate()); 56 | } 57 | 58 | var json = model.toJSON(); 59 | //Save the models 60 | realm._realm.write(() => { 61 | realm._realm.create(name, realm.parseBackboneModel(json, model)); 62 | }); 63 | 64 | options.success(json); 65 | }, 66 | 'read': function () { 67 | 68 | //For realm models, generate a shortid as primary key; 69 | if (!model.get(schema.primaryKey)) { 70 | throw 'Cannot fetch a model with out primaryKey'; 71 | } 72 | 73 | var realmObj = realm.findModelObjects(model); 74 | if (!realmObj) { 75 | return options.error({realmError: 'not_found', realmErrorMessage: 'Object not found'}); 76 | } 77 | 78 | model.realmObject = realmObj; 79 | options.success(realmObj); 80 | }, 81 | 'update': function () { 82 | 83 | var json = model.toJSON(); 84 | //Save the models 85 | realm._realm.write(() => { 86 | realm._realm.create(name, realm.parseBackboneModel(json, model), true); 87 | }); 88 | 89 | options.success(json); 90 | }, 91 | 'delete': function () { 92 | //first find the Realm object 93 | var realmObj = realm.findModelObjects(model, {noParse: true}); 94 | if (!realmObj) { 95 | return options.error({realmError: 'Cannot find object'}); 96 | } 97 | realm._realm.write(() => { 98 | realm._realm.delete(realmObj); 99 | }); 100 | options.success(); 101 | } 102 | }; 103 | 104 | if (!_.contains(_.keys(methodMap), method)) { 105 | throw 'Method ' + method + ' is not supported for models while using Realm'; 106 | } 107 | methodMap[method](model, options); 108 | }, 109 | syncCollection: function (method, collection, options) { 110 | options = options || {} 111 | var Model = collection.model, 112 | name = Model.prototype.realmSchema.name; 113 | 114 | if (!name) { 115 | throw 'Model of collection does not have realmSchema.name'; 116 | } 117 | 118 | var methodMap = { 119 | 'read': function () { 120 | var realmObjects = realm.findObjects(name, options, Model.prototype.realmSchema); 121 | options.success(_.toArray(realmObjects)); 122 | } 123 | }; 124 | 125 | if (!_.contains(_.keys(methodMap), method)) { 126 | throw 'Method ' + method + ' is not supported for collections while using Realm'; 127 | } 128 | 129 | methodMap[method](collection, options); 130 | }, 131 | findModelObjects: function (models, options) { 132 | options = options || {}; 133 | if (models instanceof Backbone.Collection) { 134 | //TODO: find for collections, this will be required if we want to implement Sync of local and API 135 | } else { 136 | var schema = models.realmSchema, 137 | primaryKeyAttr = schema.primaryKey, 138 | name = schema.name; 139 | 140 | options.filters = [primaryKeyAttr + ' = "' + models.get(primaryKeyAttr) + '"']; 141 | options.limit = 1; 142 | return realm.findObjects(name, options, schema)[0]; 143 | } 144 | }, 145 | findObjects: function (name, options, schema) { 146 | 147 | var filters = options.filters, timeFilter = options.timeFilter, sort = options.sort; 148 | var allRealmObj = realm._realm.objects(name); 149 | 150 | //If no filter, return all 151 | if (filters && filters.length > 0) { 152 | 153 | //generate filter query 154 | let query = filters.join(' AND '); 155 | 156 | allRealmObj = allRealmObj.filtered(query); 157 | } 158 | 159 | if (timeFilter) { 160 | _.each(timeFilter, function (tfilter) { 161 | allRealmObj = allRealmObj.filtered(tfilter.query, tfilter.date); 162 | }) 163 | } 164 | 165 | if (sort) { 166 | allRealmObj = allRealmObj.sorted(sort, options.sortDescending == true); 167 | } 168 | 169 | if(options.noParse) return allRealmObj; 170 | return this.parseRealmObject(allRealmObj, schema, options); 171 | }, 172 | 173 | /** 174 | * Parse all "object" type to a stringify JSON in order to store it in Realm 175 | * @param model the backbone model to be parsed 176 | * @returns {object} the object to be saved 177 | */ 178 | parseBackboneModel: function (_json, model) { 179 | var json = _.clone(_json); 180 | var schema = model.realmSchema.properties; 181 | _.each(json, function (value, key) { 182 | if(!schema[key]){ 183 | throw "Missing property definition for " + key + " in the Realm schema of object " + model.realmSchema.name 184 | } 185 | if (schema[key] == 'object' || schema[key].type == 'object') { 186 | json[key] = JSON.stringify(value); 187 | } 188 | }); 189 | return json; 190 | }, 191 | 192 | /** 193 | * Realm object cannot be modified outside of "write" block, we create a copy of realm object for backbone to use 194 | * Parse all "object" from stringify JSON to object 195 | * @param realmObj 196 | * @param schema 197 | * @returns {Array} 198 | */ 199 | parseRealmObject: function (realmObj, schema, options) { 200 | options = options || {}; 201 | var resultArray = []; 202 | var start = options.skip || 0; 203 | var max = realmObj.length; 204 | if (options.limit) { 205 | max = start + options.limit; 206 | if (max > realmObj.length) max = realmObj.length; 207 | } 208 | for (let i = start; i < max; i++) { 209 | var resultObj = _.clone(realmObj[i]); 210 | _.each(resultObj, function (value, key) { 211 | if (schema.properties[key] == 'object' || schema.properties[key].type == 'object') { 212 | resultObj[key] = value ? JSON.parse(value) : undefined; 213 | } 214 | }); 215 | resultArray.push(resultObj); 216 | } 217 | return resultArray; 218 | } 219 | }; 220 | 221 | export default realm; 222 | --------------------------------------------------------------------------------