yeet
This commit is contained in:
24
node_modules/expo-file-system/ios/EXFileSystem.podspec
generated
vendored
Normal file
24
node_modules/expo-file-system/ios/EXFileSystem.podspec
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
require 'json'
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'EXFileSystem'
|
||||
s.version = package['version']
|
||||
s.summary = package['description']
|
||||
s.description = package['description']
|
||||
s.license = package['license']
|
||||
s.author = package['author']
|
||||
s.homepage = package['homepage']
|
||||
s.platform = :ios, '10.0'
|
||||
s.source = { :git => 'https://github.com/expo/expo.git' }
|
||||
s.source_files = 'EXFileSystem/**/*.{h,m}'
|
||||
s.preserve_paths = 'EXFileSystem/**/*.{h,m}'
|
||||
s.requires_arc = true
|
||||
|
||||
s.dependency 'UMCore'
|
||||
s.dependency 'UMFileSystemInterface'
|
||||
|
||||
end
|
||||
|
||||
|
17
node_modules/expo-file-system/ios/EXFileSystem/EXFilePermissionModule.h
generated
vendored
Normal file
17
node_modules/expo-file-system/ios/EXFileSystem/EXFilePermissionModule.h
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UMFileSystemInterface/UMFileSystemInterface.h>
|
||||
#import <UMFileSystemInterface/UMFilePermissionModuleInterface.h>
|
||||
#import <UMCore/UMInternalModule.h>
|
||||
#import <UMCore/UMModuleRegistryConsumer.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EXFilePermissionModule : NSObject <UMInternalModule, UMFilePermissionModuleInterface, UMModuleRegistryConsumer>
|
||||
|
||||
- (UMFileSystemPermissionFlags)getPathPermissions:(NSString *)path;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
68
node_modules/expo-file-system/ios/EXFileSystem/EXFilePermissionModule.m
generated
vendored
Normal file
68
node_modules/expo-file-system/ios/EXFileSystem/EXFilePermissionModule.m
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
#import <EXFileSystem/EXFilePermissionModule.h>
|
||||
#import <UMFileSystemInterface/UMFileSystemInterface.h>
|
||||
|
||||
@interface EXFilePermissionModule ()
|
||||
|
||||
@property (nonatomic, weak) UMModuleRegistry *moduleRegistry;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXFilePermissionModule
|
||||
|
||||
UM_REGISTER_MODULE();
|
||||
|
||||
+ (const NSArray<Protocol *> *)exportedInterfaces
|
||||
{
|
||||
return @[@protocol(UMFilePermissionModuleInterface)];
|
||||
}
|
||||
|
||||
- (UMFileSystemPermissionFlags)getPathPermissions:(NSString *)path
|
||||
{
|
||||
UMFileSystemPermissionFlags permissionsForInternalDirectories = [self getInternalPathPermissions:path];
|
||||
if (permissionsForInternalDirectories != UMFileSystemPermissionNone) {
|
||||
return permissionsForInternalDirectories;
|
||||
} else {
|
||||
return [self getExternalPathPermissions:path];
|
||||
}
|
||||
}
|
||||
|
||||
- (UMFileSystemPermissionFlags)getInternalPathPermissions:(NSString *)path
|
||||
{
|
||||
id<UMFileSystemInterface> fileSystem = [_moduleRegistry getModuleImplementingProtocol:@protocol(UMFileSystemInterface)];
|
||||
NSArray<NSString *> *scopedDirs = @[fileSystem.cachesDirectory, fileSystem.documentDirectory];
|
||||
NSString *standardizedPath = [path stringByStandardizingPath];
|
||||
for (NSString *scopedDirectory in scopedDirs) {
|
||||
if ([standardizedPath hasPrefix:[scopedDirectory stringByAppendingString:@"/"]] ||
|
||||
[standardizedPath isEqualToString:scopedDirectory]) {
|
||||
return UMFileSystemPermissionRead | UMFileSystemPermissionWrite;
|
||||
}
|
||||
}
|
||||
|
||||
NSString *bundleDirectory = fileSystem.bundleDirectory;
|
||||
if (bundleDirectory != nil && [path hasPrefix:[bundleDirectory stringByAppendingString:@"/"]]) {
|
||||
return UMFileSystemPermissionRead;
|
||||
}
|
||||
|
||||
return UMFileSystemPermissionNone;
|
||||
}
|
||||
|
||||
- (UMFileSystemPermissionFlags)getExternalPathPermissions:(NSString *)path
|
||||
{
|
||||
UMFileSystemPermissionFlags filePermissions = UMFileSystemPermissionNone;
|
||||
if ([[NSFileManager defaultManager] isReadableFileAtPath:path]) {
|
||||
filePermissions |= UMFileSystemPermissionRead;
|
||||
}
|
||||
|
||||
if ([[NSFileManager defaultManager] isWritableFileAtPath:path]) {
|
||||
filePermissions |= UMFileSystemPermissionWrite;
|
||||
}
|
||||
|
||||
return filePermissions;
|
||||
}
|
||||
|
||||
- (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry {
|
||||
_moduleRegistry = moduleRegistry;
|
||||
}
|
||||
|
||||
@end
|
43
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystem.h
generated
vendored
Normal file
43
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystem.h
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2016-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UMCore/UMExportedModule.h>
|
||||
#import <UMCore/UMModuleRegistryConsumer.h>
|
||||
#import <UMCore/UMEventEmitter.h>
|
||||
#import <UMFileSystemInterface/UMFileSystemInterface.h>
|
||||
|
||||
@interface EXFileSystem : UMExportedModule <UMEventEmitter, UMModuleRegistryConsumer, UMFileSystemInterface>
|
||||
|
||||
@property (nonatomic, readonly) NSString *documentDirectory;
|
||||
@property (nonatomic, readonly) NSString *cachesDirectory;
|
||||
@property (nonatomic, readonly) NSString *bundleDirectory;
|
||||
|
||||
- (instancetype)initWithDocumentDirectory:(NSString *)documentDirectory cachesDirectory:(NSString *)cachesDirectory bundleDirectory:(NSString *)bundleDirectory;
|
||||
|
||||
- (UMFileSystemPermissionFlags)permissionsForURI:(NSURL *)uri;
|
||||
|
||||
- (BOOL)ensureDirExistsWithPath:(NSString *)path;
|
||||
|
||||
- (NSString *)generatePathInDirectory:(NSString *)directory withExtension:(NSString *)extension;
|
||||
|
||||
@end
|
||||
|
||||
@protocol EXFileSystemHandler
|
||||
|
||||
+ (void)getInfoForFile:(NSURL *)fileUri
|
||||
withOptions:(NSDictionary *)optionxs
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject;
|
||||
|
||||
+ (void)copyFrom:(NSURL *)from
|
||||
to:(NSURL *)to
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSData (EXFileSystem)
|
||||
|
||||
- (NSString *)md5String;
|
||||
|
||||
@end
|
984
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystem.m
generated
vendored
Normal file
984
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystem.m
generated
vendored
Normal file
@ -0,0 +1,984 @@
|
||||
// Copyright 2016-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <UMCore/UMModuleRegistry.h>
|
||||
|
||||
#import <EXFileSystem/EXFileSystem.h>
|
||||
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
#import <EXFileSystem/EXFileSystemLocalFileHandler.h>
|
||||
#import <EXFileSystem/EXFileSystemAssetLibraryHandler.h>
|
||||
|
||||
#import <UMFileSystemInterface/UMFileSystemInterface.h>
|
||||
#import <UMFileSystemInterface/UMFilePermissionModuleInterface.h>
|
||||
|
||||
#import <UMCore/UMEventEmitterService.h>
|
||||
|
||||
#import <EXFileSystem/EXResumablesManager.h>
|
||||
#import <EXFileSystem/EXSessionTaskDispatcher.h>
|
||||
#import <EXFileSystem/EXSessionDownloadTaskDelegate.h>
|
||||
#import <EXFileSystem/EXSessionResumableDownloadTaskDelegate.h>
|
||||
#import <EXFileSystem/EXSessionUploadTaskDelegate.h>
|
||||
|
||||
NSString * const EXDownloadProgressEventName = @"expo-file-system.downloadProgress";
|
||||
|
||||
typedef NS_ENUM(NSInteger, EXFileSystemSessionType) {
|
||||
EXFileSystemBackgroundSession = 0,
|
||||
EXFileSystemForegroundSession = 1,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSInteger, EXFileSystemUploadType) {
|
||||
EXFileSystemInvalidType = -1,
|
||||
EXFileSystemBinaryContent = 0,
|
||||
EXFileSystemMultipart = 1,
|
||||
};
|
||||
|
||||
@interface EXFileSystem ()
|
||||
|
||||
@property (nonatomic, strong) NSURLSession *backgroundSession;
|
||||
@property (nonatomic, strong) NSURLSession *foregroundSession;
|
||||
@property (nonatomic, strong) EXSessionTaskDispatcher *sessionTaskDispatcher;
|
||||
@property (nonatomic, strong) EXResumablesManager *resumableManager;
|
||||
@property (nonatomic, weak) UMModuleRegistry *moduleRegistry;
|
||||
@property (nonatomic, weak) id<UMEventEmitterService> eventEmitter;
|
||||
@property (nonatomic, strong) NSString *documentDirectory;
|
||||
@property (nonatomic, strong) NSString *cachesDirectory;
|
||||
@property (nonatomic, strong) NSString *bundleDirectory;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXFileSystem
|
||||
|
||||
UM_REGISTER_MODULE();
|
||||
|
||||
+ (const NSString *)exportedModuleName
|
||||
{
|
||||
return @"ExponentFileSystem";
|
||||
}
|
||||
|
||||
+ (const NSArray<Protocol *> *)exportedInterfaces
|
||||
{
|
||||
return @[@protocol(UMFileSystemInterface)];
|
||||
}
|
||||
|
||||
- (instancetype)initWithDocumentDirectory:(NSString *)documentDirectory cachesDirectory:(NSString *)cachesDirectory bundleDirectory:(NSString *)bundleDirectory
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_documentDirectory = documentDirectory;
|
||||
_cachesDirectory = cachesDirectory;
|
||||
_bundleDirectory = bundleDirectory;
|
||||
|
||||
_resumableManager = [EXResumablesManager new];
|
||||
|
||||
[EXFileSystem ensureDirExistsWithPath:_documentDirectory];
|
||||
[EXFileSystem ensureDirExistsWithPath:_cachesDirectory];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
NSArray<NSString *> *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||
NSString *documentDirectory = [documentPaths objectAtIndex:0];
|
||||
|
||||
NSArray<NSString *> *cachesPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
NSString *cacheDirectory = [cachesPaths objectAtIndex:0];
|
||||
|
||||
return [self initWithDocumentDirectory:documentDirectory
|
||||
cachesDirectory:cacheDirectory
|
||||
bundleDirectory:[NSBundle mainBundle].bundlePath];
|
||||
}
|
||||
|
||||
- (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
|
||||
{
|
||||
_moduleRegistry = moduleRegistry;
|
||||
_eventEmitter = [_moduleRegistry getModuleImplementingProtocol:@protocol(UMEventEmitterService)];
|
||||
|
||||
_sessionTaskDispatcher = [[EXSessionTaskDispatcher alloc] initWithSessionHandler:[moduleRegistry getSingletonModuleForName:@"SessionHandler"]];
|
||||
_backgroundSession = [self _createSession:EXFileSystemBackgroundSession delegate:_sessionTaskDispatcher];
|
||||
_foregroundSession = [self _createSession:EXFileSystemForegroundSession delegate:_sessionTaskDispatcher];
|
||||
}
|
||||
|
||||
- (NSDictionary *)constantsToExport
|
||||
{
|
||||
return @{
|
||||
@"documentDirectory": _documentDirectory ? [NSURL fileURLWithPath:_documentDirectory].absoluteString : [NSNull null],
|
||||
@"cacheDirectory": _cachesDirectory ? [NSURL fileURLWithPath:_cachesDirectory].absoluteString : [NSNull null],
|
||||
@"bundleDirectory": _bundleDirectory ? [NSURL fileURLWithPath:_bundleDirectory].absoluteString : [NSNull null]
|
||||
};
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents
|
||||
{
|
||||
return @[EXDownloadProgressEventName];
|
||||
}
|
||||
|
||||
- (void)startObserving {
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)stopObserving {
|
||||
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_sessionTaskDispatcher deactivate];
|
||||
[_backgroundSession invalidateAndCancel];
|
||||
[_foregroundSession invalidateAndCancel];
|
||||
}
|
||||
|
||||
- (NSDictionary *)encodingMap
|
||||
{
|
||||
/*
|
||||
TODO:Bacon: match node.js fs
|
||||
https://github.com/nodejs/node/blob/master/lib/buffer.js
|
||||
ascii
|
||||
base64
|
||||
binary
|
||||
hex
|
||||
ucs2/ucs-2
|
||||
utf16le/utf-16le
|
||||
utf8/utf-8
|
||||
latin1 (ISO8859-1, only in node 6.4.0+)
|
||||
*/
|
||||
return @{
|
||||
@"ascii": @(NSASCIIStringEncoding),
|
||||
@"nextstep": @(NSNEXTSTEPStringEncoding),
|
||||
@"japaneseeuc": @(NSJapaneseEUCStringEncoding),
|
||||
@"utf8": @(NSUTF8StringEncoding),
|
||||
@"isolatin1": @(NSISOLatin1StringEncoding),
|
||||
@"symbol": @(NSSymbolStringEncoding),
|
||||
@"nonlossyascii": @(NSNonLossyASCIIStringEncoding),
|
||||
@"shiftjis": @(NSShiftJISStringEncoding),
|
||||
@"isolatin2": @(NSISOLatin2StringEncoding),
|
||||
@"unicode": @(NSUnicodeStringEncoding),
|
||||
@"windowscp1251": @(NSWindowsCP1251StringEncoding),
|
||||
@"windowscp1252": @(NSWindowsCP1252StringEncoding),
|
||||
@"windowscp1253": @(NSWindowsCP1253StringEncoding),
|
||||
@"windowscp1254": @(NSWindowsCP1254StringEncoding),
|
||||
@"windowscp1250": @(NSWindowsCP1250StringEncoding),
|
||||
@"iso2022jp": @(NSISO2022JPStringEncoding),
|
||||
@"macosroman": @(NSMacOSRomanStringEncoding),
|
||||
@"utf16": @(NSUTF16StringEncoding),
|
||||
@"utf16bigendian": @(NSUTF16BigEndianStringEncoding),
|
||||
@"utf16littleendian": @(NSUTF16LittleEndianStringEncoding),
|
||||
@"utf32": @(NSUTF32StringEncoding),
|
||||
@"utf32bigendian": @(NSUTF32BigEndianStringEncoding),
|
||||
@"utf32littleendian": @(NSUTF32LittleEndianStringEncoding),
|
||||
};
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(getInfoAsync,
|
||||
getInfoAsyncWithURI:(NSString *)uriString
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *uri = [NSURL URLWithString:uriString];
|
||||
// no scheme provided in uri, handle as a local path and add 'file://' scheme
|
||||
if (!uri.scheme) {
|
||||
uri = [NSURL fileURLWithPath:uriString isDirectory:false];
|
||||
}
|
||||
if (!([self permissionsForURI:uri] & UMFileSystemPermissionRead)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't readable.", uri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([uri.scheme isEqualToString:@"file"]) {
|
||||
[EXFileSystemLocalFileHandler getInfoForFile:uri withOptions:options resolver:resolve rejecter:reject];
|
||||
} else if ([uri.scheme isEqualToString:@"assets-library"] || [uri.scheme isEqualToString:@"ph"]) {
|
||||
[EXFileSystemAssetLibraryHandler getInfoForFile:uri withOptions:options resolver:resolve rejecter:reject];
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", uri],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(readAsStringAsync,
|
||||
readAsStringAsyncWithURI:(NSString *)uriString
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *uri = [NSURL URLWithString:uriString];
|
||||
// no scheme provided in uri, handle as a local path and add 'file://' scheme
|
||||
if (!uri.scheme) {
|
||||
uri = [NSURL fileURLWithPath:uriString isDirectory:false];
|
||||
}
|
||||
if (!([self permissionsForURI:uri] & UMFileSystemPermissionRead)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't readable.", uri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([uri.scheme isEqualToString:@"file"]) {
|
||||
NSString *encodingType = @"utf8";
|
||||
if (options[@"encoding"] && [options[@"encoding"] isKindOfClass:[NSString class]]) {
|
||||
encodingType = [options[@"encoding"] lowercaseString];
|
||||
}
|
||||
if ([encodingType isEqualToString:@"base64"]) {
|
||||
NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:uri.path];
|
||||
if (file == nil) {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_READ_FILE",
|
||||
[NSString stringWithFormat:@"File '%@' could not be read.", uri.path],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
// position and length are used as a cursor/paging system.
|
||||
if ([options[@"position"] isKindOfClass:[NSNumber class]]) {
|
||||
[file seekToFileOffset:[options[@"position"] intValue]];
|
||||
}
|
||||
|
||||
NSData *data;
|
||||
if ([options[@"length"] isKindOfClass:[NSNumber class]]) {
|
||||
data = [file readDataOfLength:[options[@"length"] intValue]];
|
||||
} else {
|
||||
data = [file readDataToEndOfFile];
|
||||
}
|
||||
resolve([data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]);
|
||||
} else {
|
||||
NSUInteger encoding = NSUTF8StringEncoding;
|
||||
id possibleEncoding = [[self encodingMap] valueForKey:encodingType];
|
||||
if (possibleEncoding != nil) {
|
||||
encoding = [possibleEncoding integerValue];
|
||||
}
|
||||
NSError *error;
|
||||
NSString *string = [NSString stringWithContentsOfFile:uri.path encoding:encoding error:&error];
|
||||
if (string) {
|
||||
resolve(string);
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_READ_FILE",
|
||||
[NSString stringWithFormat:@"File '%@' could not be read.", uri],
|
||||
error);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", uri],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(writeAsStringAsync,
|
||||
writeAsStringAsyncWithURI:(NSString *)uriString
|
||||
withString:(NSString *)string
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *uri = [NSURL URLWithString:uriString];
|
||||
if (!([self permissionsForURI:uri] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't writable.", uri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([uri.scheme isEqualToString:@"file"]) {
|
||||
NSString *encodingType = @"utf8";
|
||||
if ([options[@"encoding"] isKindOfClass:[NSString class]]) {
|
||||
encodingType = [options[@"encoding"] lowercaseString];
|
||||
}
|
||||
if ([encodingType isEqualToString:@"base64"]) {
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
if (imageData) {
|
||||
// TODO:Bacon: Should we surface `attributes`?
|
||||
if ([[NSFileManager defaultManager] createFileAtPath:uri.path contents:imageData attributes:nil]) {
|
||||
resolve([NSNull null]);
|
||||
} else {
|
||||
return reject(@"ERR_FILESYSTEM_UNKNOWN_FILE",
|
||||
[NSString stringWithFormat:@"No such file or directory '%@'", uri.path],
|
||||
nil);
|
||||
}
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_FORMAT",
|
||||
@"Failed to parse base64 string.",
|
||||
nil);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
NSUInteger encoding = NSUTF8StringEncoding;
|
||||
id possibleEncoding = [[self encodingMap] valueForKey:encodingType];
|
||||
if (possibleEncoding != nil) {
|
||||
encoding = [possibleEncoding integerValue];
|
||||
}
|
||||
|
||||
NSError *error;
|
||||
if ([string writeToFile:uri.path atomically:YES encoding:encoding error:&error]) {
|
||||
resolve([NSNull null]);
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_WRITE_TO_FILE",
|
||||
[NSString stringWithFormat:@"File '%@' could not be written.", uri],
|
||||
error);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", uri],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(deleteAsync,
|
||||
deleteAsyncWithURI:(NSString *)uriString
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *uri = [NSURL URLWithString:uriString];
|
||||
if (!([self permissionsForURI:[uri URLByAppendingPathComponent:@".."]] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"Location '%@' isn't deletable.", uri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([uri.scheme isEqualToString:@"file"]) {
|
||||
NSString *path = uri.path;
|
||||
if ([self _checkIfFileExists:path]) {
|
||||
NSError *error;
|
||||
if ([[NSFileManager defaultManager] removeItemAtPath:path error:&error]) {
|
||||
resolve([NSNull null]);
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_DELETE_FILE",
|
||||
[NSString stringWithFormat:@"File '%@' could not be deleted.", uri],
|
||||
error);
|
||||
}
|
||||
} else {
|
||||
if (options[@"idempotent"]) {
|
||||
resolve([NSNull null]);
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_FIND_FILE",
|
||||
[NSString stringWithFormat:@"File '%@' could not be deleted because it could not be found.", uri],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", uri],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(moveAsync,
|
||||
moveAsyncWithOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *from = [NSURL URLWithString:options[@"from"]];
|
||||
if (!from) {
|
||||
reject(@"ERR_FILESYSTEM_MISSING_PARAMETER", @"Need a `from` location.", nil);
|
||||
return;
|
||||
}
|
||||
if (!([self permissionsForURI:[from URLByAppendingPathComponent:@".."]] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"Location '%@' isn't movable.", from],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
NSURL *to = [NSURL URLWithString:options[@"to"]];
|
||||
if (!to) {
|
||||
reject(@"ERR_FILESYSTEM_MISSING_PARAMETER", @"Need a `to` location.", nil);
|
||||
return;
|
||||
}
|
||||
if (!([self permissionsForURI:to] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't writable.", to],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: The destination-delete and the move should happen atomically, but we hope for the best for now
|
||||
if ([from.scheme isEqualToString:@"file"]) {
|
||||
NSString *fromPath = [from.path stringByStandardizingPath];
|
||||
NSString *toPath = [to.path stringByStandardizingPath];
|
||||
NSError *error;
|
||||
if ([self _checkIfFileExists:toPath]) {
|
||||
if (![[NSFileManager defaultManager] removeItemAtPath:toPath error:&error]) {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_MOVE_FILE",
|
||||
[NSString stringWithFormat:@"File '%@' could not be moved to '%@' because a file already exists at "
|
||||
"the destination and could not be deleted.", from, to],
|
||||
error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ([[NSFileManager defaultManager] moveItemAtPath:fromPath toPath:toPath error:&error]) {
|
||||
resolve([NSNull null]);
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_MOVE_FILE",
|
||||
[NSString stringWithFormat:@"File '%@' could not be moved to '%@'.", from, to],
|
||||
error);
|
||||
}
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", from],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(copyAsync,
|
||||
copyAsyncWithOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *from = [NSURL URLWithString:options[@"from"]];
|
||||
if (!from) {
|
||||
reject(@"ERR_FILESYSTEM_MISSING_PARAMETER", @"Need a `from` location.", nil);
|
||||
return;
|
||||
}
|
||||
if (!([self permissionsForURI:from] & UMFileSystemPermissionRead)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't readable.", from],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
NSURL *to = [NSURL URLWithString:options[@"to"]];
|
||||
if (!to) {
|
||||
reject(@"ERR_FILESYSTEM_MISSING_PARAMETER", @"Need a `to` location.", nil);
|
||||
return;
|
||||
}
|
||||
if (!([self permissionsForURI:to] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't writable.", to],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([from.scheme isEqualToString:@"file"]) {
|
||||
[EXFileSystemLocalFileHandler copyFrom:from to:to resolver:resolve rejecter:reject];
|
||||
} else if ([from.scheme isEqualToString:@"assets-library"] || [from.scheme isEqualToString:@"ph"]) {
|
||||
[EXFileSystemAssetLibraryHandler copyFrom:from to:to resolver:resolve rejecter:reject];
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", from],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(makeDirectoryAsync,
|
||||
makeDirectoryAsyncWithURI:(NSString *)uriString
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
|
||||
NSURL *uri = [NSURL URLWithString:uriString];
|
||||
if (!([self permissionsForURI:uri] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"Directory '%@' could not be created because the location isn't writable.", uri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([uri.scheme isEqualToString:@"file"]) {
|
||||
NSError *error;
|
||||
if ([[NSFileManager defaultManager] createDirectoryAtPath:uri.path
|
||||
withIntermediateDirectories:[options[@"intermediates"] boolValue]
|
||||
attributes:nil
|
||||
error:&error]) {
|
||||
resolve([NSNull null]);
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_CREATE_DIRECTORY",
|
||||
[NSString stringWithFormat:@"Directory '%@' could not be created.", uri],
|
||||
error);
|
||||
}
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", uri],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(readDirectoryAsync,
|
||||
readDirectoryAsyncWithURI:(NSString *)uriString
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *uri = [NSURL URLWithString:uriString];
|
||||
if (!([self permissionsForURI:uri] & UMFileSystemPermissionRead)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"Location '%@' isn't readable.", uri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if ([uri.scheme isEqualToString:@"file"]) {
|
||||
NSError *error;
|
||||
NSArray<NSString *> *children = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:uri.path error:&error];
|
||||
if (children) {
|
||||
resolve(children);
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_READ_DIRECTORY",
|
||||
[NSString stringWithFormat:@"Directory '%@' could not be read.", uri],
|
||||
error);
|
||||
}
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_URI",
|
||||
[NSString stringWithFormat:@"Unsupported URI scheme for '%@'", uri],
|
||||
nil);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(downloadAsync,
|
||||
downloadAsyncWithUrl:(NSString *)urlString
|
||||
localURI:(NSString *)localUriString
|
||||
options:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
NSURL *localUri = [NSURL URLWithString:localUriString];
|
||||
if (!([self checkIfFileDirExists:localUri.path])) {
|
||||
reject(@"ERR_FILESYSTEM_WRONG_DESTINATION",
|
||||
[NSString stringWithFormat:@"Directory for '%@' doesn't exist. Please make sure directory '%@' exists before calling downloadAsync.", localUriString, [localUri.path stringByDeletingLastPathComponent]],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
if (!([self permissionsForURI:localUri] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't writable.", localUri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
if (![self _checkHeadersDictionary:options[@"headers"]]) {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_HEADERS",
|
||||
@"Invalid headers dictionary. Keys and values should be strings.",
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLSession *session = [self _sessionForType:[options[@"sessionType"] intValue]];
|
||||
if (!session) {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_SESSION_TYPE",
|
||||
[NSString stringWithFormat:@"Invalid session type: '%@'", options[@"sessionType"]],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLRequest *request = [self _createRequest:url headers:options[@"headers"]];
|
||||
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request];
|
||||
EXSessionTaskDelegate *taskDelegate = [[EXSessionDownloadTaskDelegate alloc] initWithResolve:resolve
|
||||
reject:reject
|
||||
localUrl:localUri
|
||||
shouldCalculateMd5:[options[@"md5"] boolValue]];
|
||||
[_sessionTaskDispatcher registerTaskDelegate:taskDelegate forTask:task];
|
||||
[task resume];
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(uploadAsync,
|
||||
uploadAsync:(NSString *)urlString
|
||||
localURI:(NSString *)fileUriString
|
||||
options:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *fileUri = [NSURL URLWithString:fileUriString];
|
||||
NSString *httpMethod = options[@"httpMethod"];
|
||||
EXFileSystemUploadType type = [self _getUploadTypeFrom:options[@"uploadType"]];
|
||||
if (![fileUri.scheme isEqualToString:@"file"]) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"Cannot upload file '%@'. Only 'file://' URI are supported.", fileUri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
if (!([self _checkIfFileExists:fileUri.path])) {
|
||||
reject(@"ERR_FILE_NOT_EXISTS",
|
||||
[NSString stringWithFormat:@"File '%@' does not exist.", fileUri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
if (![self _checkHeadersDictionary:options[@"headers"]]) {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_HEADERS_DICTIONARY",
|
||||
@"Invalid headers dictionary. Keys and values should be strings.",
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
if (!httpMethod) {
|
||||
reject(@"ERR_FILESYSTEM_MISSING_HTTP_METHOD", @"Missing HTTP method.", nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableURLRequest *request = [self _createRequest:[NSURL URLWithString:urlString] headers:options[@"headers"]];
|
||||
[request setHTTPMethod:httpMethod];
|
||||
NSURLSession *session = [self _sessionForType:[options[@"sessionType"] intValue]];
|
||||
if (!session) {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_SESSION_TYPE",
|
||||
[NSString stringWithFormat:@"Invalid session type: '%@'", options[@"sessionType"]],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSURLSessionUploadTask *task;
|
||||
if (type == EXFileSystemBinaryContent) {
|
||||
task = [session uploadTaskWithRequest:request fromFile:fileUri];
|
||||
} else if (type == EXFileSystemMultipart) {
|
||||
NSString *boundaryString = [[NSUUID UUID] UUIDString];
|
||||
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundaryString] forHTTPHeaderField:@"Content-Type"];
|
||||
NSData *httpBody = [self _createBodyWithBoundary:boundaryString
|
||||
fileUri:fileUri
|
||||
parameters:options[@"parameters"]
|
||||
fieldName:options[@"fieldName"]
|
||||
mimeType:options[@"mimeType"]];
|
||||
[request setHTTPBody:httpBody];
|
||||
task = [session uploadTaskWithStreamedRequest:request];
|
||||
} else {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_UPLOAD_TYPE",
|
||||
[NSString stringWithFormat:@"Invalid upload type: '%@'.", options[@"uploadType"]],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
EXSessionTaskDelegate *taskDelegate = [[EXSessionUploadTaskDelegate alloc] initWithResolve:resolve reject:reject];
|
||||
[_sessionTaskDispatcher registerTaskDelegate:taskDelegate forTask:task];
|
||||
[task resume];
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(downloadResumableStartAsync,
|
||||
downloadResumableStartAsyncWithUrl:(NSString *)urlString
|
||||
fileURI:(NSString *)fileUri
|
||||
uuid:(NSString *)uuid
|
||||
options:(NSDictionary *)options
|
||||
resumeData:(NSString *)data
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURL *url = [NSURL URLWithString:urlString];
|
||||
NSURL *localUrl = [NSURL URLWithString:fileUri];
|
||||
if (!([self checkIfFileDirExists:localUrl.path])) {
|
||||
reject(@"ERR_FILESYSTEM_WRONG_DESTINATION",
|
||||
[NSString stringWithFormat:@"Directory for '%@' doesn't exist. Please make sure directory '%@' exists before calling downloadAsync.", fileUri, [localUrl.path stringByDeletingLastPathComponent]],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
if (![localUrl.scheme isEqualToString:@"file"]) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"Cannot download to '%@': only 'file://' URI destinations are supported.", fileUri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *path = localUrl.path;
|
||||
if (!([self _permissionsForPath:path] & UMFileSystemPermissionWrite)) {
|
||||
reject(@"ERR_FILESYSTEM_NO_PERMISSIONS",
|
||||
[NSString stringWithFormat:@"File '%@' isn't writable.", fileUri],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if (![self _checkHeadersDictionary:options[@"headers"]]) {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_HEADERS_DICTIONARY",
|
||||
@"Invalid headers dictionary. Keys and values should be strings.",
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *resumeData = data ? [[NSData alloc] initWithBase64EncodedString:data options:0] : nil;
|
||||
[self _downloadResumableCreateSessionWithUrl:url
|
||||
fileUrl:localUrl
|
||||
uuid:uuid
|
||||
optins:options
|
||||
resumeData:resumeData
|
||||
resolve:resolve
|
||||
reject:reject];
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(downloadResumablePauseAsync,
|
||||
downloadResumablePauseAsyncWithUUID:(NSString *)uuid
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
NSURLSessionDownloadTask *task = [_resumableManager taskForId:uuid];
|
||||
if (!task) {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_FIND_TASK",
|
||||
[NSString stringWithFormat:@"There is no download object with UUID: %@", uuid],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
UM_WEAKIFY(self);
|
||||
[task cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
|
||||
UM_ENSURE_STRONGIFY(self);
|
||||
resolve(@{ @"resumeData": UMNullIfNil([resumeData base64EncodedStringWithOptions:0]) });
|
||||
}];
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(getFreeDiskStorageAsync, getFreeDiskStorageAsyncWithResolver:(UMPromiseResolveBlock)resolve rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
if(![self freeDiskStorage]) {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_DETERMINE_DISK_CAPACITY", @"Unable to determine free disk storage capacity", nil);
|
||||
} else {
|
||||
resolve([self freeDiskStorage]);
|
||||
}
|
||||
}
|
||||
|
||||
UM_EXPORT_METHOD_AS(getTotalDiskCapacityAsync, getTotalDiskCapacityAsyncWithResolver:(UMPromiseResolveBlock)resolve rejecter:(UMPromiseRejectBlock)reject)
|
||||
{
|
||||
if(![self totalDiskCapacity]) {
|
||||
reject(@"ERR_FILESYSTEM_CANNOT_DETERMINE_DISK_CAPACITY", @"Unable to determine total disk capacity", nil);
|
||||
} else {
|
||||
resolve([self totalDiskCapacity]);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Internal methods
|
||||
|
||||
- (EXFileSystemUploadType)_getUploadTypeFrom:(NSNumber * _Nullable)type
|
||||
{
|
||||
switch ([type intValue]) {
|
||||
case EXFileSystemBinaryContent:
|
||||
case EXFileSystemMultipart:
|
||||
return [type intValue];
|
||||
}
|
||||
|
||||
return EXFileSystemInvalidType;
|
||||
}
|
||||
|
||||
// Borrowed from http://stackoverflow.com/questions/2439020/wheres-the-iphone-mime-type-database
|
||||
- (NSString *)_guessMIMETypeFromPath:(NSString *)path
|
||||
{
|
||||
CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);
|
||||
CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass(UTI, kUTTagClassMIMEType);
|
||||
CFRelease(UTI);
|
||||
if (!MIMEType) {
|
||||
return @"application/octet-stream";
|
||||
}
|
||||
return (__bridge NSString *)(MIMEType);
|
||||
}
|
||||
|
||||
- (NSData *)_createBodyWithBoundary:(NSString *)boundary
|
||||
fileUri:(NSURL *)fileUri
|
||||
parameters:(NSDictionary * _Nullable)parameters
|
||||
fieldName:(NSString * _Nullable)fieldName
|
||||
mimeType:(NSString * _Nullable)mimetype
|
||||
{
|
||||
|
||||
NSMutableData *body = [NSMutableData data];
|
||||
NSData *data = [NSData dataWithContentsOfURL:fileUri];
|
||||
NSString *filename = [[fileUri path] lastPathComponent];
|
||||
|
||||
if (!mimetype) {
|
||||
mimetype = [self _guessMIMETypeFromPath:[fileUri path]];
|
||||
}
|
||||
|
||||
[parameters enumerateKeysAndObjectsUsingBlock:^(NSString *parameterKey, NSString *parameterValue, BOOL *stop) {
|
||||
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", parameterKey] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"%@\r\n", parameterValue] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
}];
|
||||
|
||||
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", fieldName ?: filename, filename] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", mimetype] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:data];
|
||||
[body appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
- (NSMutableURLRequest *)_createRequest:(NSURL *)url headers:(NSDictionary * _Nullable)headers
|
||||
{
|
||||
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
|
||||
if (headers != nil) {
|
||||
for (NSString *headerKey in headers) {
|
||||
[request setValue:[headers valueForKey:headerKey] forHTTPHeaderField:headerKey];
|
||||
}
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
- (NSURLSession *)_sessionForType:(EXFileSystemSessionType)type
|
||||
{
|
||||
switch (type) {
|
||||
case EXFileSystemBackgroundSession:
|
||||
return _backgroundSession;
|
||||
case EXFileSystemForegroundSession:
|
||||
return _foregroundSession;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)_checkHeadersDictionary:(NSDictionary * _Nullable)headers
|
||||
{
|
||||
for (id key in [headers allKeys]) {
|
||||
if (![key isKindOfClass:[NSString class]] || ![headers[key] isKindOfClass:[NSString class]]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
- (NSURLSession *)_createSession:(EXFileSystemSessionType)type delegate:(id<NSURLSessionDelegate>)delegate
|
||||
{
|
||||
NSURLSessionConfiguration *sessionConfiguration;
|
||||
if (type == EXFileSystemForegroundSession) {
|
||||
sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
} else {
|
||||
sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[[NSUUID UUID] UUIDString]];
|
||||
}
|
||||
sessionConfiguration.requestCachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
|
||||
sessionConfiguration.URLCache = nil;
|
||||
return [NSURLSession sessionWithConfiguration:sessionConfiguration
|
||||
delegate:delegate
|
||||
delegateQueue:nil];
|
||||
}
|
||||
|
||||
- (BOOL)_checkIfFileExists:(NSString *)path
|
||||
{
|
||||
return [[NSFileManager defaultManager] fileExistsAtPath:path];
|
||||
}
|
||||
|
||||
- (void)_downloadResumableCreateSessionWithUrl:(NSURL *)url
|
||||
fileUrl:(NSURL *)fileUrl
|
||||
uuid:(NSString *)uuid
|
||||
optins:(NSDictionary *)options
|
||||
resumeData:(NSData * _Nullable)resumeData
|
||||
resolve:(UMPromiseResolveBlock)resolve
|
||||
reject:(UMPromiseRejectBlock)reject
|
||||
{
|
||||
UM_WEAKIFY(self);
|
||||
EXDownloadDelegateOnWriteCallback onWrite = ^(NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
|
||||
UM_ENSURE_STRONGIFY(self);
|
||||
[self sendEventWithName:EXDownloadProgressEventName
|
||||
body:@{
|
||||
@"uuid": uuid,
|
||||
@"data": @{
|
||||
@"totalBytesWritten": @(totalBytesWritten),
|
||||
@"totalBytesExpectedToWrite": @(totalBytesExpectedToWrite),
|
||||
},
|
||||
}];
|
||||
};
|
||||
|
||||
NSURLSessionDownloadTask *downloadTask;
|
||||
NSURLSession *session = [self _sessionForType:[options[@"sessionType"] intValue]];
|
||||
if (!session) {
|
||||
reject(@"ERR_FILESYSTEM_INVALID_SESSION_TYPE",
|
||||
[NSString stringWithFormat:@"Invalid session type: '%@'", options[@"sessionType"]],
|
||||
nil);
|
||||
return;
|
||||
}
|
||||
|
||||
if (resumeData) {
|
||||
downloadTask = [session downloadTaskWithResumeData:resumeData];
|
||||
} else {
|
||||
NSURLRequest *request = [self _createRequest:url headers:options[@"headers"]];
|
||||
downloadTask = [session downloadTaskWithRequest:request];
|
||||
}
|
||||
EXSessionTaskDelegate *taskDelegate = [[EXSessionResumableDownloadTaskDelegate alloc] initWithResolve:resolve
|
||||
reject:reject
|
||||
localUrl:fileUrl
|
||||
shouldCalculateMd5:[options[@"md5"] boolValue]
|
||||
onWriteCallback:onWrite
|
||||
resumableManager:_resumableManager
|
||||
uuid:uuid];
|
||||
[_sessionTaskDispatcher registerTaskDelegate:taskDelegate forTask:downloadTask];
|
||||
[_resumableManager registerTask:downloadTask uuid:uuid];
|
||||
[downloadTask resume];
|
||||
}
|
||||
|
||||
- (UMFileSystemPermissionFlags)_permissionsForPath:(NSString *)path
|
||||
{
|
||||
return [[_moduleRegistry getModuleImplementingProtocol:@protocol(UMFilePermissionModuleInterface)] getPathPermissions:(NSString *)path];
|
||||
}
|
||||
|
||||
- (void)sendEventWithName:(NSString *)eventName body:(id)body
|
||||
{
|
||||
if (_eventEmitter != nil) {
|
||||
[_eventEmitter sendEventWithName:eventName body:body];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *)documentFileSystemAttributes {
|
||||
return [[NSFileManager defaultManager] attributesOfFileSystemForPath:_documentDirectory error:nil];
|
||||
}
|
||||
|
||||
#pragma mark - Public utils
|
||||
|
||||
- (UMFileSystemPermissionFlags)permissionsForURI:(NSURL *)uri
|
||||
{
|
||||
NSArray *validSchemas = @[
|
||||
@"assets-library",
|
||||
@"http",
|
||||
@"https",
|
||||
@"ph",
|
||||
];
|
||||
if ([validSchemas containsObject:uri.scheme]) {
|
||||
return UMFileSystemPermissionRead;
|
||||
}
|
||||
if ([uri.scheme isEqualToString:@"file"]) {
|
||||
return [self _permissionsForPath:uri.path];
|
||||
}
|
||||
return UMFileSystemPermissionNone;
|
||||
}
|
||||
|
||||
- (BOOL)checkIfFileDirExists:(NSString *)path
|
||||
{
|
||||
NSString *dir = [path stringByDeletingLastPathComponent];
|
||||
return [self _checkIfFileExists:dir];
|
||||
}
|
||||
|
||||
#pragma mark - Class methods
|
||||
|
||||
- (BOOL)ensureDirExistsWithPath:(NSString *)path
|
||||
{
|
||||
return [EXFileSystem ensureDirExistsWithPath:path];
|
||||
}
|
||||
|
||||
+ (BOOL)ensureDirExistsWithPath:(NSString *)path
|
||||
{
|
||||
BOOL isDir = NO;
|
||||
NSError *error;
|
||||
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir];
|
||||
if (!(exists && isDir)) {
|
||||
[[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error];
|
||||
if (error) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *)generatePathInDirectory:(NSString *)directory withExtension:(NSString *)extension
|
||||
{
|
||||
return [EXFileSystem generatePathInDirectory:directory withExtension:extension];
|
||||
}
|
||||
|
||||
+ (NSString *)generatePathInDirectory:(NSString *)directory withExtension:(NSString *)extension
|
||||
{
|
||||
NSString *fileName = [[[NSUUID UUID] UUIDString] stringByAppendingString:extension];
|
||||
[EXFileSystem ensureDirExistsWithPath:directory];
|
||||
return [directory stringByAppendingPathComponent:fileName];
|
||||
}
|
||||
|
||||
- (NSNumber *)totalDiskCapacity {
|
||||
NSDictionary *storage = [self documentFileSystemAttributes];
|
||||
|
||||
if (storage) {
|
||||
NSNumber *fileSystemSizeInBytes = storage[NSFileSystemSize];
|
||||
return fileSystemSizeInBytes;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSNumber *)freeDiskStorage {
|
||||
NSDictionary *storage = [self documentFileSystemAttributes];
|
||||
|
||||
if (storage) {
|
||||
NSNumber *freeFileSystemSizeInBytes = storage[NSFileSystemFreeSize];
|
||||
return freeFileSystemSizeInBytes;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
6
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemAssetLibraryHandler.h
generated
vendored
Normal file
6
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemAssetLibraryHandler.h
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
#import <EXFileSystem/EXFileSystem.h>
|
||||
|
||||
@interface EXFileSystemAssetLibraryHandler : NSObject <EXFileSystemHandler>
|
||||
|
||||
@end
|
114
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemAssetLibraryHandler.m
generated
vendored
Normal file
114
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemAssetLibraryHandler.m
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
|
||||
#import <EXFileSystem/EXFileSystemAssetLibraryHandler.h>
|
||||
|
||||
#import <Photos/Photos.h>
|
||||
|
||||
@implementation EXFileSystemAssetLibraryHandler
|
||||
|
||||
+ (void)getInfoForFile:(NSURL *)fileUri
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject
|
||||
{
|
||||
NSError *error;
|
||||
PHFetchResult<PHAsset *> *fetchResult = [self fetchResultForUri:fileUri error:&error];
|
||||
if (error) {
|
||||
reject(@"E_UNSUPPORTED_ARG", error.description, error);
|
||||
return;
|
||||
}
|
||||
if (fetchResult.count > 0) {
|
||||
PHAsset *asset = fetchResult[0];
|
||||
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
||||
result[@"exists"] = @(YES);
|
||||
result[@"isDirectory"] = @(NO);
|
||||
result[@"uri"] = fileUri;
|
||||
result[@"modificationTime"] = @(asset.modificationDate.timeIntervalSince1970);
|
||||
if (options[@"md5"] || options[@"size"]) {
|
||||
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
|
||||
result[@"size"] = @(imageData.length);
|
||||
if (options[@"md5"]) {
|
||||
result[@"md5"] = [imageData md5String];
|
||||
}
|
||||
resolve(result);
|
||||
}];
|
||||
} else {
|
||||
resolve(result);
|
||||
}
|
||||
} else {
|
||||
resolve(@{@"exists": @(NO), @"isDirectory": @(NO)});
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)copyFrom:(NSURL *)from
|
||||
to:(NSURL *)to
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject
|
||||
{
|
||||
NSString *toPath = [to.path stringByStandardizingPath];
|
||||
|
||||
// NOTE: The destination-delete and the copy should happen atomically, but we hope for the best for now
|
||||
NSError *error;
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:toPath]) {
|
||||
if (![[NSFileManager defaultManager] removeItemAtPath:toPath error:&error]) {
|
||||
reject(@"E_FILE_NOT_COPIED",
|
||||
[NSString stringWithFormat:@"File '%@' could not be copied to '%@' because a file already exists at "
|
||||
"the destination and could not be deleted.", from, to],
|
||||
error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PHFetchResult<PHAsset *> *fetchResult = [self fetchResultForUri:from error:&error];
|
||||
if (error) {
|
||||
reject(@"E_UNSUPPORTED_ARG", error.description, error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fetchResult.count > 0) {
|
||||
PHAsset *asset = fetchResult[0];
|
||||
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:nil resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
|
||||
if ([imageData writeToFile:toPath atomically:YES]) {
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"E_FILE_NOT_COPIED",
|
||||
[NSString stringWithFormat:@"File '%@' could not be copied to '%@'.", from, to],
|
||||
error);
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
reject(@"E_FILE_NOT_COPIED",
|
||||
[NSString stringWithFormat:@"File '%@' could not be found.", from],
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
// adapted from RCTImageLoader.m
|
||||
+ (PHFetchResult<PHAsset *> *)fetchResultForUri:(NSURL *)url error:(NSError **)error
|
||||
{
|
||||
if ([url.scheme caseInsensitiveCompare:@"ph"] == NSOrderedSame) {
|
||||
// Fetch assets using PHAsset localIdentifier (recommended)
|
||||
NSString *const localIdentifier = [url.absoluteString substringFromIndex:@"ph://".length];
|
||||
return [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
|
||||
} else if ([url.scheme caseInsensitiveCompare:@"assets-library"] == NSOrderedSame) {
|
||||
#if TARGET_OS_MACCATALYST
|
||||
static BOOL hasWarned = NO;
|
||||
if (!hasWarned) {
|
||||
NSLog(@"assets-library:// URLs have been deprecated and cannot be accessed in macOS Catalyst. Returning nil (future warnings will be suppressed).");
|
||||
hasWarned = YES;
|
||||
}
|
||||
return nil;
|
||||
#else
|
||||
// This is the older, deprecated way of fetching assets from assets-library
|
||||
// using the "assets-library://" protocol
|
||||
return [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
|
||||
#endif
|
||||
}
|
||||
|
||||
NSString *description = [NSString stringWithFormat:@"Invalid URL provided, expected scheme to be either 'ph' or 'assets-library', was '%@'.", url.scheme];
|
||||
*error = [[NSError alloc] initWithDomain:NSURLErrorDomain
|
||||
code:NSURLErrorUnsupportedURL
|
||||
userInfo:@{NSLocalizedDescriptionKey: description}];
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
6
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemLocalFileHandler.h
generated
vendored
Normal file
6
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemLocalFileHandler.h
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
#import <EXFileSystem/EXFileSystem.h>
|
||||
|
||||
@interface EXFileSystemLocalFileHandler : NSObject <EXFileSystemHandler>
|
||||
|
||||
@end
|
78
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemLocalFileHandler.m
generated
vendored
Normal file
78
node_modules/expo-file-system/ios/EXFileSystem/EXFileSystemLocalFileHandler.m
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
#import <EXFileSystem/EXFileSystemLocalFileHandler.h>
|
||||
|
||||
@implementation EXFileSystemLocalFileHandler
|
||||
|
||||
+ (void)getInfoForFile:(NSURL *)fileUri
|
||||
withOptions:(NSDictionary *)options
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject
|
||||
{
|
||||
NSString *path = fileUri.path;
|
||||
BOOL isDirectory;
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDirectory]) {
|
||||
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
|
||||
NSMutableDictionary *result = [NSMutableDictionary dictionary];
|
||||
result[@"exists"] = @(YES);
|
||||
result[@"isDirectory"] = @(isDirectory);
|
||||
result[@"uri"] = [NSURL fileURLWithPath:path].absoluteString;
|
||||
if (options[@"md5"]) {
|
||||
result[@"md5"] = [[NSData dataWithContentsOfFile:path] md5String];
|
||||
}
|
||||
result[@"size"] = @([EXFileSystemLocalFileHandler getFileSize:path attributes:attributes]);
|
||||
result[@"modificationTime"] = @(attributes.fileModificationDate.timeIntervalSince1970);
|
||||
resolve(result);
|
||||
} else {
|
||||
resolve(@{@"exists": @(NO), @"isDirectory": @(NO)});
|
||||
}
|
||||
}
|
||||
|
||||
+ (unsigned long long)getFileSize:(NSString *)path attributes:(NSDictionary<NSFileAttributeKey, id> *)attributes
|
||||
{
|
||||
if (attributes.fileType != NSFileTypeDirectory) {
|
||||
return attributes.fileSize;
|
||||
}
|
||||
|
||||
// The path is pointing to the folder
|
||||
NSArray *contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
|
||||
NSEnumerator *contentsEnumurator = [contents objectEnumerator];
|
||||
NSString *file;
|
||||
unsigned long long folderSize = 0;
|
||||
while (file = [contentsEnumurator nextObject]) {
|
||||
NSString *filePath = [path stringByAppendingPathComponent:file];
|
||||
NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
|
||||
folderSize += [EXFileSystemLocalFileHandler getFileSize:filePath attributes:fileAttributes];
|
||||
}
|
||||
|
||||
return folderSize;
|
||||
}
|
||||
|
||||
+ (void)copyFrom:(NSURL *)from
|
||||
to:(NSURL *)to
|
||||
resolver:(UMPromiseResolveBlock)resolve
|
||||
rejecter:(UMPromiseRejectBlock)reject
|
||||
{
|
||||
NSString *fromPath = [from.path stringByStandardizingPath];
|
||||
NSString *toPath = [to.path stringByStandardizingPath];
|
||||
|
||||
NSError *error;
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:toPath]) {
|
||||
if (![[NSFileManager defaultManager] removeItemAtPath:toPath error:&error]) {
|
||||
reject(@"E_FILE_NOT_COPIED",
|
||||
[NSString stringWithFormat:@"File '%@' could not be copied to '%@' because a file already exists at "
|
||||
"the destination and could not be deleted.", from, to],
|
||||
error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ([[NSFileManager defaultManager] copyItemAtPath:fromPath toPath:toPath error:&error]) {
|
||||
resolve(nil);
|
||||
} else {
|
||||
reject(@"E_FILE_NOT_COPIED",
|
||||
[NSString stringWithFormat:@"File '%@' could not be copied to '%@'.", from, to],
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
17
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXResumablesManager.h
generated
vendored
Normal file
17
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXResumablesManager.h
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EXResumablesManager : NSObject
|
||||
|
||||
- (NSURLSessionDownloadTask * _Nullable)taskForId:(NSString *)uuid;
|
||||
|
||||
- (void)registerTask:(NSURLSessionDownloadTask *)task uuid:(NSString *)uuid;
|
||||
|
||||
- (void)unregisterTask:(NSString *)uuid;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
36
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXResumablesManager.m
generated
vendored
Normal file
36
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXResumablesManager.m
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXResumablesManager.h>
|
||||
|
||||
@interface EXResumablesManager ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSURLSessionDownloadTask *> *resumableDownloads;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXResumablesManager
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_resumableDownloads = [NSMutableDictionary dictionary];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)registerTask:(NSURLSessionDownloadTask *)task uuid:(NSString *)uuid
|
||||
{
|
||||
_resumableDownloads[uuid] = task;
|
||||
}
|
||||
|
||||
- (NSURLSessionDownloadTask * _Nullable)taskForId:(NSString *)uuid
|
||||
{
|
||||
return _resumableDownloads[uuid];
|
||||
}
|
||||
|
||||
- (void)unregisterTask:(NSString *)uuid
|
||||
{
|
||||
[_resumableDownloads removeObjectForKey:uuid];
|
||||
}
|
||||
|
||||
@end
|
13
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionDownloadTaskDelegate.h
generated
vendored
Normal file
13
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionDownloadTaskDelegate.h
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionTaskDelegate.h>
|
||||
|
||||
@interface EXSessionDownloadTaskDelegate : EXSessionTaskDelegate
|
||||
|
||||
- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
|
||||
reject:(UMPromiseRejectBlock)reject
|
||||
localUrl:(NSURL *)localUrl
|
||||
shouldCalculateMd5:(BOOL)shouldCalculateMd5;
|
||||
|
||||
@end
|
||||
|
64
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionDownloadTaskDelegate.m
generated
vendored
Normal file
64
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionDownloadTaskDelegate.m
generated
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionDownloadTaskDelegate.h>
|
||||
#import <EXFileSystem/NSData+EXFileSystem.h>
|
||||
|
||||
@interface EXSessionDownloadTaskDelegate ()
|
||||
|
||||
@property (strong, nonatomic) NSURL *localUrl;
|
||||
@property (nonatomic) BOOL shouldCalculateMd5;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXSessionDownloadTaskDelegate
|
||||
|
||||
- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
|
||||
reject:(UMPromiseRejectBlock)reject
|
||||
localUrl:(NSURL *)localUrl
|
||||
shouldCalculateMd5:(BOOL)shouldCalculateMd5
|
||||
{
|
||||
if (self = [super initWithResolve:resolve reject:reject])
|
||||
{
|
||||
_localUrl = localUrl;
|
||||
_shouldCalculateMd5 = shouldCalculateMd5;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
|
||||
{
|
||||
NSError *error;
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
if ([fileManager fileExistsAtPath:_localUrl.path]) {
|
||||
[fileManager removeItemAtURL:_localUrl error:&error];
|
||||
if (error) {
|
||||
self.reject(@"ERR_FILESYSTEM_CANNOT_REMOVE",
|
||||
[NSString stringWithFormat:@"Unable to remove file from local URI: '%@'", error.description],
|
||||
error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
[fileManager moveItemAtURL:location toURL:_localUrl error:&error];
|
||||
if (error) {
|
||||
self.reject(@"ERR_FILESYSTEM_CANNOT_SAVE",
|
||||
[NSString stringWithFormat:@"Unable to save file to local URI: '%@'", error.description],
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
self.resolve([self parseServerResponse:downloadTask.response]);
|
||||
}
|
||||
|
||||
- (NSDictionary *)parseServerResponse:(NSURLResponse *)response
|
||||
{
|
||||
NSMutableDictionary *result = [[super parseServerResponse:response] mutableCopy];
|
||||
result[@"uri"] = _localUrl.absoluteString;
|
||||
if (_shouldCalculateMd5) {
|
||||
NSData *data = [NSData dataWithContentsOfURL:_localUrl];
|
||||
result[@"md5"] = [data md5String];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
19
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionHandler.h
generated
vendored
Normal file
19
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionHandler.h
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UMCore/UMSingletonModule.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol EXSessionHandler
|
||||
|
||||
- (void)invokeCompletionHandlerForSessionIdentifier:(NSString *)identifier;
|
||||
|
||||
@end
|
||||
|
||||
@interface EXSessionHandler : UMSingletonModule <UIApplicationDelegate, EXSessionHandler>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
49
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionHandler.m
generated
vendored
Normal file
49
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionHandler.m
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionHandler.h>
|
||||
|
||||
#import <UMCore/UMDefines.h>
|
||||
|
||||
@interface EXSessionHandler ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSString *, void (^)(void)> *completionHandlers;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXSessionHandler
|
||||
|
||||
UM_REGISTER_SINGLETON_MODULE(SessionHandler);
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_completionHandlers = [NSMutableDictionary dictionary];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)invokeCompletionHandlerForSessionIdentifier:(NSString *)identifier
|
||||
{
|
||||
if (!identifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
void (^completionHandler)(void) = _completionHandlers[identifier];
|
||||
if (completionHandler) {
|
||||
// We need to run completionHandler explicite on the main thread because is's part of UIKit
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completionHandler();
|
||||
});
|
||||
[_completionHandlers removeObjectForKey:identifier];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - AppDelegate
|
||||
|
||||
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler
|
||||
{
|
||||
_completionHandlers[identifier] = completionHandler;
|
||||
}
|
||||
|
||||
@end
|
18
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionResumableDownloadTaskDelegate.h
generated
vendored
Normal file
18
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionResumableDownloadTaskDelegate.h
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionDownloadTaskDelegate.h>
|
||||
#import <EXFileSystem/EXResumablesManager.h>
|
||||
|
||||
typedef void (^EXDownloadDelegateOnWriteCallback)(NSURLSessionDownloadTask *task, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite);
|
||||
|
||||
@interface EXSessionResumableDownloadTaskDelegate : EXSessionDownloadTaskDelegate
|
||||
|
||||
- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
|
||||
reject:(UMPromiseRejectBlock)reject
|
||||
localUrl:(NSURL *)localUrl
|
||||
shouldCalculateMd5:(BOOL)shouldCalculateMd5
|
||||
onWriteCallback:(EXDownloadDelegateOnWriteCallback)onWriteCallback
|
||||
resumableManager:(EXResumablesManager *)manager
|
||||
uuid:(NSString *)uuid;
|
||||
|
||||
@end
|
60
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionResumableDownloadTaskDelegate.m
generated
vendored
Normal file
60
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionResumableDownloadTaskDelegate.m
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionResumableDownloadTaskDelegate.h>
|
||||
|
||||
@interface EXSessionResumableDownloadTaskDelegate ()
|
||||
|
||||
@property (strong, nonatomic, readonly) EXDownloadDelegateOnWriteCallback onWriteCallback;
|
||||
@property (weak, nonatomic) EXResumablesManager *manager;
|
||||
@property (strong, nonatomic) NSString *uuid;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXSessionResumableDownloadTaskDelegate
|
||||
|
||||
- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
|
||||
reject:(UMPromiseRejectBlock)reject
|
||||
localUrl:(NSURL *)localUrl
|
||||
shouldCalculateMd5:(BOOL)shouldCalculateMd5
|
||||
onWriteCallback:(EXDownloadDelegateOnWriteCallback)onWriteCallback
|
||||
resumableManager:(EXResumablesManager *)manager
|
||||
uuid:(NSString *)uuid;
|
||||
{
|
||||
if (self = [super initWithResolve:resolve
|
||||
reject:reject
|
||||
localUrl:localUrl
|
||||
shouldCalculateMd5:shouldCalculateMd5]) {
|
||||
_onWriteCallback = onWriteCallback;
|
||||
_manager = manager;
|
||||
_uuid = uuid;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
||||
{
|
||||
if (error) {
|
||||
// The task was paused by us. So, we shouldn't throw.
|
||||
if (error.code == NSURLErrorCancelled) {
|
||||
self.resolve([NSNull null]);
|
||||
} else {
|
||||
self.reject(@"ERR_FILESYSTEM_CANNOT_DOWNLOAD",
|
||||
[NSString stringWithFormat:@"Unable to download file: %@", error.description],
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
[_manager unregisterTask:_uuid];
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
didWriteData:(int64_t)bytesWritten
|
||||
totalBytesWritten:(int64_t)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
{
|
||||
if (_onWriteCallback && bytesWritten > 0) {
|
||||
_onWriteCallback(downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
27
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDelegate.h
generated
vendored
Normal file
27
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDelegate.h
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UMCore/UMDefines.h>
|
||||
|
||||
@interface EXSessionTaskDelegate : NSObject
|
||||
|
||||
@property (nonatomic, strong, readonly) UMPromiseResolveBlock resolve;
|
||||
@property (nonatomic, strong, readonly) UMPromiseRejectBlock reject;
|
||||
|
||||
- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
|
||||
reject:(UMPromiseRejectBlock)reject;
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location;
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error;
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
didWriteData:(int64_t)bytesWritten
|
||||
totalBytesWritten:(int64_t)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data;
|
||||
|
||||
- (NSDictionary *)parseServerResponse:(NSURLResponse *)response;
|
||||
|
||||
@end
|
51
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDelegate.m
generated
vendored
Normal file
51
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDelegate.m
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionTaskDelegate.h>
|
||||
|
||||
@implementation EXSessionTaskDelegate
|
||||
|
||||
- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve
|
||||
reject:(UMPromiseRejectBlock)reject
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_resolve = resolve;
|
||||
_reject = reject;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
||||
{
|
||||
if (error) {
|
||||
self.reject(@"ERR_FILESYSTEM_CANNOT_DOWNLOAD",
|
||||
[NSString stringWithFormat:@"Unable to download file: %@", error.description],
|
||||
error);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSDictionary *)parseServerResponse:(NSURLResponse *)response
|
||||
{
|
||||
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
||||
return @{
|
||||
@"status": @([httpResponse statusCode]),
|
||||
@"headers": [httpResponse allHeaderFields],
|
||||
@"mimeType": UMNullIfNil([httpResponse MIMEType])
|
||||
};
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
|
||||
{
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
didWriteData:(int64_t)bytesWritten
|
||||
totalBytesWritten:(int64_t)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
{
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
19
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDispatcher.h
generated
vendored
Normal file
19
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDispatcher.h
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <EXFileSystem/EXSessionTaskDelegate.h>
|
||||
#import <EXFileSystem/EXSessionHandler.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface EXSessionTaskDispatcher : NSObject <NSURLSessionDelegate>
|
||||
|
||||
- (instancetype)initWithSessionHandler:(id<EXSessionHandler>)sessionHandler;
|
||||
|
||||
- (void)registerTaskDelegate:(EXSessionTaskDelegate *)delegate forTask:(NSURLSessionTask *)task;
|
||||
|
||||
- (void)deactivate;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
85
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDispatcher.m
generated
vendored
Normal file
85
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionTaskDispatcher.m
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionTaskDispatcher.h>
|
||||
#import <EXFileSystem/EXSessionResumableDownloadTaskDelegate.h>
|
||||
|
||||
@interface EXSessionTaskDispatcher ()
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSURLSessionTask *, EXSessionTaskDelegate *> *tasks;
|
||||
@property (nonatomic) BOOL isActive;
|
||||
@property (nonatomic, weak) id<EXSessionHandler> sessionHandler;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXSessionTaskDispatcher
|
||||
|
||||
- (instancetype)initWithSessionHandler:(id<EXSessionHandler>)sessionHandler;
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_tasks = [NSMutableDictionary dictionary];
|
||||
_isActive = true;
|
||||
_sessionHandler = sessionHandler;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - public methods
|
||||
|
||||
- (void)registerTaskDelegate:(EXSessionTaskDelegate *)delegate forTask:(NSURLSessionTask *)task
|
||||
{
|
||||
_tasks[task] = delegate;
|
||||
}
|
||||
|
||||
- (void)deactivate
|
||||
{
|
||||
_isActive = false;
|
||||
}
|
||||
|
||||
#pragma mark - dispatcher
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
|
||||
{
|
||||
if (_isActive) {
|
||||
EXSessionTaskDelegate *exTask = _tasks[downloadTask];
|
||||
if (exTask) {
|
||||
[exTask URLSession:session downloadTask:downloadTask didFinishDownloadingToURL:location];
|
||||
[_tasks removeObjectForKey:downloadTask];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
||||
{
|
||||
if (_isActive) {
|
||||
EXSessionTaskDelegate *exTask = _tasks[task];
|
||||
if (exTask) {
|
||||
[exTask URLSession:session task:task didCompleteWithError:error];
|
||||
[_tasks removeObjectForKey:task];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
|
||||
didWriteData:(int64_t)bytesWritten
|
||||
totalBytesWritten:(int64_t)totalBytesWritten
|
||||
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
|
||||
{
|
||||
if (_isActive) {
|
||||
EXSessionTaskDelegate *exTask = _tasks[downloadTask];
|
||||
[exTask URLSession:session downloadTask:downloadTask didWriteData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
|
||||
{
|
||||
if (_isActive) {
|
||||
EXSessionTaskDelegate *exTask = _tasks[dataTask];
|
||||
[exTask URLSession:session dataTask:dataTask didReceiveData:data];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session {
|
||||
[_sessionHandler invokeCompletionHandlerForSessionIdentifier:session.configuration.identifier];
|
||||
}
|
||||
|
||||
@end
|
8
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionUploadTaskDelegate.h
generated
vendored
Normal file
8
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionUploadTaskDelegate.h
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionTaskDelegate.h>
|
||||
|
||||
@interface EXSessionUploadTaskDelegate : EXSessionTaskDelegate
|
||||
|
||||
@end
|
||||
|
52
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionUploadTaskDelegate.m
generated
vendored
Normal file
52
node_modules/expo-file-system/ios/EXFileSystem/EXSessionTasks/EXSessionUploadTaskDelegate.m
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/EXSessionUploadTaskDelegate.h>
|
||||
|
||||
@interface EXSessionUploadTaskDelegate ()
|
||||
|
||||
@property (strong, nonatomic) NSMutableData *responseData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation EXSessionUploadTaskDelegate
|
||||
|
||||
- (instancetype)initWithResolve:(UMPromiseResolveBlock)resolve reject:(UMPromiseRejectBlock)reject
|
||||
{
|
||||
if (self = [super initWithResolve:resolve reject:reject]) {
|
||||
_responseData = [NSMutableData new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
|
||||
{
|
||||
if (!data.length) {
|
||||
return;
|
||||
}
|
||||
[_responseData appendData:data];
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
||||
{
|
||||
if (error) {
|
||||
self.reject(@"ERR_FILESYSTEM_CANNOT_UPLOAD",
|
||||
[NSString stringWithFormat:@"Unable to upload the file: '%@'", error.description],
|
||||
error);
|
||||
return;
|
||||
}
|
||||
|
||||
// We only set EXSessionUploadTaskDelegates as delegates of upload tasks
|
||||
// so it should be safe to assume that this is what we will receive here.
|
||||
NSURLSessionUploadTask *uploadTask = (NSURLSessionUploadTask *)task;
|
||||
self.resolve([self parseServerResponse:uploadTask.response]);
|
||||
}
|
||||
|
||||
- (NSDictionary *)parseServerResponse:(NSURLResponse *)response
|
||||
{
|
||||
NSMutableDictionary *result = [[super parseServerResponse:response] mutableCopy];
|
||||
// TODO: add support for others response types (different encodings, files)
|
||||
result[@"body"] = UMNullIfNil([[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding]);
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
7
node_modules/expo-file-system/ios/EXFileSystem/NSData+EXFileSystem.h
generated
vendored
Normal file
7
node_modules/expo-file-system/ios/EXFileSystem/NSData+EXFileSystem.h
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
@interface NSData (EXFileSystem)
|
||||
|
||||
- (NSString *)md5String;
|
||||
|
||||
@end
|
19
node_modules/expo-file-system/ios/EXFileSystem/NSData+EXFileSystem.m
generated
vendored
Normal file
19
node_modules/expo-file-system/ios/EXFileSystem/NSData+EXFileSystem.m
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2015-present 650 Industries. All rights reserved.
|
||||
|
||||
#import <EXFileSystem/NSData+EXFileSystem.h>
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
|
||||
@implementation NSData (EXFileSystem)
|
||||
|
||||
- (NSString *)md5String
|
||||
{
|
||||
unsigned char digest[CC_MD5_DIGEST_LENGTH];
|
||||
CC_MD5(self.bytes, (CC_LONG) self.length, digest);
|
||||
NSMutableString *md5 = [NSMutableString stringWithCapacity:2 * CC_MD5_DIGEST_LENGTH];
|
||||
for (unsigned int i = 0; i < CC_MD5_DIGEST_LENGTH; ++i) {
|
||||
[md5 appendFormat:@"%02x", digest[i]];
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
|
||||
@end
|
Reference in New Issue
Block a user