ImagePicker behavior changed in Expo 28 (or earlier)?

I haven’t confirmed if this is the case in Expo 26/ 27, but I can definitely confirm that I see this new behavior in Expo 28 and did not in Expo 25 (last time I played with this functionality extensively).

Anyway, my question is, is it now required that you explicitly ask for permissions for the camera/ camera roll on iOS before pulling up the ImagePicker? Because I was getting “no camera roll permission” errors when I just called the ImagePicker.launchImageLibraryAsync() when running my code in the Expo app using SDK 28. Previously, it would ask for permissions automatically when calling the ImagePicker. Once I added specific code to ask for permissions it worked in Expo 28.

The ImagePicker docs mention requiring permissions for iOS, but I always took that to mean you need to stick them in your app.json. The code example and snack in the docs don’t show requesting the permissions first, and sure enough, when I open the snack and switch it to SDK 28, the request to open the camera roll fails silently.

When I change the snack in ImagePicker documentation to the following, it works on Expo 28:

import React from 'react';
import { Button, Image, View } from 'react-native';
import { ImagePicker, Permissions } from 'expo';

export default class ImagePickerExample extends React.Component {
  state = {
    image: null,
  };

  render() {
    let { image } = this.state;

    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Button
          title="Pick an image from camera roll"
          onPress={this._pickImage}
        />
        {image &&
          <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
      </View>
    );
  }

  _pickImage = async () => {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
    if (status === 'granted') {
      let result = await ImagePicker.launchImageLibraryAsync({
        allowsEditing: true,
        aspect: [4, 3],
      });
      console.log(result);

      if (!result.cancelled) {
        this.setState({ image: result.uri });
      }
    } else {
      throw new Error('Camera roll permission not granted');
    }
  };
}

Anyway, I’m good at the moment (I’m just asking for permissions now), but just wanted to bring it up in case it was a regression and the docs/ example code should work, or if it was intentional and maybe the example needs updating. Thanks!

1 Like

Hey @llamaluvr I’m really glad you were able to figure this out.

For some context, you aren’t the first to bring up this valid concern:

https://github.com/expo/expo/issues/1707

The TLDR:

  • We need to update our example, and could use help on that in the docs if its incorrect.
  • SDK 27 introduced asking for both CAMERA and CAMERA_ROLL permissions, and we weren’t super clear about that.
  • WRITE_EXTERNAL_STORAGE is important if you’re saving photos on the device

Thanks for bearing with us, and sorry we didn’t communicate this super clearly

1 Like

I didn’t realize I could PR the docs (now I see the link). I’ll try to give it a go sometime. Thanks!

2 Likes

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.