@nativescript/background-http
Advanced tools
Comparing version 5.0.2 to 6.0.0
@@ -1,3 +0,4 @@ | ||
import { Observable } from "@nativescript/core"; | ||
import * as common from "./index"; | ||
import { Observable } from '@nativescript/core'; | ||
import * as common from './index'; | ||
export declare function init(): void; | ||
export declare function session(id: string): Session; | ||
@@ -4,0 +5,0 @@ declare class ObservableBase extends Observable { |
@@ -1,2 +0,30 @@ | ||
import { Observable, Application, knownFolders } from "@nativescript/core"; | ||
import { Observable, Application, knownFolders, Utils } from '@nativescript/core'; | ||
let didInit = false; | ||
export function init() { | ||
if (didInit) { | ||
return; | ||
} | ||
initializeProgressReceiver(); | ||
const callback = function (event) { | ||
const appContext = Utils.android.getApplicationContext(); | ||
const packageName = appContext.getPackageName(); | ||
if (android.os.Build.VERSION.SDK_INT >= 26) { | ||
const channel = new android.app.NotificationChannel(packageName, `${packageName} Channel`, android.app.NotificationManager.IMPORTANCE_LOW); | ||
const manager = appContext.getSystemService(android.content.Context.NOTIFICATION_SERVICE); | ||
manager.createNotificationChannel(channel); | ||
} | ||
let isDebug = false; | ||
try { | ||
const BuildConfigClazz = java.lang.Class.forName(`${packageName}.BuildConfig`); | ||
const DEBUG = BuildConfigClazz.getDeclaredField('DEBUG'); | ||
isDebug = Boolean(DEBUG.get(null)); | ||
} | ||
catch (e) { } | ||
net.gotev.uploadservice.UploadServiceConfig.initialize(Utils.android.getApplication(), packageName, isDebug); | ||
new net.gotev.uploadservice.observer.request.GlobalRequestObserver(Utils.android.getApplication(), ProgressReceiver); | ||
didInit = true; | ||
Application.off('launch', callback); | ||
}; | ||
Application.on('launch', callback); | ||
} | ||
/* A snapshot-friendly, lazy-loaded class for ProgressReceiver BEGIN */ | ||
@@ -11,28 +39,10 @@ let ProgressReceiver; | ||
task.setUpload(currentBytes); | ||
task.setStatus("uploading"); | ||
task.setStatus('uploading'); | ||
task.notify({ | ||
eventName: "progress", | ||
eventName: 'progress', | ||
object: task, | ||
currentBytes: currentBytes, | ||
totalBytes: totalBytes | ||
totalBytes: totalBytes, | ||
}); | ||
} | ||
function onProgressReceiverCancelled(context, uploadInfo) { | ||
const uploadId = uploadInfo.getUploadId(); | ||
const task = Task.fromId(uploadId); | ||
task.setStatus("cancelled"); | ||
task.notify({ eventName: "cancelled", object: task }); | ||
} | ||
function onProgressReceiverError(context, uploadInfo, response, error) { | ||
const uploadId = uploadInfo.getUploadId(); | ||
const task = Task.fromId(uploadId); | ||
task.setStatus("error"); | ||
task.notify({ | ||
eventName: "error", | ||
object: task, | ||
error, | ||
responseCode: response && typeof response.getHttpCode === 'function' ? response.getHttpCode() : -1, | ||
response | ||
}); | ||
} | ||
function onProgressReceiverCompleted(context, uploadInfo, response) { | ||
@@ -47,22 +57,40 @@ const uploadId = uploadInfo.getUploadId(); | ||
task.setTotalUpload(totalUpload); | ||
task.setStatus("complete"); | ||
task.setStatus('complete'); | ||
task.notify({ | ||
eventName: "progress", | ||
eventName: 'progress', | ||
object: task, | ||
currentBytes: totalUpload, | ||
totalBytes: totalUpload | ||
totalBytes: totalUpload, | ||
}); | ||
task.notify({ | ||
eventName: "responded", | ||
eventName: 'responded', | ||
object: task, | ||
data: response.getBodyAsString(), | ||
responseCode: response && typeof response.getHttpCode === 'function' ? response.getHttpCode() : -1 | ||
data: response.getBodyString(), | ||
responseCode: response && typeof response.getCode === 'function' ? response.getCode() : -1, | ||
}); | ||
task.notify({ | ||
eventName: "complete", | ||
eventName: 'complete', | ||
object: task, | ||
responseCode: response && typeof response.getHttpCode === 'function' ? response.getHttpCode() : -1, | ||
response | ||
responseCode: response && typeof response.getCode === 'function' ? response.getCode() : -1, | ||
response, | ||
}); | ||
} | ||
function onProgressReceiverCancelled(context, uploadInfo) { | ||
const uploadId = uploadInfo.getUploadId(); | ||
const task = Task.fromId(uploadId); | ||
task.setStatus("cancelled"); | ||
task.notify({ eventName: "cancelled", object: task }); | ||
} | ||
function onProgressReceiverError(context, uploadInfo, response, error) { | ||
const uploadId = uploadInfo.getUploadId(); | ||
const task = Task.fromId(uploadId); | ||
task.setStatus('error'); | ||
task.notify({ | ||
eventName: 'error', | ||
object: task, | ||
error, | ||
responseCode: response && typeof response.getCode === 'function' ? response.getCode() : -1, | ||
response, | ||
}); | ||
} | ||
function initializeProgressReceiver() { | ||
@@ -76,35 +104,24 @@ if (ProgressReceiver) { | ||
const zonedOnCompleted = global.zonedCallback(onProgressReceiverCompleted); | ||
const temp = { | ||
ProgressReceiver = new net.gotev.uploadservice.observer.request.RequestObserverDelegate({ | ||
onProgress(context, uploadInfo) { | ||
zonedOnProgress(context, uploadInfo); | ||
}, | ||
onCancelled(context, uploadInfo) { | ||
zonedOnCancelled(context, uploadInfo); | ||
onSuccess(context, info, response) { | ||
zonedOnCompleted(context, info, response); | ||
}, | ||
onError(context, uploadInfo, response, error) { | ||
zonedOnError(context, uploadInfo, response, error); | ||
onError(context, uploadInfo, error) { | ||
if (error instanceof net.gotev.uploadservice.exceptions.UserCancelledUploadException) { | ||
zonedOnCancelled(context, uploadInfo); | ||
} | ||
else { | ||
zonedOnError(context, uploadInfo, error); | ||
} | ||
}, | ||
onCompleted(context, uploadInfo, serverResponse) { | ||
zonedOnCompleted(context, uploadInfo, serverResponse); | ||
} | ||
}; | ||
const ProgressReceiverImpl = net.gotev.uploadservice.UploadServiceBroadcastReceiver.extend(temp); | ||
ProgressReceiver = ProgressReceiverImpl; | ||
onCompleted(context, uploadInfo) { }, | ||
onCompletedWhileNotObserving() { }, | ||
}); | ||
} | ||
/* ProgressReceiver END */ | ||
let hasNamespace = false; | ||
function ensureUploadServiceNamespace() { | ||
if (!hasNamespace) { | ||
net.gotev.uploadservice.UploadService.NAMESPACE = Application.android.packageName; | ||
hasNamespace = true; | ||
} | ||
} | ||
let receiver; | ||
function ensureReceiver() { | ||
if (!receiver) { | ||
const context = Application.android.context; | ||
initializeProgressReceiver(); | ||
receiver = new ProgressReceiver(); | ||
receiver.register(context); | ||
} | ||
initializeProgressReceiver(); | ||
} | ||
@@ -136,5 +153,4 @@ export function session(id) { | ||
static create(session, file, options) { | ||
ensureUploadServiceNamespace(); | ||
ensureReceiver(); | ||
const taskId = session.id + "{" + ++Task.taskCount + "}"; | ||
const taskId = session.id + '{' + ++Task.taskCount + '}'; | ||
const request = getBinaryRequest(taskId, options, file); | ||
@@ -147,5 +163,4 @@ const task = Task.initTask(taskId, session, options); | ||
static createMultiPart(session, params, options) { | ||
ensureUploadServiceNamespace(); | ||
ensureReceiver(); | ||
const taskId = session.id + "{" + ++Task.taskCount + "}"; | ||
const taskId = session.id + '{' + ++Task.taskCount + '}'; | ||
const request = getMultipartRequest(taskId, options, params); | ||
@@ -164,3 +179,3 @@ const task = Task.initTask(taskId, session, options); | ||
task.setTotalUpload(1); | ||
task.setStatus("pending"); | ||
task.setStatus('pending'); | ||
return task; | ||
@@ -188,15 +203,15 @@ } | ||
this._totalUpload = value; | ||
this.notifyPropertyChanged("totalUpload", value); | ||
this.notifyPropertyChanged('totalUpload', value); | ||
} | ||
setUpload(value) { | ||
this._upload = value; | ||
this.notifyPropertyChanged("upload", value); | ||
this.notifyPropertyChanged('upload', value); | ||
} | ||
setStatus(value) { | ||
this._status = value; | ||
this.notifyPropertyChanged("status", value); | ||
this.notifyPropertyChanged('status', value); | ||
} | ||
setDescription(value) { | ||
this._description = value; | ||
this.notifyPropertyChanged("description", value); | ||
this.notifyPropertyChanged('description', value); | ||
} | ||
@@ -210,3 +225,4 @@ cancel() { | ||
function getBinaryRequest(taskId, options, file) { | ||
const request = new net.gotev.uploadservice.BinaryUploadRequest(Application.android.context, taskId, options.url); | ||
const request = new net.gotev.uploadservice.protocols.binary.BinaryUploadRequest(Application.android.context, options.url); | ||
request.setUploadID(taskId); | ||
request.setFileToUpload(file); | ||
@@ -217,7 +233,8 @@ setRequestOptions(request, options); | ||
function getMultipartRequest(taskId, options, params) { | ||
const request = new net.gotev.uploadservice.MultipartUploadRequest(Application.android.context, taskId, options.url); | ||
const request = new net.gotev.uploadservice.protocols.multipart.MultipartUploadRequest(Application.android.context, options.url); | ||
request.setUploadID(taskId); | ||
for (let i = 0; i < params.length; i++) { | ||
const curParam = params[i]; | ||
if (typeof curParam.name === 'undefined') { | ||
throw new Error("You must have a `name` value"); | ||
throw new Error('You must have a `name` value'); | ||
} | ||
@@ -229,4 +246,4 @@ if (typeof curParam.filename === 'undefined') { | ||
let fileName = curParam.filename; | ||
if (fileName.startsWith("~/")) { | ||
fileName = fileName.replace("~/", knownFolders.currentApp().path + "/"); | ||
if (fileName.startsWith('~/')) { | ||
fileName = fileName.replace('~/', knownFolders.currentApp().path + '/'); | ||
} | ||
@@ -236,6 +253,2 @@ const destFileName = curParam.destFilename || fileName.substring(fileName.lastIndexOf('/') + 1, fileName.length); | ||
} | ||
const utf8 = options.utf8; | ||
if (utf8) { | ||
request.setUtf8Charset(); | ||
} | ||
setRequestOptions(request, options); | ||
@@ -245,25 +258,42 @@ return request; | ||
function setRequestOptions(request, options) { | ||
const displayNotificationProgress = typeof options.androidDisplayNotificationProgress === "boolean" ? options.androidDisplayNotificationProgress : true; | ||
if (displayNotificationProgress) { | ||
const uploadNotificationConfig = new net.gotev.uploadservice.UploadNotificationConfig(); | ||
const notificationTitle = typeof options.androidNotificationTitle === "string" ? options.androidNotificationTitle : 'File Upload'; | ||
uploadNotificationConfig.setTitleForAllStatuses(notificationTitle); | ||
if (typeof options.androidRingToneEnabled === "boolean") { | ||
uploadNotificationConfig.setRingToneEnabled(new java.lang.Boolean(options.androidRingToneEnabled)); | ||
} | ||
if (typeof options.androidAutoClearNotification === "boolean") { | ||
uploadNotificationConfig.getCompleted().autoClear = options.androidAutoClearNotification; | ||
uploadNotificationConfig.getCancelled().autoClear = options.androidAutoClearNotification; | ||
uploadNotificationConfig.getError().autoClear = options.androidAutoClearNotification; | ||
} | ||
if (typeof options.androidNotificationChannelID === "string" && options.androidNotificationChannelID) { | ||
uploadNotificationConfig.setNotificationChannelId(options.androidNotificationChannelID); | ||
} | ||
request.setNotificationConfig(uploadNotificationConfig); | ||
const config = new org.nativescript.plugins.background_http.NotificationConfig(); | ||
if (typeof options.androidNotificationChannelID === 'string' && options.androidNotificationChannelID) { | ||
config.setNotificationChannelId(options.androidNotificationChannelID); | ||
} | ||
const autoDeleteAfterUpload = typeof options.androidAutoDeleteAfterUpload === "boolean" ? options.androidAutoDeleteAfterUpload : false; | ||
if (typeof options.androidRingToneEnabled === 'boolean') { | ||
config.setRingToneEnabled(options.androidRingToneEnabled); | ||
} | ||
if (typeof options.androidAutoClearNotification === 'boolean') { | ||
config.setAutoClearNotification(options.androidAutoClearNotification); | ||
} | ||
if (typeof options.androidNotificationOnProgressTitle === 'string') { | ||
config.setOnProgressTitle(options.androidNotificationOnProgressTitle); | ||
} | ||
if (typeof options.androidNotificationOnProgressMessage === 'string') { | ||
config.setOnProgressMessage(options.androidNotificationOnProgressMessage); | ||
} | ||
if (typeof options.androidNotificationOnCompleteTitle === 'string') { | ||
config.setOnCompleteTitle(options.androidNotificationOnCompleteTitle); | ||
} | ||
if (typeof options.androidNotificationOnCompleteMessage === 'string') { | ||
config.setOnCompleteMessage(options.androidNotificationOnCompleteMessage); | ||
} | ||
if (typeof options.androidNotificationOnErrorTitle === 'string') { | ||
config.setOnErrorTitle(options.androidNotificationOnErrorTitle); | ||
} | ||
if (typeof options.androidNotificationOnErrorMessage === 'string') { | ||
config.setOnErrorMessage(options.androidNotificationOnErrorMessage); | ||
} | ||
if (typeof options.androidNotificationOnCancelledTitle === 'string') { | ||
config.setOnCancelledTitle(options.androidNotificationOnCancelledTitle); | ||
} | ||
if (typeof options.androidNotificationOnCancelledMessage === 'string') { | ||
config.setOnCancelledMessage(options.androidNotificationOnCancelledMessage); | ||
} | ||
org.nativescript.plugins.background_http.NotificationConfig.setConfig(request, config); | ||
const autoDeleteAfterUpload = typeof options.androidAutoDeleteAfterUpload === 'boolean' ? options.androidAutoDeleteAfterUpload : false; | ||
if (autoDeleteAfterUpload) { | ||
request.setAutoDeleteFilesAfterSuccessfulUpload(true); | ||
} | ||
const maxRetryCount = typeof options.androidMaxRetries === "number" ? options.androidMaxRetries : undefined; | ||
const maxRetryCount = typeof options.androidMaxRetries === 'number' ? options.androidMaxRetries : undefined; | ||
if (maxRetryCount) { | ||
@@ -281,4 +311,4 @@ request.setMaxRetries(maxRetryCount); | ||
} | ||
request.setMethod(options.method ? options.method : "GET"); | ||
request.setMethod(options.method ? options.method : 'GET'); | ||
} | ||
//# sourceMappingURL=index.android.js.map |
import { EventData } from "@nativescript/core"; | ||
export function init(); | ||
/** | ||
@@ -176,14 +178,54 @@ * Get or create a background download/upload session by id. | ||
/* | ||
* Use this to set if progress notification should be displayed or not. | ||
* Please note that since API26, Android requires developers to use notifications | ||
* when running background tasks. https://developer.android.com/about/versions/oreo/background | ||
* Use this to set the on progress title shown in the Android notifications center. | ||
*/ | ||
androidDisplayNotificationProgress?: boolean; | ||
androidNotificationOnProgressTitle?: string; | ||
/* | ||
* Use this to set the title shown in the Android notifications center. | ||
* Use this to set the on progress message shown in the Android notifications center. | ||
*/ | ||
androidNotificationTitle?: string; | ||
androidNotificationOnProgressMessage?: string; | ||
/* | ||
* Use this to set the on complete title shown in the Android notifications center. | ||
*/ | ||
androidNotificationOnCompleteTitle?: string; | ||
/* | ||
* Use this to set the on complete message shown in the Android notifications center. | ||
*/ | ||
androidNotificationOnCompleteMessage?: string; | ||
/* | ||
* Use this to set the on error title shown in the Android notifications center. | ||
*/ | ||
androidNotificationOnErrorTitle?: string; | ||
/* | ||
* Use this to set the on error message shown in the Android notifications center. | ||
*/ | ||
androidNotificationOnErrorMessage?: string; | ||
/* | ||
* Use this to set the on cancelled title shown in the Android notifications center. | ||
*/ | ||
androidNotificationOnCancelledTitle?: string; | ||
/* | ||
* Use this to set the on cancelled message shown in the Android notifications center. | ||
*/ | ||
androidNotificationOnCancelledMessage?: string; | ||
/* | ||
* Use this to set if files should be deleted automatically after upload | ||
@@ -190,0 +232,0 @@ */ |
import { Observable } from "@nativescript/core"; | ||
import { Request as IRequest } from "."; | ||
export declare function init(): void; | ||
declare class Session implements Session { | ||
@@ -4,0 +5,0 @@ private static _sessions; |
@@ -5,2 +5,3 @@ import { knownFolders, Observable } from "@nativescript/core"; | ||
let zonedOnError = null; | ||
export function init() { } | ||
function onProgress(nsSession, nsTask, sent, expectedTotal) { | ||
@@ -7,0 +8,0 @@ const task = Task.getTask(nsSession, nsTask); |
{ | ||
"name": "@nativescript/background-http", | ||
"version": "5.0.2", | ||
"version": "6.0.0", | ||
"description": "Background upload for iOS and Android", | ||
"main": "index.js", | ||
"main": "index", | ||
"typings": "index.d.ts", | ||
@@ -7,0 +7,0 @@ "nativescript": { |
@@ -1,4 +0,4 @@ | ||
# Nativescript background-http | ||
# @nativescript/background-http | ||
```javascript | ||
```cli | ||
ns plugin add @nativescript/background-http | ||
@@ -11,2 +11,11 @@ ``` | ||
##### Note | ||
Call `init` before the app starts to initialize the http background service | ||
```typescript | ||
import { init } from '@nativescript/background-http'; | ||
init(); | ||
``` | ||
### Uploading files | ||
@@ -16,20 +25,19 @@ | ||
```JavaScript | ||
```javascript | ||
// file path and url | ||
var file = "/some/local/file/path/and/file/name.jpg"; | ||
var url = "https://some.remote.service.com/path"; | ||
var name = file.substr(file.lastIndexOf("/") + 1); | ||
var file = '/some/local/file/path/and/file/name.jpg'; | ||
var url = 'https://some.remote.service.com/path'; | ||
var name = file.substr(file.lastIndexOf('/') + 1); | ||
// upload configuration | ||
var bghttp = require("@nativescript/background-http"); | ||
var session = bghttp.session("image-upload"); | ||
var bghttp = require('@nativescript/background-http'); | ||
var session = bghttp.session('image-upload'); | ||
var request = { | ||
url: url, | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/octet-stream" | ||
}, | ||
description: "Uploading " + name | ||
}; | ||
url: url, | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/octet-stream', | ||
}, | ||
description: 'Uploading ' + name, | ||
}; | ||
``` | ||
@@ -62,26 +70,41 @@ | ||
Name | Type | Description | ||
--- | --- | --- | ||
url | `string` | The request url (e.g.`https://some.remote.service.com/path`). | ||
method | `string` | The request method (e.g. `POST`). | ||
headers | `object` | Used to specify additional headers. | ||
description | `string` | Used to help identify the upload task locally - not sent to the remote server. | ||
utf8 | `boolean` | (Android only/multipart only) If true, sets the charset for the multipart request to UTF-8. Default is false. | ||
androidDisplayNotificationProgress | `boolean` | (Android only) Used to set if progress notifications should be displayed or not. Please note that since API26, Android requires developers to use notifications when running background tasks. https://developer.android.com/about/versions/oreo/background | ||
androidNotificationTitle | `string` | (Android only) Used to set the title shown in the Android notifications center. | ||
androidAutoDeleteAfterUpload | `boolean` | (Android only) Used to set if files should be deleted automatically after upload. | ||
androidMaxRetries | `number` | (Android only) Used to set the maximum retry count. The default retry count is 0. https://github.com/gotev/android-upload-service/wiki/Recipes#backoff | ||
androidAutoClearNotification | `boolean` | (Android only) Used to set if notifications should be cleared automatically upon upload completion. Default is false. Please note that setting this to true will also disable the ringtones. | ||
androidRingToneEnabled | `boolean` | (Android only) Used to set if a ringtone should be played upon upload completion. Default is true. Please note that this flag has no effect when `androidAutoClearNotification` is set to true. | ||
androidNotificationChannelID | `string` | (Android only) Used to set the channel ID for the notifications. | ||
| Name | Type | Description | | ||
| ------------------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| url | `string` | The request url (e.g.`https://some.remote.service.com/path`). | | ||
| method | `string` | The request method (e.g. `POST`). | | ||
| headers | `object` | Used to specify additional headers. | | ||
| description | `string` | Used to help identify the upload task locally - not sent to the remote server. | | ||
| utf8 | `boolean` | (Android only/multipart only) If true, sets the charset for the multipart request to UTF-8. Default is false. | | ||
| androidNotificationOnProgressTitle | `string` | Use this to set the on progress title shown in the Android notifications center. | | ||
| androidNotificationOnProgressMessage | `string` | Use this to set the on progress message shown in the Android notifications center. | | ||
| androidNotificationOnCompleteTitle | `string` | Use this to set the on complete message shown in the Android notifications center. | | ||
| androidNotificationOnCompleteMessage | `string` | Use this to set the on error title shown in the Android notifications center. | | ||
| androidNotificationOnErrorTitle | `string` | Use this to set the on error title shown in the Android notifications center. | | ||
| androidNotificationOnErrorMessage | `string` | Use this to set the on error message shown in the Android notifications center. | | ||
| androidNotificationOnCancelledTitle | `string` | Use this to set the on cancelled title shown in the Android notifications center. | | ||
| androidNotificationOnCancelledMessage | `string` | Use this to set the on cancelled message shown in the Android notifications center. | | ||
| androidAutoDeleteAfterUpload | `boolean` | (Android only) Used to set if files should be deleted automatically after upload. | | ||
| androidMaxRetries | `number` | (Android only) Used to set the maximum retry count. The default retry count is 0. https://github.com/gotev/android-upload-service/wiki/Recipes#backoff | | ||
| androidAutoClearNotification | `boolean` | (Android only) Used to set if notifications should be cleared automatically upon upload completion. Default is false. Please note that setting this to true will also disable the ringtones. | | ||
| androidRingToneEnabled | `boolean` | (Android only) Used to set if a ringtone should be played upon upload completion. Default is true. Please note that this flag has no effect when `androidAutoClearNotification` is set to true. | | ||
| androidNotificationChannelID | `string` | (Android only) Used to set the channel ID for the notifications. | | ||
**Note** :- Android Notification titles/messages can be constructed with one of the following placeholder which will be replaced by the system . | ||
Replaced with the current upload rate/speed `[upload_rate]` | ||
Replaced with the current upload progress `[upload_progress]` | ||
Replaced with the elapsed time `[upload_elapsed_time]` | ||
The task object has the following properties and methods, that can be used to get information about the upload: | ||
Name | Type | Description | ||
--- | --- | --- | ||
upload | `number` | Bytes uploaded. | ||
totalUpload | `number` | Total number of bytes to upload. | ||
status | `string` | One of the following: `error`, `uploading`, `complete`, `pending`, `cancelled`. | ||
description | `string` | The description set in the request used to create the upload task. | ||
cancel()| `void` | Call this method to cancel an upload in progress. | ||
| Name | Type | Description | | ||
| ----------- | -------- | ------------------------------------------------------------------------------- | | ||
| upload | `number` | Bytes uploaded. | | ||
| totalUpload | `number` | Total number of bytes to upload. | | ||
| status | `string` | One of the following: `error`, `uploading`, `complete`, `pending`, `cancelled`. | | ||
| description | `string` | The description set in the request used to create the upload task. | | ||
| cancel() | `void` | Call this method to cancel an upload in progress. | | ||
@@ -158,3 +181,3 @@ ### Handling upload events | ||
>Note: If you are using the iOS simulator then `http://localhost:8080` should be used to upload to the demo server. If you are using an Android emulator, `http://10.0.2.2:8080` should be used instead. | ||
> **Note**: If you are using the iOS simulator then `http://localhost:8080` should be used to upload to the demo server. If you are using an Android emulator, `http://10.0.2.2:8080` should be used instead. | ||
@@ -161,0 +184,0 @@ ## License |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
12
889
183
80182