Skip to content

Instantly share code, notes, and snippets.

@Aliath
Last active March 24, 2024 15:26
Show Gist options
  • Save Aliath/25dde43cc0e59d3cbaec5b5cbb62100f to your computer and use it in GitHub Desktop.
Save Aliath/25dde43cc0e59d3cbaec5b5cbb62100f to your computer and use it in GitHub Desktop.
Wrapper for the react-native-image-picker and react-native-document-picker. Allow to pick media from gallery on iOS.
import { Platform, ActionSheetIOS } from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import ImagePicker from 'react-native-image-picker';
import RNFS from 'react-native-fs';
type Captions = {
image: string,
document: string,
cancel: string,
title: string,
};
export class AttachmentPicker {
private captions: Captions;
constructor(captions: Captions = { image: 'Image', document: 'Document', cancel: 'Cancel', title: 'Pick type of media' }) {
this.captions = captions;
}
pick = () => {
if (Platform.OS === 'ios') {
return this.pickIOS();
}
return new Promise((resolve, reject) => {
return this.pickDocument(resolve, reject);
});
}
pickIOS = () => {
return new Promise((resolve, reject) => {
const { image, document, cancel, title } = this.captions;
const options = [image, document, cancel];
const handlers = [this.pickImage, this.pickDocument, this.pickClosed];
const cancelButtonIndex = options.indexOf(cancel);
ActionSheetIOS.showActionSheetWithOptions(
{ options, cancelButtonIndex, title },
buttonIndex => { handlers[buttonIndex](resolve, reject); }
);
});
}
pickImage = (resolve: (payload: any) => void, reject: (payload: any) => void) => {
ImagePicker.showImagePicker(response => {
if (response.didCancel) {
reject(new Error('Action cancelled!'));
} else {
const { data: b64Content, type: fileType } = response;
const b64 = `data:${fileType};base64,${b64Content}`;
const fileExtension = String(fileType).substr(String(fileType).indexOf('/') + 1);
resolve({ b64, fileType, fileExtension });
}
});
}
pickDocument = async (resolve: (payload: any) => void, reject: (payload: any) => void) => {
try {
const result = await DocumentPicker.pick({
type: [DocumentPicker.types.images, DocumentPicker.types.pdf]
});
const fileType = result.type;
const fileExtension = fileType.substr(fileType.indexOf('/') + 1);
const realURI = Platform.select({ android: result.uri, ios: decodeURI(result.uri), })
const b64Content = await RNFS.readFile(realURI, "base64")
const b64 = `data:${fileType};base64,${b64Content}`;
resolve({ b64, fileType, fileExtension });
} catch {
reject(new Error('Action cancelled!'));
}
}
pickClosed = (_: any, reject: (payload: any) => void) => {
reject(new Error('Action cancelled!'));
}
}
// example of use:
(async () => {
const attachmentPicker = new AttachmentPicker();
const response = await attachmentPicker.pick();
})();
@Cchumi
Copy link

Cchumi commented Oct 9, 2019

Hi thanks for your wrapper. I have a question...
How to use it ?
I just import It in my component and call ?

Thanks

@Aliath
Copy link
Author

Aliath commented Oct 9, 2019

Yes, create instance of the class and use pick method on it.

@ali-hellani
Copy link

Just one thing to note here that i have faced an issue on ios when picking a document that has spaces in its filename to read it as base64.
I solved it by using this:
const realURI = Platform.select({ android: result.uri, ios: decodeURI(result.uri), })
const b64Content = await RNFS.readFile(realURI, "base64")

@Aliath
Copy link
Author

Aliath commented Oct 19, 2019

Thank you! Corrected. 😄

@ankitsdglobal
Copy link

Hello

is their a simple .js version of this code. It is giving error because of typescript and my project doesn't uses typescript

@Aliath
Copy link
Author

Aliath commented Mar 20, 2020

Hello, nope but as typescript is just superset of js you can compile it straight into pure js.

@sujatha2016
Copy link

do I need to add "react-native-image-picker" to my project to use this ?

@eramudeep
Copy link

Bit confused,
can you please provide a sample code, How to use it.

@Wesleyomnion
Copy link

Thanks man!! you saved me a lot of time

@tylerkrett
Copy link

const realURI = Platform.select({ android: result.uri, ios: decodeURI(result.uri), })

Thanks bro. As I could not fetch the Sha1 due to the path not being valid.

@JB712
Copy link

JB712 commented Dec 13, 2023

Thanks ! Be aware that some adaptations are needed to fit with latest version of the image picker but most of the work is already done ^^

@AdrianKnowde
Copy link

Thanks man, you saved my life! 🥇

@SVN-05
Copy link

SVN-05 commented Mar 1, 2024

thanks for your wrapper code syntax, i modified according to my requirements

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment