0

Hello I am attempting to access the user photo album on iOS in order for users to select a profile pic in my app.

I am using native script and I cannot figure out how to request permission to do so. My error is:

 CONSOLE LOG file:///app/shared/user-view-model/user-view-model.js:96:28: fileUri: file:///var/mobile/Media/DCIM/100APPLE/IMG_0002.JPG
    CONSOLE LOG file:///app/shared/user-view-model/user-view-model.js:101:24: NSErrorWrapper: You don’t have permission to save the file “100APPLE” in the folder “DCIM”.

I used

<key>NSPhotoLibraryUsageDescription</key>
<string> ${PRODUCT_NAME} photo use</string>

in my info.plist but no luck. Does anybody know what I'm missing?

var frame = require("ui/frame");
var platform = require("platform");
var firebase = require("nativescript-plugin-firebase");
var page;
var list;

function pageLoaded(args) {
    page = args.object;
    list = page.getViewById("urls-list");
}
exports.pageLoaded = pageLoaded;

function onSelectMultipleTap(args) {
    var imagepicker = require("nativescript-imagepicker");
    var context = imagepicker.create({
        mode: "multiple"
    });
    startSelection(context);
}
exports.onSelectMultipleTap = onSelectMultipleTap;

function onSelectSingleTap(args) {
    var imagepicker = require("nativescript-imagepicker");
    var context = imagepicker.create({
        mode: "single"
    });
    startSelection(context);
}
exports.onSelectSingleTap = onSelectSingleTap;

function startSelection(context) {
    context
        .authorize()
        .then(function() {
            list.items = [];
            return context.present();
        })
        .then(function(selection) {
            console.log("Selection done:");
            selection.forEach(function(selected) {
                console.log("----------------");
                console.log("uri: " + selected.uri);
                console.log("fileUri: " + selected.fileUri);
                uploadImage(selected.fileUri);
            });
            list.items = selection;
        }).catch(function (e) {
            console.log(e);
        });
}

function uploadImage(imageUrl){
  firebase.uploadFile({
    remoteFullPath: "test/testimage.jpg",
    localFullPath: imageUrl,
     onProgress: function(status) {
      console.log("Uploaded fraction: " + status.fractionCompleted);
      console.log("Percentage complete: " + status.percentageCompleted);
    }
  }).then((success) => {
    console.log("success: " + success);
  }, (error) => {
    console.log("Error: " + error);
  })
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
xerotolerant
  • 1,955
  • 4
  • 21
  • 39
  • Can you please post some more code? And have you tried this plugin https://www.npmjs.com/package/nativescript-imagepicker – Dean Le Oct 10 '16 at 06:41
  • you could also review this example - https://github.com/NativeScript/sample-ImageUpload , where has been used the above suggested plugin - `nativescript-imagepicker` – Nikolay Tsonev Oct 10 '16 at 07:59
  • Hello I updated the post to include more code. I am using the image picker. I am also using it in conjunction with nativescript-plugin-firebase. As far as I can tell I am doing everything exactly as they are, I get the thumbnail as in the example. When it comes to uploading the image however it just fails with the error above. – xerotolerant Oct 10 '16 at 13:31

2 Answers2

1

You need this requestAuthorization

PHPhotoLibrary.requestAuthorization(function (result) {
    if (result === PHAuthorizationStatus.PHAuthorizationStatusAuthorized) {
        // OK
    } else {
        // no permissions!
    }
});

You also need this in your info.plist

<dict>
    <key>NSPhotoLibraryUsageDescription</key>
    <string></string>
</dict>
Nick Iliev
  • 9,610
  • 3
  • 35
  • 89
  • Thanks but do you have any idea how to do this using nativescript? – xerotolerant Oct 10 '16 at 13:40
  • That's native code taht can be used in NativeScript application. If you are using TypeScript you will need to install tns-platform-declarations.. if you are using vanilla JavaScript then you can copy/paste directly where needed. The info.plist is in app/App_Resources/iOS/ – Nick Iliev Oct 10 '16 at 13:44
  • Here is the real-life example usage in the imagepicker plugin (a bit complicated to be used with promises and looper) https://github.com/NativeScript/nativescript-imagepicker/blob/release/source/viewmodel.ios.ts#L249 – Nick Iliev Oct 10 '16 at 13:46
  • I have never been able to use tns-platform declarations for some impossible to understand reason. I installed it via npm for example but there is no "ios.d.ts" anywhere in the package even though every article I could find references it. Also I used the `imagepicker.authorize() ` which as far as I could tell does nothing. I'm going to try to get the platform declarations working and see what's what. – xerotolerant Oct 10 '16 at 14:01
  • To use tns-platform-declarations use one of the following solutions described here : https://github.com/NativeScript/NativeScript/issues/2541#issuecomment-251056341 (either the 2.2.0 solution or the "next") – Nick Iliev Oct 10 '16 at 14:06
  • 1
    Ok thanks I got the declarations in. When I run the function you recommended I'm getting that the authorization was successful but the same error occurs when attempting the upload. I think your suggestion has me on the correct path because I didn't know how to access native stuff. If I use the url directly instead of using the file-system module to fetch the file I get the same error as in [this post](http://stackoverflow.com/questions/37670009/obtain-nsurl-from-uiimagepickercontroller?noredirect=1&lq=1) – xerotolerant Oct 10 '16 at 14:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/125369/discussion-between-xerotolerant-and-nick-iliev). – xerotolerant Oct 10 '16 at 20:05
  • @xerotolerant were you able to find a solution to this problem? – Muhammad bin Yusrat Jun 11 '19 at 10:39
0

I found a solution from this github post

https://github.com/NativeScript/sample-ImageUpload/issues/2#issuecomment-252795778

The solution was to use the getImage() method and then saveToFile method on the result.

private selectImage(context){
    context.authorize()
      .then(() => {return context.present()})
      .then((selection) => {
        selection.forEach((selected) => {
          selected.getImage()
            .then((imageSource) => {
              var appPath = fs.knownFolders.currentApp().path;
              var profilePath = "/img/profile.jpg";
              var filePath = fs.path.join(appPath, profilePath);
              var saved = imageSource.saveToFile(filePath, enums.ImageFormat.jpeg);
              console.log(`item saved:${saved}`);
              console.log("FilePath: " + filePath);
              console.log("Image source " + JSON.stringify(imageSource));
            },
            (error) => {
              console.log("error");
            })
        })
      })
  }
xerotolerant
  • 1,955
  • 4
  • 21
  • 39