2
0
mirror of synced 2025-02-07 20:14:21 +00:00

[storage][ios] fix automatic mime/content type detection for storage meta

This commit is contained in:
Salakar 2018-07-07 03:10:35 +01:00
parent d59ee569b6
commit c13c81f36d
4 changed files with 82 additions and 122 deletions

View File

@ -601,12 +601,10 @@ public class RNFirebaseStorage extends ReactContextBaseJavaModule {
*/
private void sendJSEvent(String appName, final String name, final String path, WritableMap body) {
WritableMap event = Arguments.createMap();
event.putString("appName", appName);
event.putString("eventName", name);
event.putString("path", path);
event.putMap("body", body);
event.putString("path", path);
event.putString("eventName", name);
event.putString("appName", appName);
Utils.sendEvent(this.getReactApplicationContext(), STORAGE_EVENT, event);
}

View File

@ -55,18 +55,18 @@ PODS:
- FirebaseAnalytics (5.0.1):
- FirebaseCore (~> 5.0)
- FirebaseInstanceID (~> 3.0)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- nanopb (~> 0.3)
- FirebaseAuth (5.0.1):
- FirebaseCore (~> 5.0)
- GTMSessionFetcher/Core (~> 1.1)
- FirebaseCore (5.0.4):
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- FirebaseCrash (3.0.0):
- FirebaseAnalytics (~> 5.0)
- FirebaseInstanceID (~> 3.0)
- GoogleToolboxForMac/Logger (~> 2.1)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- Protobuf (~> 3.5)
- FirebaseDatabase (5.0.1):
- FirebaseCore (~> 5.0)
@ -95,8 +95,8 @@ PODS:
- GoogleAPIClientForREST (~> 1.0)
- GoogleSignIn (~> 4.1)
- GoogleToolboxForMac/Logger (~> 2.1)
- GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)
- GoogleToolboxForMac/NSString+URLArguments (~> 2.1)
- "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)"
- "GoogleToolboxForMac/NSString+URLArguments (~> 2.1)"
- GoogleToolboxForMac/StringEncoding (~> 2.1)
- GoogleToolboxForMac/URLBuilder (~> 2.1)
- GTMOAuth2 (~> 1.0)
@ -114,7 +114,7 @@ PODS:
- FirebaseSwizzlingUtilities/ISASwizzling (~> 2.0)
- FirebaseSwizzlingUtilities/MethodSwizzling (~> 2.0)
- GoogleToolboxForMac/Logger (~> 2.1)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- GTMSessionFetcher/Core (~> 1.1)
- Protobuf (~> 3.5)
- FirebaseRemoteConfig (3.0.0):
@ -122,7 +122,7 @@ PODS:
- FirebaseAnalytics (~> 5.0)
- FirebaseCore (~> 5.0)
- FirebaseInstanceID (~> 3.0)
- GoogleToolboxForMac/NSData+zlib (~> 2.1)
- "GoogleToolboxForMac/NSData+zlib (~> 2.1)"
- Protobuf (~> 3.5)
- FirebaseStorage (3.0.0):
- FirebaseCore (~> 5.0)
@ -137,8 +137,8 @@ PODS:
- GoogleAPIClientForREST/Core (1.3.4):
- GTMSessionFetcher (>= 1.1.7)
- GoogleSignIn (4.1.2):
- GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)
- GoogleToolboxForMac/NSString+URLArguments (~> 2.1)
- "GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1)"
- "GoogleToolboxForMac/NSString+URLArguments (~> 2.1)"
- GTMOAuth2 (~> 1.0)
- GTMSessionFetcher/Core (~> 1.1)
- GoogleToolboxForMac/Core (2.1.4):
@ -148,20 +148,20 @@ PODS:
- GoogleToolboxForMac/Defines (2.1.4)
- GoogleToolboxForMac/Logger (2.1.4):
- GoogleToolboxForMac/Defines (= 2.1.4)
- GoogleToolboxForMac/NSData+zlib (2.1.4):
- "GoogleToolboxForMac/NSData+zlib (2.1.4)":
- GoogleToolboxForMac/Defines (= 2.1.4)
- GoogleToolboxForMac/NSDictionary+URLArguments (2.1.4):
- "GoogleToolboxForMac/NSDictionary+URLArguments (2.1.4)":
- GoogleToolboxForMac/DebugUtils (= 2.1.4)
- GoogleToolboxForMac/Defines (= 2.1.4)
- GoogleToolboxForMac/NSString+URLArguments (= 2.1.4)
- GoogleToolboxForMac/NSString+URLArguments (2.1.4)
- "GoogleToolboxForMac/NSString+URLArguments (= 2.1.4)"
- "GoogleToolboxForMac/NSString+URLArguments (2.1.4)"
- GoogleToolboxForMac/StringEncoding (2.1.4):
- GoogleToolboxForMac/Defines (= 2.1.4)
- GoogleToolboxForMac/URLBuilder (2.1.4):
- GoogleToolboxForMac/Core (= 2.1.4)
- GoogleToolboxForMac/Defines (= 2.1.4)
- GoogleToolboxForMac/NSDictionary+URLArguments (= 2.1.4)
- GoogleToolboxForMac/NSString+URLArguments (= 2.1.4)
- "GoogleToolboxForMac/NSDictionary+URLArguments (= 2.1.4)"
- "GoogleToolboxForMac/NSString+URLArguments (= 2.1.4)"
- gRPC (1.12.0):
- gRPC-RxLibrary (= 1.12.0)
- gRPC/Main (= 1.12.0)
@ -238,13 +238,49 @@ DEPENDENCIES:
- RNFirebase (from `../../ios/RNFirebase.podspec`)
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- BoringSSL
- Crashlytics
- Fabric
- Firebase
- FirebaseABTesting
- FirebaseAnalytics
- FirebaseAuth
- FirebaseCore
- FirebaseCrash
- FirebaseDatabase
- FirebaseDynamicLinks
- FirebaseFirestore
- FirebaseFunctions
- FirebaseInstanceID
- FirebaseInvites
- FirebaseMessaging
- FirebasePerformance
- FirebaseRemoteConfig
- FirebaseStorage
- FirebaseSwizzlingUtilities
- Google-Mobile-Ads-SDK
- GoogleAPIClientForREST
- GoogleSignIn
- GoogleToolboxForMac
- gRPC
- gRPC-Core
- gRPC-ProtoRPC
- gRPC-RxLibrary
- GTMOAuth2
- GTMSessionFetcher
- leveldb-library
- nanopb
- Protobuf
EXTERNAL SOURCES:
React:
:path: ../node_modules/react-native
:path: "../node_modules/react-native"
RNFirebase:
:path: ../../ios/RNFirebase.podspec
:path: "../../ios/RNFirebase.podspec"
yoga:
:path: ../node_modules/react-native/ReactCommon/yoga
:path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
BoringSSL: cf3f1793eb6e3c445c4d150456341f149c268a35
@ -286,4 +322,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 582ceaad051470812ad9203e13b5ea8ad20c78ac
COCOAPODS: 1.4.0
COCOAPODS: 1.5.3

