├── .gitignore
├── LICENSE.md
├── README.md
├── android
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ └── java
│ └── com
│ └── burlap
│ └── filetransfer
│ ├── FileTransferModule.java
│ └── FileTransferPackage.java
├── examples
└── UploadFromCameraRoll
│ ├── .flowconfig
│ ├── .gitignore
│ ├── .watchmanconfig
│ ├── index.ios.js
│ ├── ios
│ ├── UploadFromCameraRoll.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── UploadFromCameraRoll.xcscheme
│ ├── UploadFromCameraRoll
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.m
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── Images.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── main.m
│ └── UploadFromCameraRollTests
│ │ ├── Info.plist
│ │ └── UploadFromCameraRollTests.m
│ ├── package.json
│ └── uploader.gif
├── index.android.js
├── index.ios.js
├── ios
├── RNUploader.m
└── RNUploader.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ └── contents.xcworkspacedata
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata
19 |
20 | ## Other
21 | *.xccheckout
22 | *.moved-aside
23 | *.xcuserstate
24 | *.vscode
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Adam Roth
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-native-uploader
2 | A React Native module for uploading files and camera roll assets. Supports progress notification.
3 |
4 | # Do you absolutely need this?
5 | You can use file upload with `fetch` and if you want progress bar, you can use xhr. Read my post [How to upload photo/file in react-native](https://github.com/g6ling/React-Native-Tips/tree/master/How_to_upload_photo%2Cfile_in%20react-native). Even after read my post, but you are not enough, read the following.
6 |
7 | ## Install
8 | ### Use rnpm
9 | 1. `npm install react-native-uploader --save`
10 | 2. `rnpm link react-native-uploader`
11 |
12 |
13 | If you don't want use rnpm, do this
14 | ### iOS
15 | 1. `npm install react-native-uploader --save`
16 | 2. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`
17 | 3. Go to `node_modules` ➜ `react-native-uploader` ➜ `RNUploader` and add `RNUploader.xcodeproj`
18 | 4. In XCode, in the project navigator, select your project. Add `libRNUploader.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`
19 | 5. Run your project (`Cmd+R`)
20 |
21 | ### Android
22 | 1. Add to your settings.gradle:
23 | ```
24 | include ':RNFileTransfer', ':app'
25 | project(':RNFileTransfer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-file-transfer-android/android')
26 | ```
27 |
28 | 2. Add to your android/build.gradle:
29 | ```
30 | dependencies {
31 | ...
32 | compile project(':RNFileTransfer')
33 | }
34 | ```
35 |
36 | 3. Add to MainActivity.java
37 | ```
38 | import com.burlap.filetransfer.FileTransferPackage;
39 | ...
40 | mReactInstanceManager = ReactInstanceManager.builder()
41 | .setApplication(getApplication())
42 | .setBundleAssetName("index.android.bundle")
43 | .setJSMainModuleName("index.android")
44 | .addPackage(new MainReactPackage())
45 | .addPackage(new FileTransferPackage())
46 | ```
47 |
48 | ## Example
49 | See ./examples/UploadFromCameraRoll
50 |
51 | 
52 |
53 |
54 | ## Usage
55 | ```javascript
56 | var RNUploader = require('react-native-uploader');
57 |
58 | var {
59 | StyleSheet,
60 | Component,
61 | View,
62 | DeviceEventEmitter,
63 | } = React;
64 | ```
65 |
66 | ```javascript
67 | componentDidMount(){
68 | // upload progress
69 | DeviceEventEmitter.addListener('RNUploaderProgress', (data)=>{
70 | let bytesWritten = data.totalBytesWritten;
71 | let bytesTotal = data.totalBytesExpectedToWrite;
72 | let progress = data.progress;
73 |
74 | console.log( "upload progress: " + progress + "%");
75 | });
76 | }
77 | ```
78 |
79 | ```javascript
80 | doUpload(){
81 | let files = [
82 | {
83 | name: 'file[]',
84 | filename: 'image1.png',
85 | filepath: 'assets-library://....', // image from camera roll/assets library
86 | filetype: 'image/png',
87 | },
88 | {
89 | name: 'file[]',
90 | filename: 'image2.gif',
91 | filepath: "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7", // base64 only support ios
92 | filetype: 'image/gif',
93 | },
94 | ];
95 |
96 | let opts = {
97 | url: 'http://my.server/api/upload',
98 | files: files,
99 | method: 'POST', // optional: POST or PUT, only support ios, android always have POST
100 | headers: { 'Accept': 'application/json' }, // optional, only support ios, android always have { 'Accept': 'application/json' }
101 | params: { 'user_id': 1 }, // optional, Android support this only string. If you want this in Android use params: { 'user_id': '1' }
102 | };
103 |
104 | RNUploader.upload( opts, (err, response) => {
105 | if( err ){
106 | console.log(err);
107 | return;
108 | }
109 |
110 | let status = response.status;
111 | let responseString = response.data;
112 | let json = JSON.parse( responseString );
113 |
114 | console.log('upload complete with status ' + status);
115 |
116 | // android's response is response.body.string.
117 | });
118 | }
119 |
120 | ```
121 |
122 | ## API
123 | #### RNUploader.upload( options, callback )
124 |
125 | `options` is an object with values:
126 |
127 | ||type|required|description|example|
128 | |---|---|---|---|---|
129 | |`url`|string|required|URL to upload to|`http://my.server/api/upload`|
130 | |`method(only iOS)`|string|optional|HTTP method, values: [PUT,POST], default: POST|`POST`|
131 | |`headers(only iOS)`|object|optional|HTTP headers|`{ 'Accept': 'application/json' }`|
132 | |`params(iOS)`|object|optional|Query parameters|`{ 'user_id': 1 }`|
133 | |`params(Android)`|object|optional|Query parameters|`{ 'user_id': '1' }`
only support string value. You can't use int, boolean, etc..|
134 | |`files`|array|required|Array of file objects to upload. See below.| `[{ name: 'file', filename: 'image1.png', filepath: 'assets-library://...', filetype: 'image/png' } ]` |
135 |
136 | `callback` is a method with two parameters:
137 |
138 | ||type|description|example|
139 | |---|---|---|---|
140 | |error|string|String detailing the error|`A server with the specified hostname could not be found.`|
141 | |response(iOS)|object{status:Number, data:String}|Object returned with a status code and data.|`{ status: 200, data: '{ success: true }' }`|
142 | |response(Android)|String|String returned with responseBody.|`success: true`|
143 |
144 |
145 | #### `files`
146 | `files` is an array of objects with values:
147 |
148 | ||type|required|description|example|
149 | |---|---|---|---|---|
150 | |name|string|optional|Form parameter key for the specified file. If missing, will use `filename`.|`file[]`|
151 | |filename|string|required|filename|`image1.png`|
152 | |filepath|string|required|File URI
Supports `assets-library:`, `data:` and `file:` URIs and file paths.|`assets-library://...(iOS)`
`content://...(Android)`
`data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOV...(only iOS)`
`file:/tmp/image1.png`
`/tmp/image1.png`|
153 | |filetype|string|optional|MIME type of file. If missing, will infer based on the extension in `filepath`.|`image/png`|
154 |
155 | ### Progress (only support iOS)
156 | To monitor upload progress simply subscribe to the `RNUploaderProgress` event using DeviceEventEmitter.
157 |
158 | ```
159 | DeviceEventEmitter.addListener('RNUploaderProgress', (data)=>{
160 | let bytesWritten = data.totalBytesWritten;
161 | let bytesTotal = data.totalBytesExpectedToWrite;
162 | let progress = data.progress;
163 |
164 | console.log( "upload progress: " + progress + "%");
165 | });
166 | ```
167 |
168 | ### Cancel (only support iOS)
169 | To cancel an upload in progress:
170 | ```
171 | RNUploader.cancel()
172 | ```
173 |
174 | ### Notes
175 |
176 | Inspired by similiar projects:
177 | * https://github.com/booxood/react-native-file-upload
178 | * https://github.com/kamilkp/react-native-file-transfer
179 |
180 | ...with noteable enhancements:
181 | * uploads are performed asynchronously on the native side
182 | * progress reporting
183 | * packaged as a static library
184 | * support for multiple files at a time
185 | * support for files from the assets library, base64 `data:` or `file:` paths
186 | * no external dependencies (ie: AFNetworking)
187 | * support Android
188 |
189 | ## License
190 |
191 | MIT
192 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | maven { url "https://jitpack.io" }
5 | }
6 |
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:1.1.3'
9 | }
10 | }
11 |
12 | apply plugin: 'com.android.library'
13 |
14 | android {
15 | compileSdkVersion 23
16 | buildToolsVersion "23.0.1"
17 |
18 | defaultConfig {
19 | minSdkVersion 16
20 | targetSdkVersion 23
21 | versionCode 1
22 | versionName "1.0"
23 | }
24 | }
25 |
26 | repositories {
27 | maven { url "https://jitpack.io" }
28 | }
29 |
30 | dependencies {
31 | compile 'com.android.support:appcompat-v7:23.+'
32 | compile 'com.facebook.react:react-native:0.16.+'
33 | compile 'com.squareup.okhttp3:okhttp:3.3.1'
34 | compile 'com.zhy:okhttputils:2.6.2'
35 | compile fileTree(dir: 'libs', include: ['*.jar'])
36 | }
37 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/android/src/main/java/com/burlap/filetransfer/FileTransferModule.java:
--------------------------------------------------------------------------------
1 | package com.burlap.filetransfer;
2 |
3 | import android.app.DownloadManager;
4 | import android.content.Context;
5 | import android.database.Cursor;
6 | import android.provider.MediaStore;
7 | import android.util.Log;
8 | import android.net.Uri;
9 |
10 | import com.facebook.react.bridge.NativeModule;
11 | import com.facebook.react.bridge.ReactApplicationContext;
12 | import com.facebook.react.bridge.ReactContext;
13 | import com.facebook.react.bridge.ReactContextBaseJavaModule;
14 | import com.facebook.react.bridge.ReactMethod;
15 | import com.facebook.react.bridge.Callback;
16 | import com.facebook.react.bridge.ReadableArray;
17 | import com.facebook.react.bridge.ReadableMap;
18 | import com.facebook.react.bridge.ReadableMapKeySetIterator;
19 | import com.facebook.react.bridge.ReadableType;
20 | import com.facebook.react.bridge.WritableMap;
21 | import com.facebook.react.bridge.Arguments;
22 | import com.facebook.react.modules.core.DeviceEventManagerModule;
23 |
24 | import org.json.*;
25 |
26 | import java.util.Map;
27 | import java.io.File;
28 | import java.io.FileInputStream;
29 | import java.io.FileOutputStream;
30 | import java.io.IOException;
31 | import java.io.FileNotFoundException;
32 | import java.util.HashMap;
33 |
34 | import okhttp3.MediaType;
35 | import okhttp3.MultipartBody;
36 | import okhttp3.OkHttpClient;
37 | import okhttp3.Request;
38 | import okhttp3.RequestBody;
39 | import okhttp3.Response;
40 |
41 | import com.zhy.http.okhttp.request.CountingRequestBody;
42 |
43 | public class FileTransferModule extends ReactContextBaseJavaModule {
44 |
45 | private final OkHttpClient client = new OkHttpClient();
46 | private String TAG = "ImageUploadAndroid";
47 | ReactApplicationContext reactContext = null;
48 |
49 | public FileTransferModule(ReactApplicationContext reactContext) {
50 | super(reactContext);
51 | this.reactContext = reactContext;
52 | }
53 |
54 | @Override
55 | public String getName() {
56 | // match up with the IOS name
57 | return "FileTransfer";
58 | }
59 |
60 | @ReactMethod
61 | public void upload(ReadableMap options, Callback complete) {
62 |
63 | final Callback completeCallback = complete;
64 |
65 | try {
66 | MultipartBody.Builder mRequestBody = new MultipartBody.Builder()
67 | .setType(MultipartBody.FORM);
68 |
69 | ReadableArray files = options.getArray("files");
70 | String url = options.getString("url");
71 |
72 | if(options.hasKey("params")){
73 | ReadableMap data = options.getMap("params");
74 | ReadableMapKeySetIterator iterator = data.keySetIterator();
75 |
76 | while(iterator.hasNextKey()){
77 | String key = iterator.nextKey();
78 | if(ReadableType.String.equals(data.getType(key))) {
79 | mRequestBody.addFormDataPart(key, data.getString(key));
80 | }
81 | }
82 | }
83 |
84 |
85 |
86 |
87 | if(files.size() != 0){
88 | for(int fileIndex=0 ; fileIndex createNativeModules(ReactApplicationContext reactContext) {
19 | return Arrays.asList(
20 | new FileTransferModule(reactContext)
21 | );
22 | }
23 |
24 |
25 | @Override
26 | public List> createJSModules() {
27 | return Collections.emptyList();
28 | }
29 |
30 | @Override
31 | public List createViewManagers(ReactApplicationContext reactContext) {
32 | return Arrays.asList();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/.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-haste/.*/__tests__/.*
18 | .*/node_modules/fbjs-haste/__forks__/Map.js
19 | .*/node_modules/fbjs-haste/__forks__/Promise.js
20 | .*/node_modules/fbjs-haste/__forks__/fetch.js
21 | .*/node_modules/fbjs-haste/core/ExecutionEnvironment.js
22 | .*/node_modules/fbjs-haste/core/isEmpty.js
23 | .*/node_modules/fbjs-haste/crypto/crc32.js
24 | .*/node_modules/fbjs-haste/stubs/ErrorUtils.js
25 | .*/node_modules/react-haste/React.js
26 | .*/node_modules/react-haste/renderers/dom/ReactDOM.js
27 | .*/node_modules/react-haste/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
28 |
29 | # Ignore commoner tests
30 | .*/node_modules/commoner/test/.*
31 |
32 | # See https://github.com/facebook/flow/issues/442
33 | .*/react-tools/node_modules/commoner/lib/reader.js
34 |
35 | # Ignore jest
36 | .*/node_modules/jest-cli/.*
37 |
38 | # Ignore Website
39 | .*/website/.*
40 |
41 | [include]
42 |
43 | [libs]
44 | node_modules/react-native/Libraries/react-native/react-native-interface.js
45 |
46 | [options]
47 | module.system=haste
48 |
49 | munge_underscores=true
50 |
51 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
52 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.png$' -> 'RelativeImageStub'
53 |
54 | suppress_type=$FlowIssue
55 | suppress_type=$FlowFixMe
56 | suppress_type=$FixMe
57 |
58 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
59 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)? #[0-9]+
60 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
61 |
62 | [version]
63 | 0.19.0
64 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/.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 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/index.ios.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var React = require('react-native');
4 | var {
5 | AppRegistry,
6 | StyleSheet,
7 | Text,
8 | View,
9 | CameraRoll,
10 | DeviceEventEmitter,
11 | ActivityIndicatorIOS,
12 | Image,
13 | TouchableOpacity,
14 | Modal,
15 | } = React;
16 |
17 |
18 | var RNUploader = require('NativeModules').RNUploader;
19 |
20 | class UploadFromCameraRoll extends React.Component {
21 |
22 | constructor(props){
23 | super(props);
24 |
25 | this.state = {
26 | uploading: false,
27 | showUploadModal: false,
28 | uploadProgress: 0,
29 | uploadTotal: 0,
30 | uploadWritten: 0,
31 | uploadStatus: undefined,
32 | cancelled: false,
33 | images: [],
34 | }
35 | }
36 |
37 | componentDidMount(){
38 | DeviceEventEmitter.addListener('RNUploaderProgress', (data)=>{
39 | let bytesWritten = data.totalBytesWritten;
40 | let bytesTotal = data.totalBytesExpectedToWrite;
41 | let progress = data.progress;
42 | this.setState( { uploadProgress: progress, uploadTotal: bytesTotal, uploadWritten: bytesWritten } );
43 | });
44 | }
45 |
46 | _addImage(){
47 | const fetchParams = {
48 | first: 25,
49 | };
50 |
51 | CameraRoll.getPhotos( fetchParams, (data)=>{
52 | const assets = data.edges;
53 | const index = parseInt( Math.random() * ( assets.length ) );
54 | const randomImage = assets[ index ];
55 |
56 | let images = this.state.images;
57 | images.push( randomImage.node.image );
58 |
59 | this.setState( { images: images } );
60 | },
61 | (err)=>{
62 | console.log(err);
63 | });
64 | }
65 |
66 | _closeUploadModal(){
67 | this.setState( { showUploadModal: false, uploadProgress: 0, uploadTotal: 0, uploadWritten: 0, images: [], cancelled: false, } );
68 | }
69 |
70 | _cancelUpload(){
71 | RNUploader.cancel();
72 | this.setState( { uploading: false, cancelled: true } );
73 | }
74 |
75 | _uploadImages(){
76 | let files = this.state.images.map( (f)=>{
77 | return {
78 | name: 'file',
79 | filename: _generateUUID + '.png',
80 | filepath: f.uri,
81 | filetype: 'image/png',
82 | }
83 | });
84 |
85 | let opts = {
86 | url: 'https://posttestserver.com/post.php',
87 | files: files,
88 | params: { name: 'test-app' }
89 | };
90 |
91 | this.setState({ uploading: true, showUploadModal: true, });
92 | RNUploader.upload( opts, ( err, res )=>{
93 | if( err ){
94 | console.log(err);
95 | return;
96 | }
97 |
98 | let status = res.status;
99 | let responseString = res.data;
100 |
101 | console.log('upload complete with status ' + status);
102 | console.log( responseString );
103 | this.setState( { uploading: false, uploadStatus: status } );
104 | });
105 |
106 | }
107 |
108 | uploadProgressModal(){
109 | let uploadProgress;
110 |
111 | if( this.state.cancelled ){
112 | uploadProgress = (
113 |
114 |
115 | Upload Cancelled
116 |
117 |
118 | Close
119 |
120 |
121 | );
122 | }else if( !this.state.uploading && this.state.uploadStatus ){
123 | uploadProgress = (
124 |
125 |
126 | Upload complete with status: { this.state.uploadStatus }
127 |
128 |
129 | { this.state.uploading ? '' : 'Close' }
130 |
131 |
132 | );
133 | }else if( this.state.uploading ){
134 | uploadProgress = (
135 |
136 | Uploading { this.state.images.length } Image{ this.state.images.length == 1 ? '' : 's' }
137 |
141 | { this.state.uploadProgress.toFixed(0) }%
142 |
143 | { ( this.state.uploadWritten / 1024 ).toFixed(0) }/{ ( this.state.uploadTotal / 1024 ).toFixed(0) } KB
144 |
145 |
146 | { 'Cancel' }
147 |
148 |
149 | );
150 | }
151 |
152 | return uploadProgress;
153 | }
154 |
155 | render() {
156 |
157 | return (
158 |
159 |
160 |
161 | react-native-uploader example
162 |
163 |
164 |
168 |
169 |
170 | { this.uploadProgressModal() }
171 |
172 |
173 |
174 |
175 |
176 |
177 | Add Image
178 |
179 |
180 |
181 | Upload
182 |
183 |
184 |
185 |
186 |
187 | { this.state.images.map( (image)=>{
188 | return
189 | })}
190 |
191 |
192 |
193 | );
194 | }
195 |
196 |
197 | }
198 |
199 | function _generateUUID() {
200 | var d = new Date().getTime();
201 | var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
202 | var r = (d + Math.random()*16)%16 | 0;
203 | d = Math.floor(d/16);
204 | return (c=='x' ? r : (r&0x3|0x8)).toString(16);
205 | });
206 | return uuid;
207 | };
208 |
209 |
210 | var styles = StyleSheet.create({
211 | container: {
212 | flex: 1,
213 | backgroundColor: '#F5FCFF',
214 | padding: 20,
215 | paddingTop: 40,
216 | },
217 | welcome: {
218 | fontSize: 20,
219 | textAlign: 'center',
220 | margin: 10,
221 | },
222 | instructions: {
223 | textAlign: 'center',
224 | color: '#333333',
225 | marginBottom: 5,
226 | },
227 | thumbnail: {
228 | width: 73,
229 | height: 73,
230 | borderWidth: 1,
231 | borderColor: '#DDD',
232 | margin: 5,
233 | },
234 | modal: {
235 | margin: 50,
236 | borderWidth: 1,
237 | borderColor: '#DDD',
238 | padding: 20,
239 | borderRadius: 12,
240 | backgroundColor: 'lightyellow',
241 | justifyContent: 'center',
242 | alignItems: 'center',
243 | },
244 | title: {
245 | textAlign: 'center',
246 | fontWeight: '500',
247 | fontSize: 14,
248 | },
249 | button: {
250 | borderWidth: 1,
251 | borderColor: '#CCC',
252 | borderRadius: 8,
253 | padding: 10,
254 | backgroundColor: '#EEE',
255 | marginHorizontal: 5,
256 | }
257 | });
258 |
259 | AppRegistry.registerComponent('UploadFromCameraRoll', () => UploadFromCameraRoll);
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
11 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
12 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
13 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
14 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
15 | 00E356F31AD99517003FC87E /* UploadFromCameraRollTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* UploadFromCameraRollTests.m */; };
16 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
17 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
18 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
19 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
20 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
21 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
22 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
23 | 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
24 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
25 | E3912FF01C3375F700DE7204 /* libRNUploader.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E3912FEF1C3375ED00DE7204 /* libRNUploader.a */; };
26 | E3EFFF521C285FEB00EDA48D /* libRCTCameraRoll.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E3EFFF511C285FE100EDA48D /* libRCTCameraRoll.a */; };
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 = UploadFromCameraRoll;
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 | E3912FEE1C3375ED00DE7204 /* PBXContainerItemProxy */ = {
108 | isa = PBXContainerItemProxy;
109 | containerPortal = E3912FEA1C3375EC00DE7204 /* RNUploader.xcodeproj */;
110 | proxyType = 2;
111 | remoteGlobalIDString = 134814201AA4EA6300B7C361;
112 | remoteInfo = RNUploader;
113 | };
114 | E3EFFF501C285FE100EDA48D /* PBXContainerItemProxy */ = {
115 | isa = PBXContainerItemProxy;
116 | containerPortal = E3EFFF4C1C285FE100EDA48D /* RCTCameraRoll.xcodeproj */;
117 | proxyType = 2;
118 | remoteGlobalIDString = 58B5115D1A9E6B3D00147676;
119 | remoteInfo = RCTCameraRoll;
120 | };
121 | /* End PBXContainerItemProxy section */
122 |
123 | /* Begin PBXFileReference section */
124 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; };
125 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "../node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; };
126 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "../node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; };
127 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "../node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; };
128 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "../node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; };
129 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "../node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; };
130 | 00E356EE1AD99517003FC87E /* UploadFromCameraRollTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UploadFromCameraRollTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
131 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
132 | 00E356F21AD99517003FC87E /* UploadFromCameraRollTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UploadFromCameraRollTests.m; sourceTree = ""; };
133 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "../node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; };
134 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "../node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; };
135 | 13B07F961A680F5B00A75B9A /* UploadFromCameraRoll.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UploadFromCameraRoll.app; sourceTree = BUILT_PRODUCTS_DIR; };
136 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = UploadFromCameraRoll/AppDelegate.h; sourceTree = ""; };
137 | 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = UploadFromCameraRoll/AppDelegate.m; sourceTree = ""; };
138 | 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
139 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = UploadFromCameraRoll/Images.xcassets; sourceTree = ""; };
140 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = UploadFromCameraRoll/Info.plist; sourceTree = ""; };
141 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = UploadFromCameraRoll/main.m; sourceTree = ""; };
142 | 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "../node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; };
143 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "../node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; };
144 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "../node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; };
145 | E3912FEA1C3375EC00DE7204 /* RNUploader.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RNUploader.xcodeproj; path = "../node_modules/react-native-uploader/RNUploader/RNUploader.xcodeproj"; sourceTree = ""; };
146 | E3EFFF4C1C285FE100EDA48D /* RCTCameraRoll.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTCameraRoll.xcodeproj; path = "../node_modules/react-native/Libraries/CameraRoll/RCTCameraRoll.xcodeproj"; sourceTree = ""; };
147 | /* End PBXFileReference section */
148 |
149 | /* Begin PBXFrameworksBuildPhase section */
150 | 00E356EB1AD99517003FC87E /* Frameworks */ = {
151 | isa = PBXFrameworksBuildPhase;
152 | buildActionMask = 2147483647;
153 | files = (
154 | );
155 | runOnlyForDeploymentPostprocessing = 0;
156 | };
157 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
158 | isa = PBXFrameworksBuildPhase;
159 | buildActionMask = 2147483647;
160 | files = (
161 | E3912FF01C3375F700DE7204 /* libRNUploader.a in Frameworks */,
162 | E3EFFF521C285FEB00EDA48D /* libRCTCameraRoll.a in Frameworks */,
163 | 146834051AC3E58100842450 /* libReact.a in Frameworks */,
164 | 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
165 | 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
166 | 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
167 | 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
168 | 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
169 | 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
170 | 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
171 | 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
172 | 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
173 | );
174 | runOnlyForDeploymentPostprocessing = 0;
175 | };
176 | /* End PBXFrameworksBuildPhase section */
177 |
178 | /* Begin PBXGroup section */
179 | 00C302A81ABCB8CE00DB3ED1 /* Products */ = {
180 | isa = PBXGroup;
181 | children = (
182 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */,
183 | );
184 | name = Products;
185 | sourceTree = "";
186 | };
187 | 00C302B61ABCB90400DB3ED1 /* Products */ = {
188 | isa = PBXGroup;
189 | children = (
190 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */,
191 | );
192 | name = Products;
193 | sourceTree = "";
194 | };
195 | 00C302BC1ABCB91800DB3ED1 /* Products */ = {
196 | isa = PBXGroup;
197 | children = (
198 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */,
199 | );
200 | name = Products;
201 | sourceTree = "";
202 | };
203 | 00C302D41ABCB9D200DB3ED1 /* Products */ = {
204 | isa = PBXGroup;
205 | children = (
206 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */,
207 | );
208 | name = Products;
209 | sourceTree = "";
210 | };
211 | 00C302E01ABCB9EE00DB3ED1 /* Products */ = {
212 | isa = PBXGroup;
213 | children = (
214 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */,
215 | );
216 | name = Products;
217 | sourceTree = "";
218 | };
219 | 00E356EF1AD99517003FC87E /* UploadFromCameraRollTests */ = {
220 | isa = PBXGroup;
221 | children = (
222 | 00E356F21AD99517003FC87E /* UploadFromCameraRollTests.m */,
223 | 00E356F01AD99517003FC87E /* Supporting Files */,
224 | );
225 | path = UploadFromCameraRollTests;
226 | sourceTree = "";
227 | };
228 | 00E356F01AD99517003FC87E /* Supporting Files */ = {
229 | isa = PBXGroup;
230 | children = (
231 | 00E356F11AD99517003FC87E /* Info.plist */,
232 | );
233 | name = "Supporting Files";
234 | sourceTree = "";
235 | };
236 | 139105B71AF99BAD00B5F7CC /* Products */ = {
237 | isa = PBXGroup;
238 | children = (
239 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */,
240 | );
241 | name = Products;
242 | sourceTree = "";
243 | };
244 | 139FDEE71B06529A00C62182 /* Products */ = {
245 | isa = PBXGroup;
246 | children = (
247 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */,
248 | );
249 | name = Products;
250 | sourceTree = "";
251 | };
252 | 13B07FAE1A68108700A75B9A /* UploadFromCameraRoll */ = {
253 | isa = PBXGroup;
254 | children = (
255 | 008F07F21AC5B25A0029DE68 /* main.jsbundle */,
256 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */,
257 | 13B07FB01A68108700A75B9A /* AppDelegate.m */,
258 | 13B07FB51A68108700A75B9A /* Images.xcassets */,
259 | 13B07FB61A68108700A75B9A /* Info.plist */,
260 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
261 | 13B07FB71A68108700A75B9A /* main.m */,
262 | );
263 | name = UploadFromCameraRoll;
264 | sourceTree = "";
265 | };
266 | 146834001AC3E56700842450 /* Products */ = {
267 | isa = PBXGroup;
268 | children = (
269 | 146834041AC3E56700842450 /* libReact.a */,
270 | );
271 | name = Products;
272 | sourceTree = "";
273 | };
274 | 78C398B11ACF4ADC00677621 /* Products */ = {
275 | isa = PBXGroup;
276 | children = (
277 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */,
278 | );
279 | name = Products;
280 | sourceTree = "";
281 | };
282 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
283 | isa = PBXGroup;
284 | children = (
285 | E3912FEA1C3375EC00DE7204 /* RNUploader.xcodeproj */,
286 | E3EFFF4C1C285FE100EDA48D /* RCTCameraRoll.xcodeproj */,
287 | 146833FF1AC3E56700842450 /* React.xcodeproj */,
288 | 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */,
289 | 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */,
290 | 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */,
291 | 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */,
292 | 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */,
293 | 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */,
294 | 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
295 | 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */,
296 | 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */,
297 | );
298 | name = Libraries;
299 | sourceTree = "";
300 | };
301 | 832341B11AAA6A8300B99B32 /* Products */ = {
302 | isa = PBXGroup;
303 | children = (
304 | 832341B51AAA6A8300B99B32 /* libRCTText.a */,
305 | );
306 | name = Products;
307 | sourceTree = "";
308 | };
309 | 83CBB9F61A601CBA00E9B192 = {
310 | isa = PBXGroup;
311 | children = (
312 | 13B07FAE1A68108700A75B9A /* UploadFromCameraRoll */,
313 | 832341AE1AAA6A7D00B99B32 /* Libraries */,
314 | 00E356EF1AD99517003FC87E /* UploadFromCameraRollTests */,
315 | 83CBBA001A601CBA00E9B192 /* Products */,
316 | );
317 | indentWidth = 2;
318 | sourceTree = "";
319 | tabWidth = 2;
320 | };
321 | 83CBBA001A601CBA00E9B192 /* Products */ = {
322 | isa = PBXGroup;
323 | children = (
324 | 13B07F961A680F5B00A75B9A /* UploadFromCameraRoll.app */,
325 | 00E356EE1AD99517003FC87E /* UploadFromCameraRollTests.xctest */,
326 | );
327 | name = Products;
328 | sourceTree = "";
329 | };
330 | E3912FEB1C3375EC00DE7204 /* Products */ = {
331 | isa = PBXGroup;
332 | children = (
333 | E3912FEF1C3375ED00DE7204 /* libRNUploader.a */,
334 | );
335 | name = Products;
336 | sourceTree = "";
337 | };
338 | E3EFFF4D1C285FE100EDA48D /* Products */ = {
339 | isa = PBXGroup;
340 | children = (
341 | E3EFFF511C285FE100EDA48D /* libRCTCameraRoll.a */,
342 | );
343 | name = Products;
344 | sourceTree = "";
345 | };
346 | /* End PBXGroup section */
347 |
348 | /* Begin PBXNativeTarget section */
349 | 00E356ED1AD99517003FC87E /* UploadFromCameraRollTests */ = {
350 | isa = PBXNativeTarget;
351 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "UploadFromCameraRollTests" */;
352 | buildPhases = (
353 | 00E356EA1AD99517003FC87E /* Sources */,
354 | 00E356EB1AD99517003FC87E /* Frameworks */,
355 | 00E356EC1AD99517003FC87E /* Resources */,
356 | );
357 | buildRules = (
358 | );
359 | dependencies = (
360 | 00E356F51AD99517003FC87E /* PBXTargetDependency */,
361 | );
362 | name = UploadFromCameraRollTests;
363 | productName = UploadFromCameraRollTests;
364 | productReference = 00E356EE1AD99517003FC87E /* UploadFromCameraRollTests.xctest */;
365 | productType = "com.apple.product-type.bundle.unit-test";
366 | };
367 | 13B07F861A680F5B00A75B9A /* UploadFromCameraRoll */ = {
368 | isa = PBXNativeTarget;
369 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "UploadFromCameraRoll" */;
370 | buildPhases = (
371 | 13B07F871A680F5B00A75B9A /* Sources */,
372 | 13B07F8C1A680F5B00A75B9A /* Frameworks */,
373 | 13B07F8E1A680F5B00A75B9A /* Resources */,
374 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
375 | );
376 | buildRules = (
377 | );
378 | dependencies = (
379 | );
380 | name = UploadFromCameraRoll;
381 | productName = "Hello World";
382 | productReference = 13B07F961A680F5B00A75B9A /* UploadFromCameraRoll.app */;
383 | productType = "com.apple.product-type.application";
384 | };
385 | /* End PBXNativeTarget section */
386 |
387 | /* Begin PBXProject section */
388 | 83CBB9F71A601CBA00E9B192 /* Project object */ = {
389 | isa = PBXProject;
390 | attributes = {
391 | LastUpgradeCheck = 0610;
392 | ORGANIZATIONNAME = Facebook;
393 | TargetAttributes = {
394 | 00E356ED1AD99517003FC87E = {
395 | CreatedOnToolsVersion = 6.2;
396 | TestTargetID = 13B07F861A680F5B00A75B9A;
397 | };
398 | };
399 | };
400 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "UploadFromCameraRoll" */;
401 | compatibilityVersion = "Xcode 3.2";
402 | developmentRegion = English;
403 | hasScannedForEncodings = 0;
404 | knownRegions = (
405 | en,
406 | Base,
407 | );
408 | mainGroup = 83CBB9F61A601CBA00E9B192;
409 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
410 | projectDirPath = "";
411 | projectReferences = (
412 | {
413 | ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */;
414 | ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */;
415 | },
416 | {
417 | ProductGroup = E3EFFF4D1C285FE100EDA48D /* Products */;
418 | ProjectRef = E3EFFF4C1C285FE100EDA48D /* RCTCameraRoll.xcodeproj */;
419 | },
420 | {
421 | ProductGroup = 00C302B61ABCB90400DB3ED1 /* Products */;
422 | ProjectRef = 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */;
423 | },
424 | {
425 | ProductGroup = 00C302BC1ABCB91800DB3ED1 /* Products */;
426 | ProjectRef = 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */;
427 | },
428 | {
429 | ProductGroup = 78C398B11ACF4ADC00677621 /* Products */;
430 | ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
431 | },
432 | {
433 | ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;
434 | ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
435 | },
436 | {
437 | ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */;
438 | ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */;
439 | },
440 | {
441 | ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
442 | ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
443 | },
444 | {
445 | ProductGroup = 00C302E01ABCB9EE00DB3ED1 /* Products */;
446 | ProjectRef = 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */;
447 | },
448 | {
449 | ProductGroup = 139FDEE71B06529A00C62182 /* Products */;
450 | ProjectRef = 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */;
451 | },
452 | {
453 | ProductGroup = 146834001AC3E56700842450 /* Products */;
454 | ProjectRef = 146833FF1AC3E56700842450 /* React.xcodeproj */;
455 | },
456 | {
457 | ProductGroup = E3912FEB1C3375EC00DE7204 /* Products */;
458 | ProjectRef = E3912FEA1C3375EC00DE7204 /* RNUploader.xcodeproj */;
459 | },
460 | );
461 | projectRoot = "";
462 | targets = (
463 | 13B07F861A680F5B00A75B9A /* UploadFromCameraRoll */,
464 | 00E356ED1AD99517003FC87E /* UploadFromCameraRollTests */,
465 | );
466 | };
467 | /* End PBXProject section */
468 |
469 | /* Begin PBXReferenceProxy section */
470 | 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */ = {
471 | isa = PBXReferenceProxy;
472 | fileType = archive.ar;
473 | path = libRCTActionSheet.a;
474 | remoteRef = 00C302AB1ABCB8CE00DB3ED1 /* PBXContainerItemProxy */;
475 | sourceTree = BUILT_PRODUCTS_DIR;
476 | };
477 | 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */ = {
478 | isa = PBXReferenceProxy;
479 | fileType = archive.ar;
480 | path = libRCTGeolocation.a;
481 | remoteRef = 00C302B91ABCB90400DB3ED1 /* PBXContainerItemProxy */;
482 | sourceTree = BUILT_PRODUCTS_DIR;
483 | };
484 | 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */ = {
485 | isa = PBXReferenceProxy;
486 | fileType = archive.ar;
487 | path = libRCTImage.a;
488 | remoteRef = 00C302BF1ABCB91800DB3ED1 /* PBXContainerItemProxy */;
489 | sourceTree = BUILT_PRODUCTS_DIR;
490 | };
491 | 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */ = {
492 | isa = PBXReferenceProxy;
493 | fileType = archive.ar;
494 | path = libRCTNetwork.a;
495 | remoteRef = 00C302DB1ABCB9D200DB3ED1 /* PBXContainerItemProxy */;
496 | sourceTree = BUILT_PRODUCTS_DIR;
497 | };
498 | 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */ = {
499 | isa = PBXReferenceProxy;
500 | fileType = archive.ar;
501 | path = libRCTVibration.a;
502 | remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */;
503 | sourceTree = BUILT_PRODUCTS_DIR;
504 | };
505 | 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = {
506 | isa = PBXReferenceProxy;
507 | fileType = archive.ar;
508 | path = libRCTSettings.a;
509 | remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */;
510 | sourceTree = BUILT_PRODUCTS_DIR;
511 | };
512 | 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */ = {
513 | isa = PBXReferenceProxy;
514 | fileType = archive.ar;
515 | path = libRCTWebSocket.a;
516 | remoteRef = 139FDEF31B06529B00C62182 /* PBXContainerItemProxy */;
517 | sourceTree = BUILT_PRODUCTS_DIR;
518 | };
519 | 146834041AC3E56700842450 /* libReact.a */ = {
520 | isa = PBXReferenceProxy;
521 | fileType = archive.ar;
522 | path = libReact.a;
523 | remoteRef = 146834031AC3E56700842450 /* PBXContainerItemProxy */;
524 | sourceTree = BUILT_PRODUCTS_DIR;
525 | };
526 | 78C398B91ACF4ADC00677621 /* libRCTLinking.a */ = {
527 | isa = PBXReferenceProxy;
528 | fileType = archive.ar;
529 | path = libRCTLinking.a;
530 | remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */;
531 | sourceTree = BUILT_PRODUCTS_DIR;
532 | };
533 | 832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
534 | isa = PBXReferenceProxy;
535 | fileType = archive.ar;
536 | path = libRCTText.a;
537 | remoteRef = 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */;
538 | sourceTree = BUILT_PRODUCTS_DIR;
539 | };
540 | E3912FEF1C3375ED00DE7204 /* libRNUploader.a */ = {
541 | isa = PBXReferenceProxy;
542 | fileType = archive.ar;
543 | path = libRNUploader.a;
544 | remoteRef = E3912FEE1C3375ED00DE7204 /* PBXContainerItemProxy */;
545 | sourceTree = BUILT_PRODUCTS_DIR;
546 | };
547 | E3EFFF511C285FE100EDA48D /* libRCTCameraRoll.a */ = {
548 | isa = PBXReferenceProxy;
549 | fileType = archive.ar;
550 | path = libRCTCameraRoll.a;
551 | remoteRef = E3EFFF501C285FE100EDA48D /* PBXContainerItemProxy */;
552 | sourceTree = BUILT_PRODUCTS_DIR;
553 | };
554 | /* End PBXReferenceProxy section */
555 |
556 | /* Begin PBXResourcesBuildPhase section */
557 | 00E356EC1AD99517003FC87E /* Resources */ = {
558 | isa = PBXResourcesBuildPhase;
559 | buildActionMask = 2147483647;
560 | files = (
561 | );
562 | runOnlyForDeploymentPostprocessing = 0;
563 | };
564 | 13B07F8E1A680F5B00A75B9A /* Resources */ = {
565 | isa = PBXResourcesBuildPhase;
566 | buildActionMask = 2147483647;
567 | files = (
568 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
569 | 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
570 | );
571 | runOnlyForDeploymentPostprocessing = 0;
572 | };
573 | /* End PBXResourcesBuildPhase section */
574 |
575 | /* Begin PBXShellScriptBuildPhase section */
576 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = {
577 | isa = PBXShellScriptBuildPhase;
578 | buildActionMask = 2147483647;
579 | files = (
580 | );
581 | inputPaths = (
582 | );
583 | name = "Bundle React Native code and images";
584 | outputPaths = (
585 | );
586 | runOnlyForDeploymentPostprocessing = 0;
587 | shellPath = /bin/sh;
588 | shellScript = "../node_modules/react-native/packager/react-native-xcode.sh";
589 | };
590 | /* End PBXShellScriptBuildPhase section */
591 |
592 | /* Begin PBXSourcesBuildPhase section */
593 | 00E356EA1AD99517003FC87E /* Sources */ = {
594 | isa = PBXSourcesBuildPhase;
595 | buildActionMask = 2147483647;
596 | files = (
597 | 00E356F31AD99517003FC87E /* UploadFromCameraRollTests.m in Sources */,
598 | );
599 | runOnlyForDeploymentPostprocessing = 0;
600 | };
601 | 13B07F871A680F5B00A75B9A /* Sources */ = {
602 | isa = PBXSourcesBuildPhase;
603 | buildActionMask = 2147483647;
604 | files = (
605 | 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
606 | 13B07FC11A68108700A75B9A /* main.m in Sources */,
607 | );
608 | runOnlyForDeploymentPostprocessing = 0;
609 | };
610 | /* End PBXSourcesBuildPhase section */
611 |
612 | /* Begin PBXTargetDependency section */
613 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = {
614 | isa = PBXTargetDependency;
615 | target = 13B07F861A680F5B00A75B9A /* UploadFromCameraRoll */;
616 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */;
617 | };
618 | /* End PBXTargetDependency section */
619 |
620 | /* Begin PBXVariantGroup section */
621 | 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = {
622 | isa = PBXVariantGroup;
623 | children = (
624 | 13B07FB21A68108700A75B9A /* Base */,
625 | );
626 | name = LaunchScreen.xib;
627 | path = UploadFromCameraRoll;
628 | sourceTree = "";
629 | };
630 | /* End PBXVariantGroup section */
631 |
632 | /* Begin XCBuildConfiguration section */
633 | 00E356F61AD99517003FC87E /* Debug */ = {
634 | isa = XCBuildConfiguration;
635 | buildSettings = {
636 | BUNDLE_LOADER = "$(TEST_HOST)";
637 | FRAMEWORK_SEARCH_PATHS = (
638 | "$(SDKROOT)/Developer/Library/Frameworks",
639 | "$(inherited)",
640 | );
641 | GCC_PREPROCESSOR_DEFINITIONS = (
642 | "DEBUG=1",
643 | "$(inherited)",
644 | );
645 | INFOPLIST_FILE = UploadFromCameraRollTests/Info.plist;
646 | IPHONEOS_DEPLOYMENT_TARGET = 8.2;
647 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
648 | PRODUCT_NAME = "$(TARGET_NAME)";
649 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UploadFromCameraRoll.app/UploadFromCameraRoll";
650 | };
651 | name = Debug;
652 | };
653 | 00E356F71AD99517003FC87E /* Release */ = {
654 | isa = XCBuildConfiguration;
655 | buildSettings = {
656 | BUNDLE_LOADER = "$(TEST_HOST)";
657 | COPY_PHASE_STRIP = NO;
658 | FRAMEWORK_SEARCH_PATHS = (
659 | "$(SDKROOT)/Developer/Library/Frameworks",
660 | "$(inherited)",
661 | );
662 | INFOPLIST_FILE = UploadFromCameraRollTests/Info.plist;
663 | IPHONEOS_DEPLOYMENT_TARGET = 8.2;
664 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
665 | PRODUCT_NAME = "$(TARGET_NAME)";
666 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/UploadFromCameraRoll.app/UploadFromCameraRoll";
667 | };
668 | name = Release;
669 | };
670 | 13B07F941A680F5B00A75B9A /* Debug */ = {
671 | isa = XCBuildConfiguration;
672 | buildSettings = {
673 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
674 | DEAD_CODE_STRIPPING = NO;
675 | HEADER_SEARCH_PATHS = (
676 | "$(inherited)",
677 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
678 | "$(SRCROOT)/../node_modules/react-native/React/**",
679 | );
680 | INFOPLIST_FILE = UploadFromCameraRoll/Info.plist;
681 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
682 | OTHER_LDFLAGS = "-ObjC";
683 | PRODUCT_NAME = UploadFromCameraRoll;
684 | };
685 | name = Debug;
686 | };
687 | 13B07F951A680F5B00A75B9A /* Release */ = {
688 | isa = XCBuildConfiguration;
689 | buildSettings = {
690 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
691 | HEADER_SEARCH_PATHS = (
692 | "$(inherited)",
693 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
694 | "$(SRCROOT)/../node_modules/react-native/React/**",
695 | );
696 | INFOPLIST_FILE = UploadFromCameraRoll/Info.plist;
697 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
698 | OTHER_LDFLAGS = "-ObjC";
699 | PRODUCT_NAME = UploadFromCameraRoll;
700 | };
701 | name = Release;
702 | };
703 | 83CBBA201A601CBA00E9B192 /* Debug */ = {
704 | isa = XCBuildConfiguration;
705 | buildSettings = {
706 | ALWAYS_SEARCH_USER_PATHS = NO;
707 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
708 | CLANG_CXX_LIBRARY = "libc++";
709 | CLANG_ENABLE_MODULES = YES;
710 | CLANG_ENABLE_OBJC_ARC = YES;
711 | CLANG_WARN_BOOL_CONVERSION = YES;
712 | CLANG_WARN_CONSTANT_CONVERSION = YES;
713 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
714 | CLANG_WARN_EMPTY_BODY = YES;
715 | CLANG_WARN_ENUM_CONVERSION = YES;
716 | CLANG_WARN_INT_CONVERSION = YES;
717 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
718 | CLANG_WARN_UNREACHABLE_CODE = YES;
719 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
720 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
721 | COPY_PHASE_STRIP = NO;
722 | ENABLE_STRICT_OBJC_MSGSEND = YES;
723 | GCC_C_LANGUAGE_STANDARD = gnu99;
724 | GCC_DYNAMIC_NO_PIC = NO;
725 | GCC_OPTIMIZATION_LEVEL = 0;
726 | GCC_PREPROCESSOR_DEFINITIONS = (
727 | "DEBUG=1",
728 | "$(inherited)",
729 | );
730 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
731 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
732 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
733 | GCC_WARN_UNDECLARED_SELECTOR = YES;
734 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
735 | GCC_WARN_UNUSED_FUNCTION = YES;
736 | GCC_WARN_UNUSED_VARIABLE = YES;
737 | HEADER_SEARCH_PATHS = (
738 | "$(inherited)",
739 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
740 | "$(SRCROOT)/../node_modules/react-native/React/**",
741 | );
742 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
743 | MTL_ENABLE_DEBUG_INFO = YES;
744 | ONLY_ACTIVE_ARCH = YES;
745 | SDKROOT = iphoneos;
746 | };
747 | name = Debug;
748 | };
749 | 83CBBA211A601CBA00E9B192 /* Release */ = {
750 | isa = XCBuildConfiguration;
751 | buildSettings = {
752 | ALWAYS_SEARCH_USER_PATHS = NO;
753 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
754 | CLANG_CXX_LIBRARY = "libc++";
755 | CLANG_ENABLE_MODULES = YES;
756 | CLANG_ENABLE_OBJC_ARC = YES;
757 | CLANG_WARN_BOOL_CONVERSION = YES;
758 | CLANG_WARN_CONSTANT_CONVERSION = YES;
759 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
760 | CLANG_WARN_EMPTY_BODY = YES;
761 | CLANG_WARN_ENUM_CONVERSION = YES;
762 | CLANG_WARN_INT_CONVERSION = YES;
763 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
764 | CLANG_WARN_UNREACHABLE_CODE = YES;
765 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
766 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
767 | COPY_PHASE_STRIP = YES;
768 | ENABLE_NS_ASSERTIONS = NO;
769 | ENABLE_STRICT_OBJC_MSGSEND = YES;
770 | GCC_C_LANGUAGE_STANDARD = gnu99;
771 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
772 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
773 | GCC_WARN_UNDECLARED_SELECTOR = YES;
774 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
775 | GCC_WARN_UNUSED_FUNCTION = YES;
776 | GCC_WARN_UNUSED_VARIABLE = YES;
777 | HEADER_SEARCH_PATHS = (
778 | "$(inherited)",
779 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
780 | "$(SRCROOT)/../node_modules/react-native/React/**",
781 | );
782 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
783 | MTL_ENABLE_DEBUG_INFO = NO;
784 | SDKROOT = iphoneos;
785 | VALIDATE_PRODUCT = YES;
786 | };
787 | name = Release;
788 | };
789 | /* End XCBuildConfiguration section */
790 |
791 | /* Begin XCConfigurationList section */
792 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "UploadFromCameraRollTests" */ = {
793 | isa = XCConfigurationList;
794 | buildConfigurations = (
795 | 00E356F61AD99517003FC87E /* Debug */,
796 | 00E356F71AD99517003FC87E /* Release */,
797 | );
798 | defaultConfigurationIsVisible = 0;
799 | defaultConfigurationName = Release;
800 | };
801 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "UploadFromCameraRoll" */ = {
802 | isa = XCConfigurationList;
803 | buildConfigurations = (
804 | 13B07F941A680F5B00A75B9A /* Debug */,
805 | 13B07F951A680F5B00A75B9A /* Release */,
806 | );
807 | defaultConfigurationIsVisible = 0;
808 | defaultConfigurationName = Release;
809 | };
810 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "UploadFromCameraRoll" */ = {
811 | isa = XCConfigurationList;
812 | buildConfigurations = (
813 | 83CBBA201A601CBA00E9B192 /* Debug */,
814 | 83CBBA211A601CBA00E9B192 /* Release */,
815 | );
816 | defaultConfigurationIsVisible = 0;
817 | defaultConfigurationName = Release;
818 | };
819 | /* End XCConfigurationList section */
820 | };
821 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */;
822 | }
823 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll.xcodeproj/xcshareddata/xcschemes/UploadFromCameraRoll.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 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll/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 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll/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 "Bundle React Native code and images" build step.
40 | */
41 |
42 | // jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
43 |
44 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
45 | moduleName:@"UploadFromCameraRoll"
46 | initialProperties:nil
47 | launchOptions:launchOptions];
48 |
49 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
50 | UIViewController *rootViewController = [UIViewController new];
51 | rootViewController.view = rootView;
52 | self.window.rootViewController = rootViewController;
53 | [self.window makeKeyAndVisible];
54 | return YES;
55 | }
56 |
57 | @end
58 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll/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 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll/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 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRoll/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 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRollTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/ios/UploadFromCameraRollTests/UploadFromCameraRollTests.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 240
17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!"
18 |
19 | @interface UploadFromCameraRollTests : XCTestCase
20 |
21 | @end
22 |
23 | @implementation UploadFromCameraRollTests
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 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "UploadFromCameraRoll",
3 | "version": "0.0.1",
4 | "private": true,
5 | "scripts": {
6 | "start": "react-native start"
7 | },
8 | "dependencies": {
9 | "react-native": "^0.17.0",
10 | "react-native-uploader": "file:../../"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/examples/UploadFromCameraRoll/uploader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/choru-k/react-native-uploader/3253ea32127d53bd39294946103ae7405bc8f6d2/examples/UploadFromCameraRoll/uploader.gif
--------------------------------------------------------------------------------
/index.android.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var { NativeModules } = require('react-native');
4 | var FileTransfer = NativeModules.FileTransfer
5 |
6 | class RNUploader {
7 | constructor() {
8 | }
9 |
10 | static upload(opts, callback) {
11 | FileTransfer.upload(opts, callback);
12 | }
13 | }
14 |
15 | module.exports = RNUploader;
--------------------------------------------------------------------------------
/index.ios.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @providesModule RNUploader
3 | * @flow
4 | */
5 | 'use strict';
6 | var { NativeModules } = require('react-native');
7 | var NativeRNUploader = NativeModules.RNUploader;
8 |
9 | /**
10 | * High-level docs for the RNUploader iOS API can be written here.
11 | */
12 |
13 | class RNUploader {
14 | constructor() {
15 | }
16 |
17 | static upload(opts, callback) {
18 | NativeRNUploader.upload(opts, callback);
19 | }
20 | static cancel(){
21 | NativeRNUploader.cancel()
22 | }
23 | static test() {
24 | NativeRNUploader.test()
25 | }
26 | }
27 |
28 | module.exports = RNUploader;
--------------------------------------------------------------------------------
/ios/RNUploader.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 | #import
5 |
6 | #import "RCTBridgeModule.h"
7 | #import "RCTEventDispatcher.h"
8 | #import "RCTLog.h"
9 |
10 | @interface RNUploader : NSObject
11 | @property NSMutableData *responseData;
12 | @property NSInteger responseStatusCode;
13 |
14 | @property NSURLConnection *connection;
15 | @property NSMutableURLRequest *request;
16 | @property NSMutableData *requestBody;
17 | @property NSMutableArray *files;
18 |
19 | @property NSString *formBoundaryString;
20 | @property NSData *formBoundaryData;
21 |
22 | @property dispatch_group_t fgroup;
23 | @end
24 |
25 | @implementation RNUploader
26 |
27 | @synthesize bridge = _bridge;
28 | RCTResponseSenderBlock _callback;
29 |
30 |
31 | RCT_EXPORT_MODULE()
32 |
33 | RCT_EXPORT_METHOD(cancel){
34 | [self.connection cancel];
35 | }
36 |
37 | RCT_EXPORT_METHOD(upload:(NSDictionary *)obj callback:(RCTResponseSenderBlock)callback)
38 | {
39 | _callback = callback;
40 |
41 | NSString *uploadURL = obj[@"url"];
42 | NSDictionary *headers = obj[@"headers"];
43 | NSDictionary *params = obj[@"params"];
44 | NSArray *files = obj[@"files"];
45 | NSString *method = obj[@"method"];
46 |
47 | NSURL *url = [NSURL URLWithString:uploadURL];
48 |
49 | self.formBoundaryString = [self generateBoundaryString];
50 | self.formBoundaryData = [[NSString stringWithFormat:@"--%@\r\n", self.formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
51 |
52 | self.request = [NSMutableURLRequest requestWithURL:url];
53 | self.responseData = [[NSMutableData alloc] init];
54 | self.requestBody = [[NSMutableData alloc] init];
55 | self.files = [[NSMutableArray alloc] init];
56 | self.fgroup = dispatch_group_create();
57 |
58 | [self setMethod:method];
59 | [self setHeaders:headers];
60 | [self setParams:params];
61 | [self prepareFiles:files];
62 |
63 | dispatch_group_notify(self.fgroup, dispatch_get_main_queue(), ^{
64 | [self appendFiles];
65 | [self sendRequest];
66 | });
67 | }
68 |
69 | //
70 | // Action Methods
71 | //
72 |
73 | - (void)setMethod:(NSString *)method {
74 | if( [method isEqualToString:@"POST"] || [method isEqualToString:@"PUT"] ){
75 | [self.request setHTTPMethod:method];
76 | }else{
77 | [self.request setHTTPMethod:@"POST"];
78 | }
79 | }
80 |
81 | - (void)setHeaders:(NSDictionary *)headers {
82 | NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.formBoundaryString];
83 | [self.request setValue:contentType forHTTPHeaderField:@"Content-Type"];
84 | for (NSString *key in headers) {
85 | id val = [headers objectForKey:key];
86 | if ([val respondsToSelector:@selector(stringValue)]) {
87 | val = [val stringValue];
88 | }
89 | if (![val isKindOfClass:[NSString class]]) {
90 | continue;
91 | }
92 | [self.request setValue:val forHTTPHeaderField:key];
93 | }
94 | }
95 |
96 | - (void)setParams:(NSDictionary *)params {
97 | for (NSString *key in params) {
98 | id value = [params objectForKey:key];
99 | if ([value respondsToSelector:@selector(stringValue)]) {
100 | value = [value stringValue];
101 | }
102 | //
103 | // TODO: handle objects
104 | //
105 | if (![value isKindOfClass:[NSString class]]) {
106 | continue;
107 | }
108 |
109 | [self.requestBody appendData:self.formBoundaryData];
110 | [self.requestBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key] dataUsingEncoding:NSUTF8StringEncoding]];
111 | [self.requestBody appendData:[value dataUsingEncoding:NSUTF8StringEncoding]];
112 | [self.requestBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
113 | }
114 | }
115 |
116 | - (void)prepareFiles:(NSArray *)files {
117 | ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
118 |
119 | for (NSDictionary *file in files) {
120 | dispatch_group_enter(self.fgroup);
121 |
122 | NSMutableDictionary *_file = [[NSMutableDictionary alloc] initWithDictionary:file];
123 | [self.files addObject:_file];
124 |
125 | if( [_file[@"filepath"] hasPrefix:@"assets-library:"]) {
126 | NSURL *assetURL = [[NSURL alloc] initWithString:file[@"filepath"]];
127 |
128 | [library assetForURL:assetURL resultBlock:^(ALAsset *asset) {
129 |
130 |
131 | ALAssetRepresentation *representation = [asset defaultRepresentation];
132 |
133 | NSString *fileName = [representation filename];
134 | //Getting MIMEType
135 | NSString *MIMEType = (__bridge_transfer NSString*)UTTypeCopyPreferredTagWithClass
136 | ((__bridge CFStringRef)[representation UTI], kUTTagClassMIMEType);
137 |
138 |
139 | ALAssetRepresentation *rep = [asset defaultRepresentation];
140 |
141 | //testing RegExp (video|image)
142 | if([MIMEType rangeOfString:@"video" options:NSRegularExpressionSearch].location != NSNotFound){
143 |
144 | //buffering output
145 | Byte *buffer = (Byte*)malloc((NSUInteger)rep.size);
146 | NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:(NSUInteger)rep.size error:nil];
147 | NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];
148 |
149 | _file[@"data"] = data;
150 |
151 | }else if([MIMEType rangeOfString:@"image" options:NSRegularExpressionSearch].location != NSNotFound){
152 |
153 | CGImageRef fullScreenImageRef = [rep fullScreenImage];
154 | UIImage *image = [UIImage imageWithCGImage:fullScreenImageRef];
155 |
156 | _file[@"data"] = UIImagePNGRepresentation(image);
157 | }
158 |
159 | dispatch_group_leave(self.fgroup);
160 |
161 | } failureBlock:^(NSError *error) {
162 | NSLog(@"Getting file from library failed: %@", error);
163 | dispatch_group_leave(self.fgroup);
164 | }];
165 |
166 |
167 | }else{
168 | NSString *filepath = _file[@"filepath"];
169 | NSURL *fileUrl = [[NSURL alloc] initWithString:filepath];
170 |
171 | if ( [filepath hasPrefix:@"data:"] || [filepath hasPrefix:@"file:"]) {
172 | _file[@"data"] = [NSData dataWithContentsOfURL: fileUrl];
173 | } else {
174 | _file[@"data"] = [NSData dataWithContentsOfFile:filepath];
175 | }
176 |
177 | dispatch_group_leave(self.fgroup);
178 | }
179 | }
180 |
181 | }
182 |
183 | - (void)appendFiles {
184 | for( NSMutableDictionary *file in self.files ){
185 | NSString *name = file[@"name"];
186 | NSString *filename = file[@"filename"];
187 | NSString *filetype = file[@"filetype"];
188 | NSData *data = file[@"data"];
189 |
190 | [self.requestBody appendData:self.formBoundaryData];
191 | [self.requestBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", name.length ? name : filename, filename] dataUsingEncoding:NSUTF8StringEncoding]];
192 |
193 | if (filetype) {
194 | [self.requestBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", filetype] dataUsingEncoding:NSUTF8StringEncoding]];
195 | } else {
196 | [self.requestBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n", [self mimeTypeForPath:filename]] dataUsingEncoding:NSUTF8StringEncoding]];
197 | }
198 |
199 | [self.requestBody appendData:[[NSString stringWithFormat:@"Content-Length: %ld\r\n\r\n", (long)[data length]] dataUsingEncoding:NSUTF8StringEncoding]];
200 | [self.requestBody appendData:data];
201 | [self.requestBody appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
202 | }
203 | }
204 |
205 | - (void)sendRequest {
206 | NSData *endData = [[NSString stringWithFormat:@"--%@--\r\n", self.formBoundaryString] dataUsingEncoding:NSUTF8StringEncoding];
207 |
208 | [self.requestBody appendData:endData];
209 | [self.request setHTTPBody:self.requestBody];
210 |
211 | // upload
212 | self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];
213 | [self.connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
214 | [self.connection start];
215 | }
216 |
217 | //
218 | // Helpers
219 | //
220 |
221 | - (NSString *)generateBoundaryString
222 | {
223 | NSString *uuid = [[NSUUID UUID] UUIDString];
224 | NSString *boundaryString = [NSString stringWithFormat:@"----%@", uuid];
225 | return boundaryString;
226 | }
227 |
228 | - (NSString *)mimeTypeForPath:(NSString *)filepath
229 | {
230 | NSString *fileExtension = [filepath pathExtension];
231 | NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL);
232 | NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
233 |
234 | if (!contentType) {
235 | contentType = @"application/octet-stream";
236 | }
237 |
238 | return contentType;
239 | }
240 |
241 | //
242 | // Delegate Methods
243 | //
244 |
245 | #pragma mark - NSURLConnectionDelegate
246 |
247 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
248 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNUploaderDidFailWithError" body:[error localizedDescription]];
249 | _callback(@[[error localizedDescription], [NSNull null]]);
250 | }
251 |
252 | #pragma mark - NSURLConnectionDataDelegate
253 |
254 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
255 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNUploaderDidReceiveResponse" body:nil];
256 | self.responseStatusCode = [(NSHTTPURLResponse *)response statusCode];
257 | }
258 |
259 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
260 | NSString *resString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
261 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNUploaderDidReceiveData" body:resString];
262 | [self.responseData appendData:data];
263 | }
264 |
265 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
266 | NSString *responseString = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
267 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNUploaderDataFinishLoading" body:responseString];
268 |
269 | NSDictionary *res= [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInteger:self.responseStatusCode],@"status",responseString,@"data",nil];
270 |
271 | _callback(@[[NSNull null], res]);
272 | }
273 |
274 | - (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
275 | NSNumber *progress = @([@(totalBytesWritten) floatValue]/[@(totalBytesExpectedToWrite) floatValue] * 100.0);
276 | [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNUploaderProgress"
277 | body:@{ @"totalBytesWritten": @(totalBytesWritten),
278 | @"totalBytesExpectedToWrite": @(totalBytesExpectedToWrite),
279 | @"progress": progress }];
280 | }
281 |
282 | @end
283 |
--------------------------------------------------------------------------------
/ios/RNUploader.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 13BE3DEE1AC21097009241FE /* RNUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* RNUploader.m */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXCopyFilesBuildPhase section */
14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = {
15 | isa = PBXCopyFilesBuildPhase;
16 | buildActionMask = 2147483647;
17 | dstPath = "include/$(PRODUCT_NAME)";
18 | dstSubfolderSpec = 16;
19 | files = (
20 | );
21 | runOnlyForDeploymentPostprocessing = 0;
22 | };
23 | /* End PBXCopyFilesBuildPhase section */
24 |
25 | /* Begin PBXFileReference section */
26 | 134814201AA4EA6300B7C361 /* libRNUploader.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNUploader.a; sourceTree = BUILT_PRODUCTS_DIR; };
27 | 13BE3DED1AC21097009241FE /* RNUploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNUploader.m; sourceTree = ""; };
28 | /* End PBXFileReference section */
29 |
30 | /* Begin PBXFrameworksBuildPhase section */
31 | 58B511D81A9E6C8500147676 /* Frameworks */ = {
32 | isa = PBXFrameworksBuildPhase;
33 | buildActionMask = 2147483647;
34 | files = (
35 | );
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXFrameworksBuildPhase section */
39 |
40 | /* Begin PBXGroup section */
41 | 134814211AA4EA7D00B7C361 /* Products */ = {
42 | isa = PBXGroup;
43 | children = (
44 | 134814201AA4EA6300B7C361 /* libRNUploader.a */,
45 | );
46 | name = Products;
47 | sourceTree = "";
48 | };
49 | 58B511D21A9E6C8500147676 = {
50 | isa = PBXGroup;
51 | children = (
52 | 13BE3DED1AC21097009241FE /* RNUploader.m */,
53 | 134814211AA4EA7D00B7C361 /* Products */,
54 | );
55 | sourceTree = "";
56 | };
57 | /* End PBXGroup section */
58 |
59 | /* Begin PBXNativeTarget section */
60 | 58B511DA1A9E6C8500147676 /* RNUploader */ = {
61 | isa = PBXNativeTarget;
62 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNUploader" */;
63 | buildPhases = (
64 | 58B511D71A9E6C8500147676 /* Sources */,
65 | 58B511D81A9E6C8500147676 /* Frameworks */,
66 | 58B511D91A9E6C8500147676 /* CopyFiles */,
67 | );
68 | buildRules = (
69 | );
70 | dependencies = (
71 | );
72 | name = RNUploader;
73 | productName = RCTDataManager;
74 | productReference = 134814201AA4EA6300B7C361 /* libRNUploader.a */;
75 | productType = "com.apple.product-type.library.static";
76 | };
77 | /* End PBXNativeTarget section */
78 |
79 | /* Begin PBXProject section */
80 | 58B511D31A9E6C8500147676 /* Project object */ = {
81 | isa = PBXProject;
82 | attributes = {
83 | LastUpgradeCheck = 0610;
84 | ORGANIZATIONNAME = "Adam Roth";
85 | TargetAttributes = {
86 | 58B511DA1A9E6C8500147676 = {
87 | CreatedOnToolsVersion = 6.1.1;
88 | };
89 | };
90 | };
91 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNUploader" */;
92 | compatibilityVersion = "Xcode 3.2";
93 | developmentRegion = English;
94 | hasScannedForEncodings = 0;
95 | knownRegions = (
96 | en,
97 | );
98 | mainGroup = 58B511D21A9E6C8500147676;
99 | productRefGroup = 58B511D21A9E6C8500147676;
100 | projectDirPath = "";
101 | projectRoot = "";
102 | targets = (
103 | 58B511DA1A9E6C8500147676 /* RNUploader */,
104 | );
105 | };
106 | /* End PBXProject section */
107 |
108 | /* Begin PBXSourcesBuildPhase section */
109 | 58B511D71A9E6C8500147676 /* Sources */ = {
110 | isa = PBXSourcesBuildPhase;
111 | buildActionMask = 2147483647;
112 | files = (
113 | 13BE3DEE1AC21097009241FE /* RNUploader.m in Sources */,
114 | );
115 | runOnlyForDeploymentPostprocessing = 0;
116 | };
117 | /* End PBXSourcesBuildPhase section */
118 |
119 | /* Begin XCBuildConfiguration section */
120 | 58B511ED1A9E6C8500147676 /* Debug */ = {
121 | isa = XCBuildConfiguration;
122 | buildSettings = {
123 | ALWAYS_SEARCH_USER_PATHS = NO;
124 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
125 | CLANG_CXX_LIBRARY = "libc++";
126 | CLANG_ENABLE_MODULES = YES;
127 | CLANG_ENABLE_OBJC_ARC = YES;
128 | CLANG_WARN_BOOL_CONVERSION = YES;
129 | CLANG_WARN_CONSTANT_CONVERSION = YES;
130 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
131 | CLANG_WARN_EMPTY_BODY = YES;
132 | CLANG_WARN_ENUM_CONVERSION = YES;
133 | CLANG_WARN_INT_CONVERSION = YES;
134 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
135 | CLANG_WARN_UNREACHABLE_CODE = YES;
136 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
137 | COPY_PHASE_STRIP = NO;
138 | ENABLE_STRICT_OBJC_MSGSEND = YES;
139 | GCC_C_LANGUAGE_STANDARD = gnu99;
140 | GCC_DYNAMIC_NO_PIC = NO;
141 | GCC_OPTIMIZATION_LEVEL = 0;
142 | GCC_PREPROCESSOR_DEFINITIONS = (
143 | "DEBUG=1",
144 | "$(inherited)",
145 | );
146 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
147 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
148 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
149 | GCC_WARN_UNDECLARED_SELECTOR = YES;
150 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
151 | GCC_WARN_UNUSED_FUNCTION = YES;
152 | GCC_WARN_UNUSED_VARIABLE = YES;
153 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
154 | MTL_ENABLE_DEBUG_INFO = YES;
155 | ONLY_ACTIVE_ARCH = YES;
156 | SDKROOT = iphoneos;
157 | };
158 | name = Debug;
159 | };
160 | 58B511EE1A9E6C8500147676 /* Release */ = {
161 | isa = XCBuildConfiguration;
162 | buildSettings = {
163 | ALWAYS_SEARCH_USER_PATHS = NO;
164 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
165 | CLANG_CXX_LIBRARY = "libc++";
166 | CLANG_ENABLE_MODULES = YES;
167 | CLANG_ENABLE_OBJC_ARC = YES;
168 | CLANG_WARN_BOOL_CONVERSION = YES;
169 | CLANG_WARN_CONSTANT_CONVERSION = YES;
170 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
171 | CLANG_WARN_EMPTY_BODY = YES;
172 | CLANG_WARN_ENUM_CONVERSION = YES;
173 | CLANG_WARN_INT_CONVERSION = YES;
174 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
175 | CLANG_WARN_UNREACHABLE_CODE = YES;
176 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
177 | COPY_PHASE_STRIP = YES;
178 | ENABLE_NS_ASSERTIONS = NO;
179 | ENABLE_STRICT_OBJC_MSGSEND = YES;
180 | GCC_C_LANGUAGE_STANDARD = gnu99;
181 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
182 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
183 | GCC_WARN_UNDECLARED_SELECTOR = YES;
184 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
185 | GCC_WARN_UNUSED_FUNCTION = YES;
186 | GCC_WARN_UNUSED_VARIABLE = YES;
187 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
188 | MTL_ENABLE_DEBUG_INFO = NO;
189 | SDKROOT = iphoneos;
190 | VALIDATE_PRODUCT = YES;
191 | };
192 | name = Release;
193 | };
194 | 58B511F01A9E6C8500147676 /* Debug */ = {
195 | isa = XCBuildConfiguration;
196 | buildSettings = {
197 | HEADER_SEARCH_PATHS = (
198 | "$(inherited)",
199 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
200 | "$(SRCROOT)/../../../React/**",
201 | "$(SRCROOT)/../../../node_modules/react-native/React/**",
202 | "$(SRCROOT)/node_modules/react-native/React/**",
203 | "$(SRCROOT)/../../node_modules/react-native/React/**/**",
204 | );
205 | LIBRARY_SEARCH_PATHS = "$(inherited)";
206 | OTHER_LDFLAGS = "-ObjC";
207 | PRODUCT_NAME = RNUploader;
208 | SKIP_INSTALL = YES;
209 | };
210 | name = Debug;
211 | };
212 | 58B511F11A9E6C8500147676 /* Release */ = {
213 | isa = XCBuildConfiguration;
214 | buildSettings = {
215 | HEADER_SEARCH_PATHS = (
216 | "$(inherited)",
217 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
218 | "$(SRCROOT)/../../React/**",
219 | "$(SRCROOT)/../../node_modules/react-native/React/**",
220 | "$(SRCROOT)/../../node_modules/react-native/React/**/**",
221 | "$(SRCROOT)/../../../node_modules/react-native/React/**",
222 | "$(SRCROOT)/node_modules/react-native/React/**",
223 | );
224 | LIBRARY_SEARCH_PATHS = "$(inherited)";
225 | OTHER_LDFLAGS = "-ObjC";
226 | PRODUCT_NAME = RNUploader;
227 | SKIP_INSTALL = YES;
228 | };
229 | name = Release;
230 | };
231 | /* End XCBuildConfiguration section */
232 |
233 | /* Begin XCConfigurationList section */
234 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNUploader" */ = {
235 | isa = XCConfigurationList;
236 | buildConfigurations = (
237 | 58B511ED1A9E6C8500147676 /* Debug */,
238 | 58B511EE1A9E6C8500147676 /* Release */,
239 | );
240 | defaultConfigurationIsVisible = 0;
241 | defaultConfigurationName = Release;
242 | };
243 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNUploader" */ = {
244 | isa = XCConfigurationList;
245 | buildConfigurations = (
246 | 58B511F01A9E6C8500147676 /* Debug */,
247 | 58B511F11A9E6C8500147676 /* Release */,
248 | );
249 | defaultConfigurationIsVisible = 0;
250 | defaultConfigurationName = Release;
251 | };
252 | /* End XCConfigurationList section */
253 | };
254 | rootObject = 58B511D31A9E6C8500147676 /* Project object */;
255 | }
256 |
--------------------------------------------------------------------------------
/ios/RNUploader.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-uploader",
3 | "repository": {
4 | "type": "git",
5 | "url": "git+https://github.com/aroth/react-native-uploader.git"
6 | },
7 | "version": "0.0.10",
8 | "description": "A React Native module to upload files and camera roll assets. Supports progress notification.",
9 | "author": {
10 | "name": "Adam Roth",
11 | "url": "aroth"
12 | },
13 | "nativePackage": true,
14 | "keywords": [
15 | "react-native",
16 | "react-native-upload",
17 | "react-component",
18 | "react",
19 | "native",
20 | "image",
21 | "upload",
22 | "transfer",
23 | "file"
24 | ],
25 | "bugs": {
26 | "url": "https://github.com/aroth/react-native-uploader/issues"
27 | },
28 | "homepage": "https://github.com/aroth/react-native-uploader#readme",
29 | "maintainers": [
30 | {
31 | "name": "aroth",
32 | "email": "adamjroth@gmail.com"
33 | }
34 | ],
35 | "main": "index"
36 | }
37 |
--------------------------------------------------------------------------------