[ios][storage] now detects if pod installed (makes the pod an optional dependency)

This commit is contained in:
Salakar 2017-05-25 15:14:01 +01:00
parent 410f260fc0
commit 531acece76
2 changed files with 34 additions and 28 deletions

View File

@ -1,7 +1,6 @@
#ifndef RNFirebaseStorage_h #ifndef RNFirebaseStorage_h
#define RNFirebaseStorage_h #define RNFirebaseStorage_h
#import "Firebase.h"
#if __has_include(<React/RCTEventEmitter.h>) #if __has_include(<React/RCTEventEmitter.h>)
#import <React/RCTEventEmitter.h> #import <React/RCTEventEmitter.h>
#else // Compatibility for RN version < 0.40 #else // Compatibility for RN version < 0.40
@ -17,8 +16,6 @@
} }
@property (nonatomic) NSString *_storageUrl;
@end @end
#endif #endif

View File

@ -1,7 +1,9 @@
#import "RNFirebaseStorage.h" #import "RNFirebaseStorage.h"
#import "RNFirebaseEvents.h"
#if __has_include(<FirebaseStorage/FIRStorage.h>)
#import "RNFirebaseEvents.h"
#import <Photos/Photos.h> #import <Photos/Photos.h>
#import "Firebase.h"
@implementation RNFirebaseStorage @implementation RNFirebaseStorage
@ -21,11 +23,11 @@ RCT_EXPORT_MODULE(RNFirebaseStorage);
- (void) promiseRejectStorageException:(RCTPromiseRejectBlock) reject error:(NSError *)error { - (void) promiseRejectStorageException:(RCTPromiseRejectBlock) reject error:(NSError *)error {
NSString *code = @"storage/unknown"; NSString *code = @"storage/unknown";
NSString *message = [error localizedDescription]; NSString *message = [error localizedDescription];
NSDictionary *userInfo = [error userInfo]; NSDictionary *userInfo = [error userInfo];
NSError *underlyingError = [userInfo objectForKey:NSUnderlyingErrorKey]; NSError *underlyingError = userInfo[NSUnderlyingErrorKey];
NSString *underlyingErrorDescription = [underlyingError localizedDescription]; NSString *underlyingErrorDescription = [underlyingError localizedDescription];
switch (error.code) { switch (error.code) {
case FIRStorageErrorCodeUnknown: case FIRStorageErrorCodeUnknown:
if ([underlyingErrorDescription isEqualToString:@"The operation couldnt be completed. Permission denied"]) { if ([underlyingErrorDescription isEqualToString:@"The operation couldnt be completed. Permission denied"]) {
@ -79,8 +81,8 @@ RCT_EXPORT_MODULE(RNFirebaseStorage);
default: default:
break; break;
} }
if (userInfo != nil && [userInfo objectForKey:@"data"]) { if (userInfo != nil && userInfo[@"data"]) {
// errors with 'data' are unserializable - it breaks react so we send nil instead // errors with 'data' are unserializable - it breaks react so we send nil instead
reject(code, message, nil); reject(code, message, nil);
} else { } else {
@ -97,7 +99,7 @@ RCT_EXPORT_MODULE(RNFirebaseStorage);
*/ */
RCT_EXPORT_METHOD(delete: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(delete: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
FIRStorageReference *fileRef = [self getReference:path]; FIRStorageReference *fileRef = [self getReference:path];
[fileRef deleteWithCompletion:^(NSError * _Nullable error) { [fileRef deleteWithCompletion:^(NSError * _Nullable error) {
if (error != nil) { if (error != nil) {
[self promiseRejectStorageException:reject error: error]; [self promiseRejectStorageException:reject error: error];
@ -115,7 +117,7 @@ RCT_EXPORT_METHOD(delete: (NSString *) path resolver:(RCTPromiseResolveBlock)res
*/ */
RCT_EXPORT_METHOD(getDownloadURL: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(getDownloadURL: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
FIRStorageReference *fileRef = [self getReference:path]; FIRStorageReference *fileRef = [self getReference:path];
[fileRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) { [fileRef downloadURLWithCompletion:^(NSURL * _Nullable URL, NSError * _Nullable error) {
if (error != nil) { if (error != nil) {
[self promiseRejectStorageException:reject error: error]; [self promiseRejectStorageException:reject error: error];
@ -133,7 +135,7 @@ RCT_EXPORT_METHOD(getDownloadURL: (NSString *) path resolver:(RCTPromiseResolveB
*/ */
RCT_EXPORT_METHOD(getMetadata: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(getMetadata: (NSString *) path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
FIRStorageReference *fileRef = [self getReference:path]; FIRStorageReference *fileRef = [self getReference:path];
[fileRef metadataWithCompletion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) { [fileRef metadataWithCompletion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
if (error != nil) { if (error != nil) {
[self promiseRejectStorageException:reject error: error]; [self promiseRejectStorageException:reject error: error];
@ -153,7 +155,7 @@ RCT_EXPORT_METHOD(getMetadata: (NSString *) path resolver:(RCTPromiseResolveBloc
RCT_EXPORT_METHOD(updateMetadata: (NSString *) path metadata:(NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { RCT_EXPORT_METHOD(updateMetadata: (NSString *) path metadata:(NSDictionary *) metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
FIRStorageReference *fileRef = [self getReference:path]; FIRStorageReference *fileRef = [self getReference:path];
FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata]; FIRStorageMetadata *firmetadata = [[FIRStorageMetadata alloc] initWithDictionary:metadata];
[fileRef updateMetadata:firmetadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) { [fileRef updateMetadata:firmetadata completion:^(FIRStorageMetadata * _Nullable metadata, NSError * _Nullable error) {
if (error != nil) { if (error != nil) {
[self promiseRejectStorageException:reject error: error]; [self promiseRejectStorageException:reject error: error];
@ -174,33 +176,33 @@ RCT_EXPORT_METHOD(downloadFile: (NSString *) path localPath:(NSString *) localPa
FIRStorageReference *fileRef = [self getReference:path]; FIRStorageReference *fileRef = [self getReference:path];
NSURL *localFile = [NSURL fileURLWithPath:localPath]; NSURL *localFile = [NSURL fileURLWithPath:localPath];
FIRStorageDownloadTask *downloadTask = [fileRef writeToFile:localFile]; 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) { [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]; NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot];
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
}]; }];
[downloadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) { [downloadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) {
// download paused // download paused
NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot];
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
}]; }];
[downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) { [downloadTask observeStatus:FIRStorageTaskStatusProgress handler:^(FIRStorageTaskSnapshot *snapshot) {
// download reported progress // download reported progress
NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot]; NSDictionary *event = [self getDownloadTaskAsDictionary:snapshot];
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
}]; }];
[downloadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) { [downloadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) {
// download completed successfully // download completed successfully
NSDictionary *resp = [self getDownloadTaskAsDictionary:snapshot]; NSDictionary *resp = [self getDownloadTaskAsDictionary:snapshot];
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_DOWNLOAD_SUCCESS props:resp]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_DOWNLOAD_SUCCESS props:resp];
resolve(resp); resolve(resp);
}]; }];
[downloadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) { [downloadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) {
// download task failed // download task failed
// TODO sendJSError event // TODO sendJSError event
@ -250,7 +252,7 @@ RCT_EXPORT_METHOD(setMaxUploadRetryTime:(NSNumber *) milliseconds) {
RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath metadata:(NSDictionary *)metadata resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { 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://"]) { if ([localPath hasPrefix:@"assets-library://"] || [localPath hasPrefix:@"ph://"]) {
PHFetchResult* assets; PHFetchResult* assets;
if ([localPath hasPrefix:@"assets-library://"]) { if ([localPath hasPrefix:@"assets-library://"]) {
NSURL *localFile = [[NSURL alloc] initWithString:localPath]; NSURL *localFile = [[NSURL alloc] initWithString:localPath];
assets = [PHAsset fetchAssetsWithALAssetURLs:@[localFile] options:nil]; assets = [PHAsset fetchAssetsWithALAssetURLs:@[localFile] options:nil];
@ -258,16 +260,16 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
NSString *assetId = [localPath substringFromIndex:@"ph://".length]; NSString *assetId = [localPath substringFromIndex:@"ph://".length];
assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil]; assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil];
} }
PHAsset *asset = [assets firstObject]; PHAsset *asset = [assets firstObject];
// this is based on http://stackoverflow.com/questions/35241449 // this is based on http://stackoverflow.com/questions/35241449
if (asset.mediaType == PHAssetMediaTypeImage) { if (asset.mediaType == PHAssetMediaTypeImage) {
// images // images
PHImageRequestOptions *options = [PHImageRequestOptions new]; PHImageRequestOptions *options = [PHImageRequestOptions new];
options.networkAccessAllowed = true; options.networkAccessAllowed = true;
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * imageData, NSString * dataUTI, UIImageOrientation orientation, NSDictionary * info) { [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData * imageData, NSString * dataUTI, UIImageOrientation orientation, NSDictionary * info) {
if ([info objectForKey:PHImageErrorKey] == nil) { if (info[PHImageErrorKey] == nil) {
[self uploadData:imageData metadata:metadata path:path resolver:resolve rejecter:reject]; [self uploadData:imageData metadata:metadata path:path resolver:resolve rejecter:reject];
} else { } else {
reject(@"storage/request-image-data-failed", @"Could not obtain image data for the specified file.", nil); reject(@"storage/request-image-data-failed", @"Could not obtain image data for the specified file.", nil);
@ -281,13 +283,13 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
if ([info objectForKey:PHImageErrorKey] == nil) { if ([info objectForKey:PHImageErrorKey] == nil) {
NSURL *tempUrl = [self temporaryFileUrl]; NSURL *tempUrl = [self temporaryFileUrl];
exportSession.outputURL = tempUrl; exportSession.outputURL = tempUrl;
NSArray<PHAssetResource *> *resources = [PHAssetResource assetResourcesForAsset:asset]; NSArray<PHAssetResource *> *resources = [PHAssetResource assetResourcesForAsset:asset];
for (PHAssetResource *resource in resources) { for (PHAssetResource *resource in resources) {
exportSession.outputFileType = resource.uniformTypeIdentifier; exportSession.outputFileType = resource.uniformTypeIdentifier;
if (exportSession.outputFileType != nil) break; if (exportSession.outputFileType != nil) break;
} }
[exportSession exportAsynchronouslyWithCompletionHandler:^{ [exportSession exportAsynchronouslyWithCompletionHandler:^{
if (exportSession.status == AVAssetExportSessionStatusCompleted) { if (exportSession.status == AVAssetExportSessionStatusCompleted) {
[self uploadFile:tempUrl metadata:metadata path:path resolver:resolve rejecter:reject]; [self uploadFile:tempUrl metadata:metadata path:path resolver:resolve rejecter:reject];
@ -305,7 +307,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
NSData *data = [[NSFileManager defaultManager] contentsAtPath:localPath]; NSData *data = [[NSFileManager defaultManager] contentsAtPath:localPath];
[self uploadData:data metadata:metadata path:path resolver:resolve rejecter:reject]; [self uploadData:data metadata:metadata path:path resolver:resolve rejecter:reject];
} }
} }
- (NSURL *) temporaryFileUrl { - (NSURL *) temporaryFileUrl {
@ -334,7 +336,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
NSDictionary *event = [self getUploadTaskAsDictionary:snapshot]; NSDictionary *event = [self getUploadTaskAsDictionary:snapshot];
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
}]; }];
[uploadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) { [uploadTask observeStatus:FIRStorageTaskStatusPause handler:^(FIRStorageTaskSnapshot *snapshot) {
// upload paused // upload paused
NSDictionary *event = [self getUploadTaskAsDictionary:snapshot]; NSDictionary *event = [self getUploadTaskAsDictionary:snapshot];
@ -345,7 +347,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
NSDictionary *event = [self getUploadTaskAsDictionary:snapshot]; NSDictionary *event = [self getUploadTaskAsDictionary:snapshot];
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_STATE_CHANGED props:event];
}]; }];
[uploadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) { [uploadTask observeStatus:FIRStorageTaskStatusSuccess handler:^(FIRStorageTaskSnapshot *snapshot) {
// upload completed successfully // upload completed successfully
NSDictionary *resp = [self getUploadTaskAsDictionary:snapshot]; NSDictionary *resp = [self getUploadTaskAsDictionary:snapshot];
@ -353,7 +355,7 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
[self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_UPLOAD_SUCCESS props:resp]; [self sendJSEvent:STORAGE_EVENT path:path title:STORAGE_UPLOAD_SUCCESS props:resp];
resolve(resp); resolve(resp);
}]; }];
[uploadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) { [uploadTask observeStatus:FIRStorageTaskStatusFailure handler:^(FIRStorageTaskSnapshot *snapshot) {
if (snapshot.error != nil) { if (snapshot.error != nil) {
[self promiseRejectStorageException:reject error:snapshot.error]; [self promiseRejectStorageException:reject error:snapshot.error];
@ -445,3 +447,10 @@ RCT_EXPORT_METHOD(putFile:(NSString *) path localPath:(NSString *)localPath meta
@end @end
#else
@implementation RNFirebaseStorage
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(nativeSDKMissing) {}
@end
#endif