View File

@ -595,7 +595,6 @@
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
CC0F353E1D461097008BB94F /* Embed Frameworks */,
7D57265F10EEF7CD92D7973F /* Copy Detox Framework */,
4EEB648E968FA6F093B42978 /* [CP] Embed Pods Frameworks */,
CC8D61273332DE7812CFF010 /* [CP] Copy Pods Resources */,
);
buildRules = (
@ -971,21 +970,6 @@
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
};
4EEB648E968FA6F093B42978 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-testing/Pods-testing-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
7D57265F10EEF7CD92D7973F /* Copy Detox Framework */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;

View File

@ -209,91 +209,33 @@ RCT_EXPORT_METHOD(putFile:(NSString *) appDisplayName
metadata:(NSDictionary *) metadata
resolver:(RCTPromiseResolveBlock) resolve
rejecter:(RCTPromiseRejectBlock) reject) {
FIRStorageMetadata *firmetadata = [self buildMetadataFromMap:metadata];
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];
} else {
NSString *assetId = [localPath substringFromIndex:@"ph://".length];
assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[assetId] options:nil];
}
PHAsset *asset = [assets firstObject];
// 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[PHImageErrorKey] == nil) {
if (UTTypeConformsTo((__bridge CFStringRef)dataUTI, kUTTypeJPEG)) {
firmetadata.contentType = [self utiToMimeType:dataUTI];
[self uploadData:appDisplayName data:imageData firmetadata:firmetadata path:path resolver:resolve rejecter:reject];
} else {
// if the image UTI is not JPEG then convert to JPEG, e.g. HEI
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
NSDictionary *imageInfo = (__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
NSDictionary *imageMetadata = [imageInfo copy];
NSMutableData *imageDataJPEG = [NSMutableData data];
CGImageDestinationRef destination = CGImageDestinationCreateWithData((__bridge CFMutableDataRef)imageDataJPEG, kUTTypeJPEG, 1, NULL);
CGImageDestinationAddImageFromSource(destination, source, 0, (__bridge CFDictionaryRef)imageMetadata);
CGImageDestinationFinalize(destination);
// Manually set mimetype to JPEG
firmetadata.contentType = @"image/jpeg";
[self uploadData:appDisplayName data:[NSData dataWithData:imageDataJPEG] firmetadata:firmetadata 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[PHImageErrorKey] == nil) {
NSURL *tempUrl = [self temporaryFileUrl];
exportSession.outputURL = tempUrl;
NSArray<PHAssetResource *> *resources = [PHAssetResource assetResourcesForAsset:asset];
for (PHAssetResource *resource in resources) {
exportSession.outputFileType = resource.uniformTypeIdentifier;
if (exportSession.outputFileType != nil) break;
}
[exportSession exportAsynchronouslyWithCompletionHandler:^{
if (exportSession.status == AVAssetExportSessionStatusCompleted) {
firmetadata.contentType = [self utiToMimeType:exportSession.outputFileType];
[self uploadFile:appDisplayName url:tempUrl firmetadata:firmetadata 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 {
// TODO: Content type for file?
NSData *data = [[NSFileManager defaultManager] contentsAtPath:localPath];
[self uploadData:appDisplayName data:data firmetadata:firmetadata path:path resolver:resolve rejecter:reject];
if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
reject(@"storage/file-not-found", @"File specified at path does not exist.", nil);
return;
}
NSData *data = [NSData dataWithContentsOfFile:localPath];
FIRStorageMetadata *firmetadata = [self buildMetadataFromMap:metadata];
if ([firmetadata valueForKey:@"contentType"] == nil) {
firmetadata.contentType = [self mimeTypeForPath:localPath];
}
// TODO convert heic -> jpeg only if users asks for it
[self uploadData:appDisplayName data:data firmetadata:firmetadata path:path resolver:resolve rejecter:reject];
}
- (NSURL *)temporaryFileUrl {
NSString *filename = [NSString stringWithFormat:@"%@.tmp", [[NSProcessInfo processInfo] globallyUniqueString]];
return [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:filename];
}
- (NSString *)utiToMimeType:(NSString *) dataUTI {
return (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)dataUTI, kUTTagClassMIMEType);
- (NSString*) mimeTypeForPath: (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_transfer NSString *) mimeType;
}
- (void)uploadFile:(NSString *)appDisplayName url:(NSURL *)url firmetadata:(FIRStorageMetadata *)firmetadata path:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject {