1
votes

I am able to upload a file on android to a C# web api, using nativescript-camera with nativescript-background-http.

I set the params as follows:

  var params = [{ name: "image", filename: fileUri, mimeType: 'application/octet-stream' }];

...

And send the request:

let request = {
        url: this.API_URL + "/UploadOctetFile",
        method: "POST",
        headers: {
          "Authorization": accessTokenJson,
          "Content-Type": "application/octet-stream",
          "File-Name": imageName
        },  
        description: "{ 'uploading': " + imageName + " }"
      };

      return this.session.multipartUpload(params, request);

In android the fileUri is returned in a fairly straight forward manner:

takePictrue.then((imageAsset: ImageAsset) => {

Then imageAsset.android has the file uri that is needed to send the image. However, for ios, imageAsset.ios is a PHAsset. To get the file URI, I use the following code:

        let manager = PHImageManager.defaultManager()
        let options = new PHImageRequestOptions();
        options.resizeMode = PHImageRequestOptionsResizeMode.Exact;
        options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;

manager.requestImageForAssetTargetSizeContentModeOptionsResultHandler(imageAsset.ios, { width: 2048, height: 1536 }, PHImageContentModeAspectFill, options, function (result, info) { let srcfilePath = info.objectForKey("PHImageFileURLKey").toString(); ... });

In the above: srcfilePath (which I pass as fileUri) is: file:///var/mobile/Media/DCIM/101APPLE/IMG_1902.JPG

The image name is then IMG_1902.JPG

However, this uploads an empty file. I'm guessing that I need to change the fileUri or perhaps I should be using a different method to: requestImageForAssetTargetSizeContentModeOptionsResultHandler.

I have tried the solution suggested here to do:

 let fileUri = image.fileUri.replace("file://","");

and I've tried changing the mime type "mimeType":"image/jpg".

Any ideas are much appreciated.

1
I doubt iOS allows us to access the actual image file, why don't you write the image asset to a temp file and upload that? - Manoj
Thanks. I think you might be right. I will give this a go in the next few days and will let you know. - trees_are_great

1 Answers

0
votes

Sam, this might help. I did the following to handle an iOS user selecting a photo from their gallery for use later in the app (Android is simple and straightforward like in your case, but iOS returns a PHAsset):

import { ImageSource } from "image-source";
import { Image } from "tns-core-modules/ui/image";
import { path, knownFolders } from "tns-core-modules/file-system";

//iOS user picks photo...

const iosImg = new ImageSource();
iosImg.fromAsset(myPHAsset).then(imsr => {
  this.counter += 1; //class property to allow unique filenames
  const folder = knownFolders.documents();
  const path2 = path.join(folder.path, `Image${this.counter}.jpg`);
  const saved = imsr.saveToFile(path2, "jpg");
  const img = new Image();
  img.src = path2;
  this.data.changeImage(img); //Ng service to allow use of image in other components
});

Links: {N} docs

{N} imagepicker #197

{N} imageUpload code