diff --git a/README.md b/README.md
index 37830e5..1082bc6 100644
--- a/README.md
+++ b/README.md
@@ -12,10 +12,16 @@ The plugin uses [NSURLSession with background session configuration for iOS](htt
tns plugin add nativescript-background-http
```
+## Breaking Change
+In v5.0 `.uploadFile` and `.multipartUpload` returns a promise with the task instead of a task directly.
+This is to allow ios "assets-library" urls to be uploaded (& easily in future ios PHAsset urls).
+
+
## Usage
The below attached code snippets demonstrate how to use `nativescript-background-http` to upload single or multiple files.
+
### Uploading files
Sample code for configuring the upload session. Each session must have a unique `id`, but it can have multiple tasks running simultaneously. The `id` is passed as a parameter when creating the session (the `image-upload` string in the code bellow):
@@ -23,14 +29,14 @@ Sample code for configuring the upload session. Each session must have a unique
```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);
+const file = "/some/local/file/path/and/file/name.jpg";
+const url = "https://some.remote.service.com/path";
+const name = file.substr(file.lastIndexOf("/") + 1);
// upload configuration
-var bghttp = require("nativescript-background-http");
-var session = bghttp.session("image-upload");
-var request = {
+const bghttp = require("nativescript-background-http");
+const session = bghttp.session("image-upload");
+const request = {
url: url,
method: "POST",
headers: {
@@ -43,23 +49,28 @@ var request = {
For a single file upload, use the following code:
```JavaScript
-var task = session.uploadFile(file, request);
+session.uploadFile(file, request).then( (task) => { /* Do something with Task */ });
```
For multiple files or to pass additional data, use the multipart upload method. All parameter values must be strings:
```JavaScript
-var params = [
+const params = [
{ name: "test", value: "value" },
{ name: "fileToUpload", filename: file, mimeType: "image/jpeg" }
];
-var task = session.multipartUpload(params, request);
+session.multipartUpload(params, request).then( (task) => { /* Do something with Task */ } );
```
In order to have a successful upload, the following must be taken into account:
- the file must be accessible from your app. This may require additional permissions (e.g. access documents and files on the device). Usually this is not a problem - e.g. if you use another plugin to select the file, which already adds the required permissions.
- the URL must not be blocked by the OS. Android Pie or later devices require TLS (HTTPS) connection by default and will not upload to an insecure (HTTP) URL.
+- If you are going to upload or allow uploading assets-library urls on iOS (i.e. URL's received from the Gallery) you need to add the following to your ios's Info.plist file:
+```
+NSPhotoLibraryUsageDescription^M
+Requires access to photo library.^M
+```
### Upload request and task API
@@ -120,7 +131,7 @@ function progressHandler(e) {
// response: net.gotev.uploadservice.ServerResponse (Android) / NSHTTPURLResponse (iOS)
function errorHandler(e) {
alert("received " + e.responseCode + " code.");
- var serverResponse = e.response;
+ let serverResponse = e.response;
}
@@ -138,7 +149,7 @@ function respondedHandler(e) {
// response: net.gotev.uploadservice.ServerResponse (Android) / NSHTTPURLResponse (iOS)
function completeHandler(e) {
alert("received " + e.responseCode + " code");
- var serverResponse = e.response;
+ let serverResponse = e.response;
}
// event arguments:
diff --git a/demo-angular/app/App_Resources/iOS/Info.plist b/demo-angular/app/App_Resources/iOS/Info.plist
index 551c9cc..05ec38e 100644
--- a/demo-angular/app/App_Resources/iOS/Info.plist
+++ b/demo-angular/app/App_Resources/iOS/Info.plist
@@ -48,5 +48,7 @@
NSAllowsArbitraryLoads
+ NSPhotoLibraryUsageDescription
+ Requires access to photo library.
diff --git a/demo-angular/app/home/home.component.ts b/demo-angular/app/home/home.component.ts
index 940ab46..f19be23 100644
--- a/demo-angular/app/home/home.component.ts
+++ b/demo-angular/app/home/home.component.ts
@@ -63,7 +63,7 @@ export class HomeComponent {
request.headers["Should-Fail"] = true;
}
- let task: bgHttp.Task;
+ let taskPromise: Promise;
let lastEvent = "";
if (isMulti) {
const params = [
@@ -72,9 +72,9 @@ export class HomeComponent {
{ name: "bool", value: true },
{ name: "fileToUpload", filename: this.file, mimeType: 'image/jpeg' }
];
- task = this.session.multipartUpload(params, request);
+ taskPromise = this.session.multipartUpload(params, request);
} else {
- task = this.session.uploadFile(this.file, request);
+ taskPromise = this.session.uploadFile(this.file, request);
}
function onEvent(e) {
@@ -97,11 +97,14 @@ export class HomeComponent {
});
}
- task.on("progress", onEvent.bind(this));
- task.on("error", onEvent.bind(this));
- task.on("responded", onEvent.bind(this));
- task.on("complete", onEvent.bind(this));
- lastEvent = "";
- this.tasks.push(task);
+ taskPromise.then( (task: bgHttp.Task) =>
+ {
+ task.on("progress", onEvent.bind(this));
+ task.on("error", onEvent.bind(this));
+ task.on("responded", onEvent.bind(this));
+ task.on("complete", onEvent.bind(this));
+ lastEvent = "";
+ this.tasks.push(task);
+ });
}
}
diff --git a/demo-server/package.json b/demo-server/package.json
old mode 100644
new mode 100755
index 7dcc84a..f9663c8
--- a/demo-server/package.json
+++ b/demo-server/package.json
@@ -5,6 +5,7 @@
"start": "npm i && node server.js 8080"
},
"dependencies": {
+ "formidable": "^1.2.2",
"stream-throttle": "*"
}
}
diff --git a/demo-server/server.js b/demo-server/server.js
old mode 100644
new mode 100755
index 7854c24..a9536df
--- a/demo-server/server.js
+++ b/demo-server/server.js
@@ -1,6 +1,7 @@
var http = require("http");
var fs = require("fs");
var path = require("path");
+var formidable = require('formidable');
function start(port, logger) {
@@ -9,13 +10,33 @@ function start(port, logger) {
try {
var Throttle = require("stream-throttle").Throttle;
+ if (request.headers["content-type"] && request.headers["content-type"].startsWith("multipart/form-data")) {
+ const form = formidable({ multiples: true, uploadDir: outDir, keepExtensions: true });
+ form.parse(request, (err, fields, files) => {
+
+ // Make the files array look nicer...
+ let uploads={};
+ for (let key in files) {
+ uploads[key] = files[key].path;
+ }
+ console.log("Fields", fields, "Files:", uploads);
+ logger.log("Done!");
+
+ var body = "Upload complete!";
+ response.writeHead(200, "Done!", { "Content-Type": "text/plain", "Content-Length": body.length });
+ response.write(body);
+ response.end();
+ });
+ return;
+ }
+
var fileName = request.headers["file-name"];
if (logger) {
logger.log(request.method + "Request! Content-Length: " + request.headers["content-length"] + ", file-name: " + fileName);
logger.dir(request.headers);
}
- var out = path.join(outDir, "upload-" + new Date().getTime() + "-" + fileName);
+ var out = path.join(outDir, "upload-" + new Date().getTime() );
if (logger) {
logger.log("Output in: " + out);
}
@@ -26,7 +47,7 @@ function start(port, logger) {
var shouldFail = request.headers["should-fail"];
// throttle write speed to 4MB/s
- request.pipe(new Throttle({ rate: 1024 * 4096 })).pipe(fs.createWriteStream(out, { flags: 'w', encoding: null, fd: null, mode: 0666 }));
+ request.pipe(new Throttle({ rate: 1024 * 8192 })).pipe(fs.createWriteStream(out, { flags: 'w', encoding: null, fd: null, mode: 0666 }));
request.on('data', function(chunk) {
current += chunk.length;
@@ -45,7 +66,7 @@ function start(port, logger) {
}
} else {
if (logger) {
- logger.log("Data [" + out + "]: " + current + " / " + total + " " + Math.floor(100 * current / total) + "%");
+ //logger.log("Data [" + out + "]: " + current + " / " + total + " " + Math.floor(100 * current / total) + "%");
}
}
});
@@ -93,4 +114,6 @@ exports.start = start;
if (process.argv.length === 3) {
var port = parseInt(process.argv[2]);
start(port, console);
+} else {
+ console.log("Args", process.argv.length);
}
diff --git a/demo-vue/app/App_Resources/iOS/Info.plist b/demo-vue/app/App_Resources/iOS/Info.plist
index 983be97..b3289ba 100644
--- a/demo-vue/app/App_Resources/iOS/Info.plist
+++ b/demo-vue/app/App_Resources/iOS/Info.plist
@@ -52,5 +52,7 @@
NSAllowsArbitraryLoads
+ NSPhotoLibraryUsageDescription
+ Requires access to photo library.
diff --git a/demo-vue/app/components/Home.vue b/demo-vue/app/components/Home.vue
index cdd6984..3eea3d9 100644
--- a/demo-vue/app/components/Home.vue
+++ b/demo-vue/app/components/Home.vue
@@ -87,7 +87,7 @@ export default {
request.headers["Should-Fail"] = true;
}
- let task; // bgHttp.Task;
+ let taskPromise; // Promise
let lastEvent = "";
if (isMulti) {
@@ -97,9 +97,9 @@ export default {
{ name: "bool", value: true },
{ name: "fileToUpload", filename: this.file, mimeType: 'image/jpeg' }
];
- task = this.session.multipartUpload(params, request);
+ taskPromise = this.session.multipartUpload(params, request);
} else {
- task = this.session.uploadFile(this.file, request);
+ taskPromise = this.session.uploadFile(this.file, request);
}
function onEvent(e) {
@@ -124,13 +124,15 @@ export default {
this.$set(this.tasks, this.tasks.indexOf(task), task);
}
- task.on("progress", onEvent.bind(this));
- task.on("error", onEvent.bind(this));
- task.on("responded", onEvent.bind(this));
- task.on("complete", onEvent.bind(this));
- lastEvent = "";
+ taskPromise.then( (task) => {
+ task.on("progress", onEvent.bind(this));
+ task.on("error", onEvent.bind(this));
+ task.on("responded", onEvent.bind(this));
+ task.on("complete", onEvent.bind(this));
+ lastEvent = "";
+ this.tasks.push(task);
+ });
- this.tasks.push(task);
},
onItemLoading(args) {
let label = args.view.getViewById("imageLabel");
diff --git a/demo/app/App_Resources/iOS/Info.plist b/demo/app/App_Resources/iOS/Info.plist
old mode 100644
new mode 100755
index 551c9cc..05ec38e
--- a/demo/app/App_Resources/iOS/Info.plist
+++ b/demo/app/App_Resources/iOS/Info.plist
@@ -48,5 +48,7 @@
NSAllowsArbitraryLoads
+ NSPhotoLibraryUsageDescription
+ Requires access to photo library.
diff --git a/demo/app/home/home-view-model.ts b/demo/app/home/home-view-model.ts
index 07fc797..4594303 100644
--- a/demo/app/home/home-view-model.ts
+++ b/demo/app/home/home-view-model.ts
@@ -63,7 +63,7 @@ export class HomeViewModel extends Observable {
request.headers["Should-Fail"] = true;
}
- let task: bghttp.Task;
+ let taskPromise: Promise;
let lastEvent = "";
if (isMulti) {
const params = [
@@ -72,9 +72,9 @@ export class HomeViewModel extends Observable {
{ name: "bool", value: true },
{ name: "fileToUpload", filename: this.file, mimeType: 'image/jpeg' }
];
- task = this.session.multipartUpload(params, request);
+ taskPromise = this.session.multipartUpload(params, request);
} else {
- task = this.session.uploadFile(this.file, request);
+ taskPromise = this.session.uploadFile(this.file, request);
}
function onEvent(e) {
@@ -97,11 +97,13 @@ export class HomeViewModel extends Observable {
});
}
- task.on("progress", onEvent.bind(this));
- task.on("error", onEvent.bind(this));
- task.on("responded", onEvent.bind(this));
- task.on("complete", onEvent.bind(this));
- lastEvent = "";
- this.tasks.push(task);
+ taskPromise.then( (task: bghttp.Task ) => {
+ task.on("progress", onEvent.bind(this));
+ task.on("error", onEvent.bind(this));
+ task.on("responded", onEvent.bind(this));
+ task.on("complete", onEvent.bind(this));
+ lastEvent = "";
+ this.tasks.push(task);
+ });
}
}
diff --git a/src/.npmignore b/src/.npmignore
old mode 100644
new mode 100755
index 6ab38bf..b852129
--- a/src/.npmignore
+++ b/src/.npmignore
@@ -1,4 +1,5 @@
-scripts/*
+scripts/
+typings/*
*.map
/node_modules
*.ts
@@ -7,4 +8,4 @@ tsconfig.json
*.tgz
/package
/platforms/android/**/*
-!platforms/android/uploadservice-release.aar
\ No newline at end of file
+!platforms/android/uploadservice-release.aar
diff --git a/src/background-http.android.ts b/src/background-http.android.ts
old mode 100644
new mode 100755
index 7ead237..fca0e84
--- a/src/background-http.android.ts
+++ b/src/background-http.android.ts
@@ -149,12 +149,12 @@ class Session {
this._id = id;
}
- public uploadFile(fileUri: string, options: common.Request): Task {
- return Task.create(this, fileUri, options);
+ public uploadFile(fileUri: string, options: common.Request): Promise {
+ return Promise.resolve( Task.create(this, fileUri, options) );
}
- public multipartUpload(params: Array, options: common.Request): Task {
- return Task.createMultiPart(this, params, options);
+ public multipartUpload(params: Array, options: common.Request): Promise {
+ return Promise.resolve( Task.createMultiPart(this, params, options) );
}
get id(): string {
diff --git a/src/background-http.ios.ts b/src/background-http.ios.ts
old mode 100644
new mode 100755
index d40875a..2c0595c
--- a/src/background-http.ios.ts
+++ b/src/background-http.ios.ts
@@ -53,6 +53,88 @@ function onError(session, nsTask, error) {
}
}
+function getAssetData(asset: string, fileHandle: NSFileHandle = null): Promise {
+ let handle = fileHandle, opened = false;
+ const fileName = fileSystemModule.knownFolders.documents().path + "/temp-MPA-" + Math.floor(Math.random() * 100000000000) + ".tmp";
+ if (fileHandle == null) {
+ NSFileManager.defaultManager.createFileAtPathContentsAttributes(fileName, null, null);
+ handle = NSFileHandle.fileHandleForWritingAtPath(fileName);
+ opened = true;
+ } else {
+ handle.seekToEndOfFile();
+ }
+ if (!handle) {
+ return Promise.resolve(null);
+ }
+
+ return new Promise(resolve => {
+
+ // Get the Asset
+ PHPhotoLibrary.requestAuthorization( (status) => {
+ if (status !== PHAuthorizationStatus.Authorized) {
+ return resolve(null);
+ }
+ const nurl = NSURL.URLWithString(asset);
+ const assets = PHAsset.fetchAssetsWithALAssetURLsOptions(NSArray.arrayWithArray([nurl]), null);
+
+ // No Asset matching via PHAsset System, try direct copy then...
+ // This path probably is NEVER hit, but for the sake of completeness, it is included...
+ if (assets.count == 0) {
+ let isWritten = false;
+ if (opened) {
+ handle.closeFile();
+ opened = false;
+ }
+ try {
+ isWritten = NSFileManager.defaultManager.copyItemAtURLToURLError(nurl, NSURL.fileURLWithPath(fileName));
+ } catch (err) {
+ // Do Nothing....
+ }
+ return resolve(isWritten ? fileName : null);
+ }
+
+ if (assets[0].mediaType === PHAssetMediaTypeImage) {
+ const options = PHImageRequestOptions.alloc().init();
+ options.synchronous = true;
+ options.isNetworkAccessAllowed = true;
+ PHImageManager.defaultManager().requestImageDataForAssetOptionsResultHandler(assets[0], options, function (imageData, dataUTI, orientation, info) {
+ handle.writeData(imageData);
+ handle.synchronizeFile();
+ if (opened) {
+ handle.closeFile();
+ }
+ resolve(fileName);
+ });
+
+ } else if (assets[0].mediaType === PHAssetMediaTypeVideo) {
+ const options = PHVideoRequestOptions.alloc().init();
+ options.version = PHVideoRequestOptionsVersionOriginal;
+
+ PHImageManager.defaultManager().requestAVAssetForVideoOptionsResultHandler(assets[0], options, function (asset, audioMix, info) {
+ handle.writeData(NSData.dataWithContentsOfURL(asset.URL));
+ handle.synchronizeFile();
+ if (opened) {
+ handle.closeFile();
+ }
+ resolve(fileName);
+ });
+ } else {
+ if (opened) {
+ handle.closeFile();
+ }
+ let fURL = NSURL.fileURLWithPath(fileName);
+ let written = NSFileManager.defaultManager.copyItemAtURLToURLError(nurl, fURL);
+ if (opened) {
+ opened = false;
+ } else {
+ handle.writeData(NSData.dataWithContentsOfURL(fURL));
+ }
+ resolve(fileName);
+ }
+ });
+ });
+}
+
class BackgroundUploadDelegate extends NSObject implements NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate {
static ObjCProtocols = [NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate];
@@ -152,8 +234,7 @@ class Session implements common.Session {
return this._session;
}
-
- public uploadFile(fileUri: string, options: common.Request): common.Task {
+ public uploadFile(fileUri: string, options: common.Request): Promise {
if (!fileUri) {
throw new Error("File must be provided.");
}
@@ -176,48 +257,79 @@ class Session implements common.Session {
}
let fileURL: NSURL;
- if (fileUri.substr(0, 7) === "file://") {
- // File URI in string format
- fileURL = NSURL.URLWithString(fileUri);
- } else if (fileUri.charAt(0) === "/") {
- // Absolute path with leading slash
- fileURL = NSURL.fileURLWithPath(fileUri);
- }
-
- const newTask = this._session.uploadTaskWithRequestFromFile(request, fileURL);
- newTask.taskDescription = options.description;
- newTask.resume();
- const retTask: common.Task = Task.getTask(this._session, newTask);
- return retTask;
- }
- public multipartUpload(params: any[], options: any): common.Task {
- const MPF = new MultiMultiPartForm();
- 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");
+ const handleUpload = (fileURL: string, deleteAfter: boolean, resolve) => {
+ console.log("In Handle", fileURL);
+ const newTask = this._session.uploadTaskWithRequestFromFile(request, fileURL);
+ newTask.taskDescription = options.description;
+ newTask.resume();
+ const retTask: common.Task = Task.getTask(this._session, newTask);
+ if (deleteAfter) {
+ console.log("Setting Cleanup");
+ (retTask)._fileToCleanup = fileURL;
}
-
- if (curParam.filename) {
- const destFileName = curParam.destFilename || curParam.filename.substring(curParam.filename.lastIndexOf('/') + 1, curParam.filename.length);
- MPF.appendParam(curParam.name, null, curParam.filename, curParam.mimeType, destFileName);
- } else {
- MPF.appendParam(curParam.name, curParam.value);
+ console.log("Done");
+ resolve(retTask);
+ };
+
+ return new Promise( (resolve) => {
+ if (fileUri.startsWith("file://")) {
+ // File URI in string format
+ fileURL = NSURL.URLWithString(fileUri);
+ handleUpload(fileURL, false, resolve);
+ } else if (fileUri.charAt(0) === "/") {
+ // Absolute path with leading slash
+ fileURL = NSURL.fileURLWithPath(fileUri);
+ handleUpload(fileURL, false, resolve);
+ } else if (fileUri.startsWith("assets-library://")) {
+ getAssetData(fileUri).then(fileName => {
+ console.log("Back from GAD", fileName);
+ if (fileName == null) {
+ return resolve(null);
+ }
+ fileURL = NSURL.fileURLWithPath(fileName);
+ handleUpload(fileURL, true, resolve);
+ }).catch(err => {
+ console.log("Error in uploadFile", err);
+ resolve(null);
+ });
}
- }
- const header = MPF.getHeader();
- const uploadFile = MPF.generateFile();
- if (!options.headers) {
- options.headers = {};
- }
- options.headers['Content-Type'] = header['Content-Type'];
+ });
+ }
- const task = this.uploadFile(uploadFile, options);
+ public multipartUpload(params: any[], options: any): Promise {
+ const MPF = new MultiMultiPartForm();
- // Tag the file to be deleted and cleanup after upload
- (task)._fileToCleanup = uploadFile;
- return task;
+ return new Promise( (resolve) => {
+ 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");
+ }
+
+ if (curParam.filename) {
+ const destFileName = curParam.destFilename || curParam.filename.substring(curParam.filename.lastIndexOf('/') + 1, curParam.filename.length);
+ MPF.appendParam(curParam.name, null, curParam.filename, curParam.mimeType, destFileName);
+ } else {
+ MPF.appendParam(curParam.name, curParam.value);
+ }
+ }
+ const header = MPF.getHeader();
+ MPF.generateFile().then( (uploadFileName: string) => {
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers['Content-Type'] = header['Content-Type'];
+
+ this.uploadFile(uploadFileName, options).then(task => {
+ // Tag the file to be deleted and cleanup after upload
+ (task)._fileToCleanup = uploadFileName;
+ resolve(task);
+ });
+ }).catch((err) => {
+ console.log("Error", err, err.stack);
+ });
+ });
}
static getSession(id: string): common.Session {
let jsSession = Session._sessions[id];
@@ -266,6 +378,7 @@ class Task extends Observable {
public _fileToCleanup: string;
private _task: NSURLSessionTask;
private _session: NSURLSession;
+ private _canceled: boolean = false;
constructor(nsSession: NSURLSession, nsTask: NSURLSessionTask) {
super();
@@ -357,54 +470,60 @@ class MultiMultiPartForm {
this.fields.push({ name: name, filename: filename, destFilename: finalName, mimeType: mimeType });
}
- public generateFile(): string {
+ private _appendStringData(stringData: string, fileHandle: NSFileHandle) {
+ const tempString = NSString.stringWithString(stringData);
+ const newData = tempString.dataUsingEncoding(NSUTF8StringEncoding);
+ fileHandle.writeData(newData);
+ }
+
+ public generateFile(): Promise {
const CRLF = "\r\n";
const fileName = fileSystemModule.knownFolders.documents().path + "/temp-MPF-" + Math.floor(Math.random() * 100000000000) + ".tmp";
-
- const combinedData = NSMutableData.alloc().init();
-
- let results: string = "";
- let tempString: NSString;
- let newData: any;
- for (let i = 0; i < this.fields.length; i++) {
- results += "--" + this.boundary + CRLF;
- results += 'Content-Disposition: form-data; name="' + this.fields[i].name + '"';
- if (!this.fields[i].filename) {
- results += CRLF + CRLF + this.fields[i].value + CRLF;
- } else {
- results += '; filename="' + this.fields[i].destFilename + '"';
- if (this.fields[i].mimeType) {
- results += CRLF + "Content-Type: " + this.fields[i].mimeType;
+ NSFileManager.defaultManager.createFileAtPathContentsAttributes(fileName, null, null);
+ let handle = NSFileHandle.fileHandleForWritingAtPath(fileName);
+
+ return new Promise( async (resolve) => {
+ let results = "";
+ for (let i = 0; i < this.fields.length; i++) {
+ results += "--" + this.boundary + CRLF;
+ results += 'Content-Disposition: form-data; name="' + this.fields[i].name + '"';
+ if (!this.fields[i].filename) {
+ results += CRLF + CRLF + this.fields[i].value + CRLF;
+ } else {
+ results += '; filename="' + this.fields[i].destFilename + '"';
+ if (this.fields[i].mimeType) {
+ results += CRLF + "Content-Type: " + this.fields[i].mimeType;
+ }
+ results += CRLF + CRLF;
}
- results += CRLF + CRLF;
- }
-
- tempString = NSString.stringWithString(results);
- results = "";
- newData = tempString.dataUsingEncoding(NSUTF8StringEncoding);
- combinedData.appendData(newData);
+ this._appendStringData(results, handle);
+ results = "";
+
+ if (this.fields[i].filename) {
+ if (this.fields[i].filename.startsWith("assets-library://")) {
+ await getAssetData(this.fields[i].filename, handle);
+ } else {
+ const fileData = NSData.alloc().initWithContentsOfFile(this.fields[i].filename);
+ handle.writeData(fileData);
+ }
+ results = CRLF;
+ }
- if (this.fields[i].filename) {
- const fileData = NSData.alloc().initWithContentsOfFile(this.fields[i].filename);
- combinedData.appendData(fileData);
- results = CRLF;
}
+ // Add final part of it...
+ results += "--" + this.boundary + "--" + CRLF;
+ this._appendStringData(results, handle);
+ handle.closeFile();
- }
- // Add final part of it...
- results += "--" + this.boundary + "--" + CRLF;
- tempString = NSString.stringWithString(results);
- newData = tempString.dataUsingEncoding(NSUTF8StringEncoding);
- combinedData.appendData(newData);
-
- NSFileManager.defaultManager.createFileAtPathContentsAttributes(fileName, combinedData, null);
-
- return fileName;
+ resolve(fileName);
+ });
}
public getHeader(): string {
return this.header;
}
}
+
+
diff --git a/src/index.d.ts b/src/index.d.ts
old mode 100644
new mode 100755
index 9e66108..a99300e
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -135,8 +135,8 @@ export interface Session {
* @param fileUri A file path to upload.
* @param options Options for the upload, sets uri, headers, task description etc.
*/
- uploadFile(fileUri: string, options: Request): Task;
- multipartUpload(params: Array, options: Request): Task;
+ uploadFile(fileUri: string, options: Request): Promise;
+ multipartUpload(params: Array, options: Request): Promise;
}