diff --git a/ios/RNFirebase/RNFirebaseStorage.m b/ios/RNFirebase/RNFirebaseStorage.m index 52715126..2d303995 100644 --- a/ios/RNFirebase/RNFirebaseStorage.m +++ b/ios/RNFirebase/RNFirebaseStorage.m @@ -8,163 +8,234 @@ RCT_EXPORT_MODULE(RNFirebaseStorage); // Run on a different thread -- (dispatch_queue_t)methodQueue -{ - return dispatch_queue_create("com.invertase.firebase.storage", DISPATCH_QUEUE_SERIAL); +- (dispatch_queue_t)methodQueue { + return dispatch_queue_create("com.invertase.firebase.storage", DISPATCH_QUEUE_SERIAL); } -RCT_EXPORT_METHOD(delete: (NSString *) path - callback:(RCTResponseSenderBlock) callback) -{ +/** + Reject a promise with a storage exception + + @param reject RCTPromiseRejectBlock + @param error NSError + */ +- (void) promiseRejectStorageException:(RCTPromiseRejectBlock) reject error:(NSError *)error { + NSString *code = @"storage/unknown"; + NSString *message = [error localizedDescription]; + + switch (error.code) { + case FIRStorageErrorCodeUnknown: + code = @"storage/unknown"; + message = @"An unknown error has occurred."; + break; + case FIRStorageErrorCodeObjectNotFound: + code = @"storage/object-not-found"; + message = @"No object exists at the desired reference."; + break; + case FIRStorageErrorCodeBucketNotFound: + code = @"storage/bucket-not-found"; + message = @"No bucket is configured for Firebase Storage."; + break; + case FIRStorageErrorCodeProjectNotFound: + code = @"storage/project-not-found"; + message = @"No project is configured for Firebase Storage."; + break; + case FIRStorageErrorCodeQuotaExceeded: + code = @"storage/quota-exceeded"; + message = @"Quota on your Firebase Storage bucket has been exceeded."; + break; + case FIRStorageErrorCodeUnauthenticated: + code = @"storage/unauthenticated"; + message = @"User is unauthenticated. Authenticate and try again."; + break; + case FIRStorageErrorCodeUnauthorized: + code = @"storage/unauthorized"; + message = @"User is not authorized to perform the desired action."; + break; + case FIRStorageErrorCodeRetryLimitExceeded: + code = @"storage/retry-limit-exceeded"; + message = @"The maximum time limit on an operation (upload, download, delete, etc.) has been exceeded."; + break; + case FIRStorageErrorCodeNonMatchingChecksum: + code = @"storage/non-matching-checksum"; + message = @"File on the client does not match the checksum of the file received by the server."; + break; + case FIRStorageErrorCodeDownloadSizeExceeded: + code = @"storage/download-size-exceeded"; + message = @"Size of the downloaded file exceeds the amount of memory allocated for the download."; + break; + case FIRStorageErrorCodeCancelled: + code = @"storage/cancelled"; + message = @"User cancelled the operation."; + break; + default: + break; + } + + reject(code, message, error); +} + +/** + delete + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#delete + @param NSString path + */ +RCT_EXPORT_METHOD(delete: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { FIRStorageReference *fileRef = [self getReference:path]; + [fileRef deleteWithCompletion:^(NSError * _Nullable error) { - if (error == nil) { - NSDictionary *resp = @{ - @"status": @"success", - @"path": path - }; - callback(@[[NSNull null], resp]); + if (error != nil) { + [self promiseRejectStorageException:reject error: error]; } else { - NSDictionary *evt = @{ - @"status": @"error", - @"path": path, - @"message": [error debugDescription] - }; - callback(@[evt]); + resolve([NSNull null]); } }]; } -RCT_EXPORT_METHOD(getDownloadURL: (NSString *) path - callback:(RCTResponseSenderBlock) callback) -{ +/** + getDownloadURL + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getDownloadURL + @param NSString path + */ +RCT_EXPORT_METHOD(getDownloadURL: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { FIRStorageReference *fileRef = [self getReference:path]; + [fileRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) { if (error != nil) { - NSDictionary *evt = @{ - @"status": @"error", - @"path": path, - @"message": [error debugDescription] - }; - callback(@[evt]); + [self promiseRejectStorageException:reject error: error]; } else { - callback(@[[NSNull null], [URL absoluteString]]); + resolve([URL absoluteString]); } }]; } -RCT_EXPORT_METHOD(getMetadata: (NSString *) path - callback:(RCTResponseSenderBlock) callback) -{ +/** + getMetaData + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#getMetaData + @param NSString path + */ +RCT_EXPORT_METHOD(getMetaData: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { FIRStorageReference *fileRef = [self getReference:path]; + [fileRef metadataWithCompletion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) { if (error != nil) { - NSDictionary *evt = @{ - @"status": @"error", - @"path": path, - @"message": [error debugDescription] - }; - callback(@[evt]); + [self promiseRejectStorageException:reject error: error]; } else { - NSDictionary *resp = [metadata dictionaryRepresentation]; - callback(@[[NSNull null], resp]); + resolve([metadata dictionaryRepresentation]); } }]; } -RCT_EXPORT_METHOD(updateMetadata: (NSString *) path - metadata:(NSDictionary *) metadata - callback:(RCTResponseSenderBlock) callback) -{ +/** + updateMetadata + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#updateMetadata + @param NSString path + @param NSDictionary metadata + */ +RCT_EXPORT_METHOD(updateMetadata: (NSString *) path metadata:(NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { FIRStorageReference *fileRef = [self getReference:path]; FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata]; + [fileRef updateMetadata:firmetadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) { if (error != nil) { - NSDictionary *evt = @{ - @"status": @"error", - @"path": path, - @"message": [error debugDescription] - }; - callback(@[evt]); + [self promiseRejectStorageException:reject error: error]; } else { - NSDictionary *resp = [metadata dictionaryRepresentation]; - callback(@[[NSNull null], resp]); + resolve([metadata dictionaryRepresentation]); } }]; } -RCT_EXPORT_METHOD(downloadFile: (NSString *) path - localPath:(NSString *) localPath - callback:(RCTResponseSenderBlock) callback) -{ +/** + downloadFile + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#downloadFile + @param NSString path + @param NSString localPath + */ +RCT_EXPORT_METHOD(downloadFile: (NSString *) path localPath:(NSString *) localPath resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { FIRStorageReference *fileRef = [self getReference:path]; NSURL *localFile = [NSURL fileURLWithPath:localPath]; - FIRStorageDownloadTask *downloadTask = [fileRef writeToFile:localFile]; - // Listen for state changes, errors, and completion of the download. + + // listen for state changes, errors, and completion of the download. [downloadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) { - // Download resumed, also fires when the upload starts + // download resumed, also fires when the upload starts NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; }]; - + [downloadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) { - // Download paused + // download paused NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; }]; + [downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { - // Download reported progress + // download reported progress NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; }]; - + [downloadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) { - // Download completed successfully + // download completed successfully NSDictionary *resp = [self getDownloadTaskAsDictionary:snapshot]; - [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_DOWNLOAD_SUCCESS props:resp]; - callback(@[[NSNull null], resp]); + resolve(resp); }]; - + [downloadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) { + // download task failed if (snapshot.error != nil) { - NSDictionary *errProps = [[NSMutableDictionary alloc] init]; - NSLog(@"Error in download: %@", snapshot.error); - - switch (snapshot.error.code) { - case FIRStorageErrorCodeObjectNotFound: - // File doesn't exist - [errProps setValue:@"File does not exist" forKey:@"message"]; - break; - case FIRStorageErrorCodeUnauthorized: - // User doesn't have permission to access file - [errProps setValue:@"You do not have permissions" forKey:@"message"]; - break; - case FIRStorageErrorCodeCancelled: - // User canceled the upload - [errProps setValue:@"Download canceled" forKey:@"message"]; - break; - case FIRStorageErrorCodeUnknown: - // Unknown error occurred, inspect the server response - [errProps setValue:@"Unknown error" forKey:@"message"]; - break; - } - - //TODO: Error event - callback(@[errProps]); - }}]; + [self promiseRejectStorageException:reject error:snapshot.error]; + } + }]; } +/** + setMaxDownloadRetryTime + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxDownloadRetryTime + @param NSNumber milliseconds + */ +RCT_EXPORT_METHOD(setMaxDownloadRetryTime:(NSNumber *) milliseconds) { + [[FIRStorage storage] setMaxDownloadRetryTime:[milliseconds doubleValue]]; +} -RCT_EXPORT_METHOD(putFile:(NSString *) path - localPath:(NSString *)localPath - metadata:(NSDictionary *)metadata - callback:(RCTResponseSenderBlock) callback) -{ +/** + setMaxOperationRetryTime + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxOperationRetryTime + @param NSNumber milliseconds + */ +RCT_EXPORT_METHOD(setMaxOperationRetryTime:(NSNumber *) milliseconds) { + [[FIRStorage storage] setMaxOperationRetryTime:[milliseconds doubleValue]]; +} + +/** + setMaxUploadRetryTime + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Storage#setMaxUploadRetryTime + */ +RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSNumber *) milliseconds) { + [[FIRStorage storage] setMaxUploadRetryTime:[milliseconds doubleValue]]; +} + +/** + putFile + + @url https://firebase.google.com/docs/reference/js/firebase.storage.Reference#putFile + @param NSString path + @param NSString localPath + @param NSDictionary metadata + */ +RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath metadata:(NSDictionary *)metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { if ([localPath hasPrefix:@"assets-library://"] || [localPath hasPrefix:@"ph://"]) { PHFetchResult* assets; + if ([localPath hasPrefix:@"assets-library://"]) { NSURL *localFile = [[NSURL alloc] initWithString:localPath]; assets = [PHAsset fetchAssetsWithALAssetURLs:@[localFile] options:nil]; @@ -172,174 +243,109 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path NSString *assetId = [localPath substringFromIndex:@"ph://".length]; assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]; } + PHAsset *asset = [assets firstObject]; - - //NOTE: This is all based on http://stackoverflow.com/questions/35241449 + + // this is based on http://stackoverflow.com/questions/35241449 if (asset.mediaType == PHAssetMediaTypeImage) { + // images PHImageRequestOptions *options = [PHImageRequestOptions new]; options.networkAccessAllowed = true; - [[PHImageManager defaultManager] requestImageDataForAsset:asset - options:options - resultHandler:^(NSData * imageData, NSString * dataUTI, UIImageOrientation orientation, NSDictionary * info) { - if ([info objectForKey:PHImageErrorKey] == nil) { - [self uploadData:imageData metadata:metadata path:path callback:callback]; - } else { - NSDictionary *errProps = [[NSMutableDictionary alloc] init]; - [errProps setValue:@"Could not obtain image data" forKey:@"message"]; - //TODO: Error event - callback(@[errProps]); - } - }]; + [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * imageData, NSString * dataUTI, UIImageOrientation orientation, NSDictionary * info) { + if ([info objectForKey:PHImageErrorKey] == nil) { + [self uploadData:imageData metadata:metadata path:path resolver:resolve rejecter:reject]; + } else { + reject(@"storage/request-image-data-failed", @"Could not obtain image data for the specified file.", nil); + } + }]; } else if (asset.mediaType == PHAssetMediaTypeVideo) { + // video PHVideoRequestOptions *options = [PHVideoRequestOptions new]; options.networkAccessAllowed = true; - [[PHImageManager defaultManager] requestExportSessionForVideo:asset - options:options - exportPreset:AVAssetExportPresetHighestQuality - resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) { - if ([info objectForKey:PHImageErrorKey] == nil) { - NSURL *tempUrl = [self temporaryFileUrl]; - exportSession.outputURL = tempUrl; - - NSArray *resources = [PHAssetResource assetResourcesForAsset:asset]; - for (PHAssetResource *resource in resources) - { - exportSession.outputFileType = resource.uniformTypeIdentifier; - if (exportSession.outputFileType != nil) - break; - } - - [exportSession exportAsynchronouslyWithCompletionHandler:^{ - if (exportSession.status == AVAssetExportSessionStatusCompleted) - { - [self uploadFile:tempUrl metadata:metadata path:path callback:callback]; - //NOTE: we're not cleaning up the temporary file at the moment, just relying on the OS to do that in it's own time - } else { - NSDictionary *errProps = [[NSMutableDictionary alloc] init]; - [errProps setValue:@"Could not create temporary file for upload" forKey:@"message"]; - //TODO: Error event - callback(@[errProps]); - } - }]; - } else { - NSDictionary *errProps = [[NSMutableDictionary alloc] init]; - [errProps setValue:@"Could not create export session for asset" forKey:@"message"]; - //TODO: Error event - callback(@[errProps]); - } - }]; + [[PHImageManager defaultManager] requestExportSessionForVideo:asset options:options exportPreset:AVAssetExportPresetHighestQuality resultHandler:^(AVAssetExportSession * _Nullable exportSession, NSDictionary * _Nullable info) { + if ([info objectForKey:PHImageErrorKey] == nil) { + NSURL *tempUrl = [self temporaryFileUrl]; + exportSession.outputURL = tempUrl; + + NSArray *resources = [PHAssetResource assetResourcesForAsset:asset]; + for (PHAssetResource *resource in resources) { + exportSession.outputFileType = resource.uniformTypeIdentifier; + if (exportSession.outputFileType != nil) break; + } + + [exportSession exportAsynchronouslyWithCompletionHandler:^{ + if (exportSession.status == AVAssetExportSessionStatusCompleted) { + [self uploadFile:tempUrl metadata:metadata path:path resolver:resolve rejecter:reject]; + // we're not cleaning up the temporary file at the moment, just relying on the OS to do that in it's own time - todo? + } else { + reject(@"storage/temporary-file-failure", @"Unable to create temporary file for upload.", nil); + } + }]; + } else { + reject(@"storage/export-session-failure", @"Unable to create export session for asset.", nil); + } + }]; } } else { NSURL *fileUrl = [NSURL fileURLWithPath:localPath]; - [self uploadFile:fileUrl metadata:metadata path:path callback:callback]; + [self uploadFile:fileUrl metadata:metadata path:path resolver:resolve rejecter:reject]; } - + } -- (NSURL *) temporaryFileUrl -{ +- (NSURL *) temporaryFileUrl { NSString *filename = [NSString stringWithFormat:@"%@.tmp", [[NSProcessInfo processInfo] globallyUniqueString]]; return [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:filename]; } -- (void) uploadFile:(NSURL *) url - metadata:(NSDictionary *) metadata - path:(NSString *) path - callback:(RCTResponseSenderBlock) callback -{ +- (void) uploadFile:(NSURL *) url metadata:(NSDictionary *) metadata path:(NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject { FIRStorageReference *fileRef = [self getReference:path]; FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata]; FIRStorageUploadTask *uploadTask = [fileRef putFile:url metadata:firmetadata]; - [self addUploadObservers:uploadTask path:path callback:callback]; + [self addUploadObservers:uploadTask path:path resolver:resolve rejecter:reject]; } -- (void) uploadData:(NSData *) data - metadata:(NSDictionary *) metadata - path:(NSString *) path - callback:(RCTResponseSenderBlock) callback -{ +- (void) uploadData:(NSData *) data metadata:(NSDictionary *) metadata path:(NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject{ FIRStorageReference *fileRef = [self getReference:path]; FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata]; FIRStorageUploadTask *uploadTask = [fileRef putData:data metadata:firmetadata]; - [self addUploadObservers:uploadTask path:path callback:callback]; + [self addUploadObservers:uploadTask path:path resolver:resolve rejecter:reject]; } -- (void) addUploadObservers:(FIRStorageUploadTask *) uploadTask - path:(NSString *) path - callback:(RCTResponseSenderBlock) callback -{ - // Listen for state changes, errors, and completion of the upload. +- (void) addUploadObservers:(FIRStorageUploadTask *) uploadTask path:(NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject{ + // listen for state changes, errors, and completion of the upload. [uploadTask observeStatus:FIRStorageTaskStatusResume handler:^(FIRStorageTaskSnapshot *snapshot) { - // Upload resumed, also fires when the upload starts + // upload resumed, also fires when the upload starts NSDictionary *event = [self getUploadTaskAsDictionary:snapshot]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; }]; - + [uploadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) { - // Upload paused + // upload paused NSDictionary *event = [self getUploadTaskAsDictionary:snapshot]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; }]; [uploadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { - // Upload reported progress + // upload reported progress NSDictionary *event = [self getUploadTaskAsDictionary:snapshot]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; }]; - + [uploadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) { - // Upload completed successfully + // upload completed successfully NSDictionary *resp = [self getUploadTaskAsDictionary:snapshot]; - [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_UPLOAD_SUCCESS props:resp]; - callback(@[[NSNull null], resp]); + resolve(resp); }]; - + [uploadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) { if (snapshot.error != nil) { - NSDictionary *errProps = [[NSMutableDictionary alloc] init]; - - switch (snapshot.error.code) { - case FIRStorageErrorCodeObjectNotFound: - // File doesn't exist - [errProps setValue:@"File does not exist" forKey:@"message"]; - break; - case FIRStorageErrorCodeUnauthorized: - // User doesn't have permission to access file - [errProps setValue:@"You do not have permissions" forKey:@"message"]; - break; - case FIRStorageErrorCodeCancelled: - // User canceled the upload - [errProps setValue:@"Upload cancelled" forKey:@"message"]; - break; - case FIRStorageErrorCodeUnknown: - // Unknown error occurred, inspect the server response - [errProps setValue:@"Unknown error" forKey:@"message"]; - break; - } - - //TODO: Error event - callback(@[errProps]); - }}]; + [self promiseRejectStorageException:reject error:snapshot.error]; + } + }]; } -//Firebase.Storage methods -RCT_EXPORT_METHOD(setMaxDownloadRetryTime:(NSNumber *) milliseconds) -{ - [[FIRStorage storage] setMaxDownloadRetryTime:[milliseconds doubleValue]]; -} - -RCT_EXPORT_METHOD(setMaxOperationRetryTime:(NSNumber *) milliseconds) -{ - [[FIRStorage storage] setMaxOperationRetryTime:[milliseconds doubleValue]]; -} - -RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSNumber *) milliseconds) -{ - [[FIRStorage storage] setMaxUploadRetryTime:[milliseconds doubleValue]]; -} - -- (FIRStorageReference *)getReference:(NSString *)path -{ +- (FIRStorageReference *)getReference:(NSString *)path { if ([path hasPrefix:@"url::"]) { NSString *url = [path substringFromIndex:5]; return [[FIRStorage storage] referenceForURL:url]; @@ -357,8 +363,7 @@ RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSNumber *) milliseconds) }; } -- (NSDictionary *)getUploadTaskAsDictionary:(FIRStorageTaskSnapshot *)task -{ +- (NSDictionary *)getUploadTaskAsDictionary:(FIRStorageTaskSnapshot *)task { NSString *downloadUrl = [task.metadata.downloadURL absoluteString]; FIRStorageMetadata *metadata = [task.metadata dictionaryRepresentation]; return @{ @@ -371,8 +376,7 @@ RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSNumber *) milliseconds) }; } -- (NSString *)getTaskStatus:(FIRStorageTaskStatus)status -{ +- (NSString *)getTaskStatus:(FIRStorageTaskStatus)status { if (status == FIRStorageTaskStatusResume || status == FIRStorageTaskStatusProgress) { return @"RUNNING"; } else if (status == FIRStorageTaskStatusPause) { @@ -386,60 +390,38 @@ RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSNumber *) milliseconds) } } -// This is just too good not to use, but I don't want to take credit for -// this work from RNFS -// https://github.com/johanneslumpe/react-native-fs/blob/master/RNFSManager.m -- (NSString *)getPathForDirectory:(int)directory -{ - NSArray *paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES); - return [paths firstObject]; +- (NSString *)getPathForDirectory:(int)directory { + NSArray *paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES); + return [paths firstObject]; } -- (NSDictionary *)constantsToExport -{ - return @{ - @"MAIN_BUNDLE_PATH": [[NSBundle mainBundle] bundlePath], - @"CACHES_DIRECTORY_PATH": [self getPathForDirectory:NSCachesDirectory], - @"DOCUMENT_DIRECTORY_PATH": [self getPathForDirectory:NSDocumentDirectory], - @"EXTERNAL_DIRECTORY_PATH": [NSNull null], - @"EXTERNAL_STORAGE_DIRECTORY_PATH": [NSNull null], - @"TEMP_DIRECTORY_PATH": NSTemporaryDirectory(), - @"LIBRARY_DIRECTORY_PATH": [self getPathForDirectory:NSLibraryDirectory], - @"FILETYPE_REGULAR": NSFileTypeRegular, - @"FILETYPE_DIRECTORY": NSFileTypeDirectory - }; +- (NSDictionary *)constantsToExport { + return @{ + @"MAIN_BUNDLE_PATH": [[NSBundle mainBundle] bundlePath], + @"CACHES_DIRECTORY_PATH": [self getPathForDirectory:NSCachesDirectory], + @"DOCUMENT_DIRECTORY_PATH": [self getPathForDirectory:NSDocumentDirectory], + @"EXTERNAL_DIRECTORY_PATH": [NSNull null], + @"EXTERNAL_STORAGE_DIRECTORY_PATH": [NSNull null], + @"TEMP_DIRECTORY_PATH": NSTemporaryDirectory(), + @"LIBRARY_DIRECTORY_PATH": [self getPathForDirectory:NSLibraryDirectory], + @"FILETYPE_REGULAR": NSFileTypeRegular, + @"FILETYPE_DIRECTORY": NSFileTypeDirectory + }; } -// Not sure how to get away from this... yet - (NSArray *)supportedEvents { return @[STORAGE_EVENT, STORAGE_ERROR]; } -- (void) sendJSError:(NSError *) error - withPath:(NSString *) path -{ - NSDictionary *evt = @{ - @"path": path, - @"message": [error debugDescription] - }; +- (void) sendJSError:(NSError *) error withPath:(NSString *) path { + NSDictionary *evt = @{ @"path": path, @"message": [error debugDescription] }; [self sendJSEvent:STORAGE_ERROR path:path title:STORAGE_ERROR props: evt]; } -- (void) sendJSEvent:(NSString *)type - path:(NSString *)path - title:(NSString *)title - props:(NSDictionary *)props -{ +- (void) sendJSEvent:(NSString *)type path:(NSString *)path title:(NSString *)title props:(NSDictionary *)props { @try { - [self sendEventWithName:type - body:@{ - @"eventName": title, - @"path": path, - @"body": props - }]; - - } - @catch (NSException *err) { + [self sendEventWithName:type body:@{ @"eventName": title, @"path": path, @"body": props }]; + } @catch (NSException *err) { NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]); NSLog(@"Tried to send: %@ with %@", title, props); }