@angelengineering/filepicker
Version:
File Picker plugin for Nativescript applications
601 lines • 28.8 kB
JavaScript
/* eslint-disable no-var */
import { MediaType } from './index.common';
import { Application, File, ImageAsset, ImageSource } from '@nativescript/core';
import { iOSNativeHelper } from '@nativescript/core/utils';
import { AssetDownloader, TempFile } from './files';
export { MediaType } from './index.common';
let _iosDocumentPickerController;
let _iosGalleryPickerController;
let _iosPHPickerController; //for iOS<14 we use UIImagePicker. ios14+ uses PHPicker
/**
* @function galleryPicker
* Present a Photos gallery picker filtered by MediaType and using single or multiple selection mode. Note: Android will just call showPicker currently.
* @param {MediaType} type OR'ed from all possible MediaType's to describe types of files allowed in selection
* @param {boolean} multiple if multiple selections are allowed
* @returns {Promise<File[]>} Promise<File[]> Returns an array of Photos gallery files selected by user.
*/
export function galleryPicker(type, multiple) {
//NOTE: iOS 14+ adds new photo/video gallery privacy access restrictions for UIImagePicker, and introduces
// the new PHPicker component which doesn't requires perms and supports multiple selections.
if (+iOSNativeHelper.MajorVersion >= 14) {
return PHPicker(type, multiple);
}
//gallery UIImage Picker version(images and video) for ios<14
//NOTE: the iOS UIImagePickerController does not allow multiple selections
else {
if (multiple)
console.warn('iOS UIImagePickerController only allows single selections!');
return ImgPicker(type);
}
}
/**
* @function getFreeMBs
* Returns the number of megabytes free on file system containing the filepath
* @param {string} filepath full filepath on device
*/
export function getFreeMBs(filepath) {
//iOS devices only have a single storage partition to work with, so we can use any path to check stats
const attributeDictionary = NSFileManager.defaultManager.attributesOfFileSystemForPathError(filepath);
// let totalsize: number = +attributeDictionary.valueForKey(NSFileSystemSize) / (1024 * 1024);
const freesize = +attributeDictionary.valueForKey(NSFileSystemFreeSize) / (1024 * 1024);
return freesize;
}
/**
* @function PHPicker
* Present a Photos gallery picker filtered by MediaType and using single or multiple selection mode. Note: Android will just call showPicker currently.
* Note: This is used by galleryPicker for iOS 14+
* @param {MediaType} type OR'ed from all possible MediaType's to describe types of files allowed in selection
* @param {boolean} multiple if multiple selections are allowed
* @returns {Promise<File[]>} Promise<File[]> Returns an array of Photos gallery files selected by user.
*/
function PHPicker(type, multiple) {
return new Promise((resolve, reject) => {
const config = PHPickerConfiguration.new();
config.selectionLimit = multiple ? 0 : 1;
config.filter = PHPickerFilter.anyFilterMatchingSubfilters(iOSNativeHelper.collections.jsArrayToNSArray(getPHTypes(type)));
_iosPHPickerController = new PHPickerViewController({ configuration: config });
const delegate = PHPickerViewControllerDelegateImpl.new().initWithCallbackAndOptions(resolve, reject, this);
delegate.registerToGlobal();
_iosPHPickerController.delegate = delegate;
Application.ios.rootController.presentViewControllerAnimatedCompletion(_iosPHPickerController, true, null);
});
}
/**
* @function ImgPicker
* Present a Photos gallery picker filtered by MediaType and using single or multiple selection mode. Note: Android will just call showPicker currently.
* Note: This is used by galleryPicker for iOS <14
* @param {MediaType} type OR'ed from all possible MediaType's to describe types of files allowed in selection
* @param {boolean} multiple if multiple selections are allowed
* @returns {Promise<File[]>} Promise<File[]> Returns an array of Photos gallery files selected by user.
*/
function ImgPicker(type) {
return new Promise((resolve, reject) => {
_iosGalleryPickerController = UIImagePickerController.new();
const mediaTypes = iOSNativeHelper.collections.jsArrayToNSArray(getMediaTypes(type));
_iosGalleryPickerController.mediaTypes = mediaTypes;
//image/video editing not allowed for now as we would need to process changes manually before returning media
_iosGalleryPickerController.allowsEditing = false;
_iosGalleryPickerController.allowsImageEditing = false;
const delegate = UIImagePickerControllerDelegateImpl.new().initWithCallbackAndOptions(resolve, reject, this);
delegate.registerToGlobal();
_iosGalleryPickerController.delegate = delegate;
Application.ios.rootController.presentViewControllerAnimatedCompletion(_iosGalleryPickerController, true, null);
});
}
/**
* @function filePicker
* Present a system picker filtered by MediaType and using single or multiple selection mode..
* @param {MediaType} type OR'ed from all possible MediaType's to describe types of files allowed in selection
* @param {boolean} multiple if multiple selections are allowed
* @returns {Promise<File[]>} Promise<File[]> returns an array of Files selected by user
*/
export function filePicker(type, multiple) {
return new Promise((resolve, reject) => {
const mediaTypes = iOSNativeHelper.collections.jsArrayToNSArray(getMediaTypes(type));
_iosDocumentPickerController = UIDocumentPickerViewController.alloc().initWithDocumentTypesInMode(mediaTypes, 0 /* UIDocumentPickerMode.Import */
//Import mode is less restrictive than Open and doesn't require a file coordinator
);
// This picker does allow multiple selections if user chooses selection view
_iosDocumentPickerController.allowsMultipleSelection = multiple;
// This doesn't actually show extensions, but we'll set it anyway
_iosDocumentPickerController.shouldShowFileExtensions = true;
// If fullscreen style is used, delegate return handler throws an access error
// If CurrentContext or others are used, delegate methods are never called
_iosDocumentPickerController.modalPresentationStyle = 2 /* UIModalPresentationStyle.FormSheet */;
const delegate = UIDocumentPickerDelegateImpl.new().initWithCallbackAndOptions(resolve, reject, this);
delegate.registerToGlobal();
_iosDocumentPickerController.delegate = delegate;
Application.ios.rootController.presentViewControllerAnimatedCompletion(_iosDocumentPickerController, true, null);
});
}
var UIDocumentPickerDelegateImpl = /** @class */ (function (_super) {
__extends(UIDocumentPickerDelegateImpl, _super);
function UIDocumentPickerDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
UIDocumentPickerDelegateImpl.new = function () {
return _super.new.call(this);
};
UIDocumentPickerDelegateImpl.prototype.initWithCallbackAndOptions = function (callback, errorCallback, owner) {
this._resolve = callback;
this._reject = errorCallback;
this._owner = owner;
return this;
};
//Need to maintain a reference otherwise iOS tends to clean it up when leaving app to launch picker
UIDocumentPickerDelegateImpl.prototype.registerToGlobal = function () {
global.documentPickerDelegate = this;
};
UIDocumentPickerDelegateImpl.prototype.deRegisterFromGlobal = function () {
global.documentPickerDelegate = null;
};
UIDocumentPickerDelegateImpl.prototype.owner = function () {
if (!this._owner)
return null;
return this._owner.get();
};
// if only single selection is allowed? sometimes, usually the next one handles all returns
UIDocumentPickerDelegateImpl.prototype.documentPickerDidPickDocumentAtURL = function (controller, url) {
var access = url.startAccessingSecurityScopedResource();
var tmppath = TempFile.getPath('asset', '.tmp');
File.fromPath(tmppath).removeSync();
var success = NSFileManager.defaultManager.copyItemAtPathToPathError(url.path, tmppath);
var file = File.fromPath(tmppath);
// persist original file name and extension in tmp file
var originalFilename = url.lastPathComponent;
var newPath = tmppath.replace(/\/[^/]+$/, "/".concat(originalFilename));
if (File.exists(newPath)) {
// remove file if it exists
File.fromPath(newPath).removeSync();
}
// add originalFilename property
file['originalFilename'] = originalFilename;
// update name so uploaded file will have the same name as the original file
file.renameSync(originalFilename);
url.stopAccessingSecurityScopedResource();
controller.dismissViewControllerAnimatedCompletion(true, null);
this._resolve([file]);
this.deRegisterFromGlobal();
};
//if multiple selections allowed:
UIDocumentPickerDelegateImpl.prototype.documentPickerDidPickDocumentsAtURLs = function (controller, urls) {
var files = [];
//This view can't display an UIActivityIndicatorView inside it using the usual ios spinner approach,
// but picker shows a small spinner on the "Open" button while processing
//Process picker results
for (var i = 0; i < urls.count; i++) {
var url = urls.objectAtIndex(i); //urls[0];
var access = url.startAccessingSecurityScopedResource();
//can't access directly, need to copy first to local app directory
var tmppath = TempFile.getPath('asset', '.tmp');
File.fromPath(tmppath).removeSync();
var suc = NSFileManager.defaultManager.copyItemAtPathToPathError(url.path, tmppath);
var file = File.fromPath(tmppath);
// persist original file name and extension in tmp file
var originalFilename = url.lastPathComponent;
var newPath = tmppath.replace(/\/[^/]+$/, "/".concat(originalFilename));
if (File.exists(newPath)) {
// remove file if it exists
File.fromPath(newPath).removeSync();
}
// add originalFilename property
file['originalFilename'] = originalFilename;
// update name so uploaded file will have the same name as the original file
file.renameSync(originalFilename);
files.push(file);
if (access)
url.stopAccessingSecurityScopedResource();
}
controller.dismissViewControllerAnimatedCompletion(true, null);
this._resolve(files);
this.deRegisterFromGlobal();
};
UIDocumentPickerDelegateImpl.prototype.documentPickerWasCancelled = function (controller) {
controller.dismissViewControllerAnimatedCompletion(true, null);
this._reject(null);
this.deRegisterFromGlobal();
};
UIDocumentPickerDelegateImpl.ObjCProtocols = [UIDocumentPickerDelegate];
return UIDocumentPickerDelegateImpl;
}(NSObject));
var UIImagePickerControllerDelegateImpl = /** @class */ (function (_super) {
__extends(UIImagePickerControllerDelegateImpl, _super);
function UIImagePickerControllerDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
UIImagePickerControllerDelegateImpl.new = function () {
return _super.new.call(this);
};
UIImagePickerControllerDelegateImpl.prototype.initWithCallbackAndOptions = function (callback, errorCallback, owner) {
this._resolve = callback;
this._reject = errorCallback;
this._owner = owner;
return this;
};
//Need to maintain a reference otherwise iOS tends to clean it up when leaving app to launch picker
UIImagePickerControllerDelegateImpl.prototype.registerToGlobal = function () {
global.galleryPickerDelegate = this;
};
UIImagePickerControllerDelegateImpl.prototype.deRegisterFromGlobal = function () {
global.galleryPickerDelegate = null;
};
UIImagePickerControllerDelegateImpl.prototype.owner = function () {
if (!this._owner)
return null;
return this._owner.get();
};
//returns media item picked from gallery
UIImagePickerControllerDelegateImpl.prototype.imagePickerControllerDidFinishPickingMediaWithInfo = function (picker, info) {
var _this = this;
if (info) {
//This view can't display an UIActivityIndicatorView inside it using the usual ios spinner approach,
// but picker shows a progress indicator when preparing video media, and images return almost instantly
var asset = info.valueForKey(UIImagePickerControllerPHAsset);
var downloader = new AssetDownloader(asset);
downloader.download().then(function (res) {
_this._resolve([res]); //returns a NS file object although filename will be of form assset???.tmp, but has originalFilename attached
});
}
else {
this._reject();
}
if (!!picker && !!picker.presentingViewController)
picker.presentingViewController.dismissViewControllerAnimatedCompletion(true, null);
this.deRegisterFromGlobal();
};
//this should never be called unless we enable editing for ios gallery selections
UIImagePickerControllerDelegateImpl.prototype.imagePickerControllerDidFinishPickingImageEditingInfo = function (picker, image, editingInfo) {
console.warn('WARNING: image picker editing feature has not yet been fully implemented!');
if (!!picker && !!picker.presentingViewController)
picker.presentingViewController.dismissViewControllerAnimatedCompletion(true, null);
this._reject();
this.deRegisterFromGlobal();
};
UIImagePickerControllerDelegateImpl.prototype.imagePickerControllerDidCancel = function (picker) {
if (!!picker && !!picker.presentingViewController)
picker.presentingViewController.dismissViewControllerAnimatedCompletion(true, null);
this._reject();
this.deRegisterFromGlobal();
};
UIImagePickerControllerDelegateImpl.ObjCProtocols = [UIImagePickerControllerDelegate];
return UIImagePickerControllerDelegateImpl;
}(NSObject));
var PHPickerViewControllerDelegateImpl = /** @class */ (function (_super) {
__extends(PHPickerViewControllerDelegateImpl, _super);
function PHPickerViewControllerDelegateImpl() {
return _super !== null && _super.apply(this, arguments) || this;
}
PHPickerViewControllerDelegateImpl.new = function () {
return _super.new.call(this);
};
PHPickerViewControllerDelegateImpl.prototype.initWithCallbackAndOptions = function (callback, errorCallback, owner) {
this._resolve = callback;
this._reject = errorCallback;
this._owner = owner;
return this;
};
//Need to maintain a reference otherwise iOS tends to clean it up when leaving app to launch picker
PHPickerViewControllerDelegateImpl.prototype.registerToGlobal = function () {
global.documentPickerDelegate = this;
};
PHPickerViewControllerDelegateImpl.prototype.deRegisterFromGlobal = function () {
global.documentPickerDelegate = null;
};
PHPickerViewControllerDelegateImpl.prototype.owner = function () {
if (!this._owner)
return null;
return this._owner.get();
};
//returns media items picked from gallery
PHPickerViewControllerDelegateImpl.prototype.pickerDidFinishPicking = function (picker, results) {
var files = [];
var waitCount = results.count;
var errorCount = 0;
if (results) {
//show activity indicator while processing selections
var currentView = picker.view;
var loaderView = UIView.alloc().initWithFrame(CGRectMake(0, 0, 90, 90));
loaderView.center = currentView.center;
loaderView.layer.cornerRadius = 4;
loaderView.backgroundColor = UIColor.lightGrayColor;
var indicator = UIActivityIndicatorView.alloc().initWithActivityIndicatorStyle(UIActivityIndicatorViewStyle.WhiteLarge);
indicator.center = CGPointMake(45, 45);
loaderView.addSubview(indicator);
currentView.addSubview(loaderView);
indicator.startAnimating();
//process picker results, but warn user if a livePhoto is selected as those are not yet supported
for (var i = 0; i < results.count; i++) {
var pickerresult = results.objectAtIndex(i);
var typeIdentifier = pickerresult.itemProvider.registeredTypeIdentifiers.firstObject;
//special handling for Live Photo Bundles of an heic and a mov file (if user selects loop in their Gallery app, then these will become animated gifs)
if (typeIdentifier == 'com.apple.live-photo-bundle') {
pickerresult.itemProvider.loadObjectOfClassCompletionHandler(PHLivePhoto.class(), function (livePhoto, err) {
if (err) {
console.error(err.description);
errorCount++;
waitCount--;
}
else {
var resources = PHAssetResource.assetResourcesForLivePhoto(livePhoto);
var photo = resources.firstObject;
var originalFilename_1 = photo.originalFilename;
var imageData_1 = NSMutableData.alloc().init();
var options = PHAssetResourceRequestOptions.alloc().init();
PHAssetResourceManager.defaultManager().requestDataForAssetResourceOptionsDataReceivedHandlerCompletionHandler(photo, options, function (data) {
imageData_1.appendData(data);
}, function (err) {
if (err) {
console.error(err.description);
waitCount--;
errorCount++;
}
else {
var image = new UIImage({ data: imageData_1, scale: 1 });
var imageAsset = new ImageAsset(image);
var tmppath_1 = TempFile.getPath('asset', '.tmp');
File.fromPath(tmppath_1).removeSync();
ImageSource.fromAsset(imageAsset).then(function (source) {
source.saveToFile(tmppath_1, 'jpeg', 0.95);
var file = File.fromPath(tmppath_1);
var newPath = tmppath_1.replace(/\/[^/]+$/, "/".concat(originalFilename_1));
if (File.exists(newPath)) {
File.fromPath(newPath).removeSync();
}
file.renameSync(originalFilename_1);
files.push(file);
waitCount--;
});
}
});
}
});
}
else {
pickerresult.itemProvider.loadFileRepresentationForTypeIdentifierCompletionHandler(typeIdentifier, function (result, err) {
if (result) {
//copy this to somewhere app has access to
var tmppath = TempFile.getPath('asset', '.tmp');
File.fromPath(tmppath).removeSync();
var suc = NSFileManager.defaultManager.copyItemAtPathToPathError(result.path, tmppath);
var file = File.fromPath(tmppath);
// persist original file name and extension in tmp file
var originalFilename = result.lastPathComponent;
var newPath = tmppath.replace(/\/[^/]+$/, "/".concat(originalFilename));
if (File.exists(newPath)) {
// remove file if it exists
File.fromPath(newPath).removeSync();
}
// add originalFilename property
file['originalFilename'] = originalFilename;
// update name so uploaded file will have the same name as the original file
file.renameSync(originalFilename);
files.push(file);
}
if (err) {
console.error(err.description);
errorCount++;
}
waitCount--;
});
}
}
// eslint-disable-next-line no-inner-declarations
function waitForComplete(delegate) {
if (waitCount > 0) {
setTimeout(function () { return waitForComplete(delegate); }, 500);
}
else {
if (!!picker && !!picker.presentingViewController)
picker.presentingViewController.dismissViewControllerAnimatedCompletion(true, null);
delegate._resolve(files);
delegate.deRegisterFromGlobal();
if (errorCount > 0)
console.warn("Unable to select ".concat(errorCount, "? selections from your device"));
}
}
waitForComplete(this);
}
else {
this._reject();
this.deRegisterFromGlobal();
}
};
PHPickerViewControllerDelegateImpl.ObjCProtocols = [+iOSNativeHelper.MajorVersion >= 14 ? PHPickerViewControllerDelegate : UIImagePickerControllerDelegate];
return PHPickerViewControllerDelegateImpl;
}(NSObject));
// used to configure media types for PHPicker
function getPHTypes(type) {
let fileTypes = [];
if (type & MediaType.VIDEO) {
fileTypes = fileTypes.concat(PHPickerFilter.videosFilter);
}
if (type & MediaType.IMAGE) {
fileTypes = fileTypes.concat(PHPickerFilter.imagesFilter);
}
return fileTypes;
}
// used to configure media types for UIImagePicker
function getMediaTypes(type) {
let fileTypes = [];
if (type & MediaType.AUDIO) {
fileTypes = fileTypes.concat(MediaFileTypes[MediaType.AUDIO]);
}
if (type & MediaType.VIDEO) {
fileTypes = fileTypes.concat(MediaFileTypes[MediaType.VIDEO]);
}
if (type & MediaType.IMAGE) {
fileTypes = fileTypes.concat(MediaFileTypes[MediaType.IMAGE]);
}
if (type & MediaType.DOCUMENT) {
fileTypes = fileTypes.concat(MediaFileTypes[MediaType.DOCUMENT]);
}
if (type & MediaType.ARCHIVE) {
fileTypes = fileTypes.concat(MediaFileTypes[MediaType.ARCHIVE]);
}
return fileTypes;
}
// iOS File types for file picker
//https://developer.apple.com/library/archive/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
//https://escapetech.eu/manuals/qdrop/uti.html
//node_modules/@nativescript/types-ios/lib/ios/objc-x86_64/objc!CoreServices.d.ts
var MediaFileTypes = {
[MediaType.AUDIO]: [
kUTTypeMP3,
kUTTypeMPEG4Audio,
kUTTypeAudio,
kUTTypeAudioInterchangeFileFormat,
kUTTypeAppleProtectedMPEG4Audio,
kUTTypeMIDIAudio,
kUTTypeWaveformAudio,
'public.aifc-audio',
'public.aiff-audio',
'com.microsoft.waveform-audio',
'com.microsoft.windows-media-wma',
'public.audio',
'public.ulaw-audio',
'com.apple.coreaudio-format',
'public.ogg-audio',
],
[MediaType.IMAGE]: [
kUTTypeImage,
kUTTypeBMP,
kUTTypeGIF,
kUTTypeJPEG,
kUTTypeJPEG2000,
kUTTypePNG,
kUTTypeQuickTimeImage,
kUTTypeRawImage,
kUTTypeScalableVectorGraphics,
kUTTypeTIFF,
'public.image',
'public.camera-raw-image',
kUTTypePICT,
kUTTypeAppleICNS,
kUTTypeICO,
kUTTypeLivePhoto,
'com.apple.private.auto-loop-gif',
],
[MediaType.VIDEO]: [
kUTTypeVideo,
kUTTypeMovie,
kUTTypeAudiovisualContent,
kUTTypeAVIMovie,
kUTTypeAppleProtectedMPEG4Video,
kUTTypeMPEG,
kUTTypeMPEG2TransportStream,
kUTTypeMPEG2Video,
kUTTypeMPEG4,
kUTTypeQuickTimeMovie,
'public.movie',
'public.audiovisual-content',
'public.avi',
'public.3gpp',
'public.3gpp2',
],
[MediaType.DOCUMENT]: [
kUTTypePDF,
kUTTypeText,
kUTTypePlainText,
kUTTypeUTF8PlainText,
kUTTypeUTF16ExternalPlainText,
kUTTypeUTF16PlainText,
kUTTypeUTF8TabSeparatedText,
kUTTypePresentation,
kUTTypeRTF,
kUTTypeRTFD,
kUTTypeSpreadsheet,
kUTTypeHTML,
kUTTypeXML,
kUTTypeSourceCode,
'com.microsoft.word.doc',
'com.microsoft.word.docx',
'org.openxmlformats.wordprocessingml.document',
'com.microsoft.powerpoint.ppt',
'com.microsoft.powerpoint.pptx',
'org.openxmlformats.presentationml.presentation',
'public.rtf',
'com.adobe.postscript',
'com.adobe.encapsulated-postscript',
'public.presentation',
'public.text',
kUTTypeCommaSeparatedText,
kUTTypeDelimitedText,
kUTTypeElectronicPublication,
kUTTypeFlatRTFD,
kUTTypeScript,
kUTTypeShellScript,
],
[MediaType.ARCHIVE]: [
kUTTypeArchive,
kUTTypeBzip2Archive,
kUTTypeGNUZipArchive,
'com.sun.java-archive',
'org.gnu.gnu-tar-archive',
'public.tar-archive',
'org.gnu.gnu-zip-archive',
'org.gnu.gnu-zip-tar-archive',
'com.apple.binhex-archive',
'com.apple.macbinary-archive',
'public.cpio-archive',
'com.pkware.zip-archive',
kUTTypeWebArchive,
kUTTypeZipArchive,
],
};
if (+iOSNativeHelper.MajorVersion >= 14) {
MediaFileTypes[MediaType.IMAGE] = MediaFileTypes[MediaType.IMAGE].concat([
UTTypeWebP.identifier,
UTTypeBMP.identifier,
UTTypeGIF.identifier,
UTTypeHEIC.identifier,
UTTypeHEIF.identifier,
UTTypeImage.identifier,
UTTypeJPEG.identifier,
UTTypeLivePhoto.identifier,
UTTypePNG.identifier,
UTTypeRAWImage.identifier,
UTTypeSVG.identifier,
UTTypeTIFF.identifier,
]);
MediaFileTypes[MediaType.AUDIO] = MediaFileTypes[MediaType.AUDIO].concat([
UTTypeAIFF.identifier,
UTTypeAppleProtectedMPEG4Audio.identifier,
UTTypeAudio.identifier,
UTTypeMP3.identifier,
UTTypeMPEG4Audio.identifier,
UTTypeWAV.identifier,
]);
MediaFileTypes[MediaType.ARCHIVE] = MediaFileTypes[MediaType.ARCHIVE].concat([
UTTypeAppleArchive.identifier,
UTTypeArchive.identifier,
UTTypeBZ2.identifier,
UTTypeDiskImage.identifier,
UTTypeGZIP.identifier,
UTTypeZIP.identifier,
]);
MediaFileTypes[MediaType.VIDEO] = MediaFileTypes[MediaType.VIDEO].concat([
UTTypeAVI.identifier,
UTTypeAppleProtectedMPEG4Video.identifier,
UTTypeMPEG.identifier,
UTTypeMPEG2TransportStream.identifier,
UTTypeMPEG2Video.identifier,
UTTypeMPEG4Movie.identifier,
UTTypeMovie.identifier,
UTTypeQuickTimeMovie.identifier,
UTTypeVideo.identifier,
]);
MediaFileTypes[MediaType.DOCUMENT] = MediaFileTypes[MediaType.DOCUMENT].concat([
UTTypeCommaSeparatedText.identifier,
UTTypeEPUB.identifier,
UTTypeFlatRTFD.identifier,
UTTypePDF.identifier,
UTTypePresentation.identifier,
UTTypePlainText.identifier,
UTTypeRTF.identifier,
UTTypeRTFD.identifier,
UTTypeSpreadsheet.identifier,
UTTypeTabSeparatedText.identifier,
UTTypeText.identifier,
]);
}
//# sourceMappingURL=index.ios.js.map