diff options
author | Sebastian Schmidt <mrschmidt@google.com> | 2018-04-13 14:37:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-13 14:37:28 -0700 |
commit | 4e01558661d74cb7eba3b6ba66d3ecc90720d5f6 (patch) | |
tree | f89ca0b8bd61c01b9dd70cbced72687672f5a653 | |
parent | 60d43d7b0980719beac21811da712f1cb4881308 (diff) | |
parent | d7316f70dc4825e75cecd47740c0541248aa9641 (diff) |
Merge pull request #1055 from firebase/mrschmidt-removedownloadurl
Removing FirebaseStorage.downloadURL
-rw-r--r-- | Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m | 32 | ||||
-rw-r--r-- | Example/Storage/Tests/Unit/FIRStorageMetadataTests.m | 60 | ||||
-rw-r--r-- | Firebase/Storage/CHANGELOG.md | 6 | ||||
-rw-r--r-- | Firebase/Storage/FIRStorageErrors.m | 17 | ||||
-rw-r--r-- | Firebase/Storage/FIRStorageGetDownloadURLTask.m | 117 | ||||
-rw-r--r-- | Firebase/Storage/FIRStorageGetMetadataTask.m | 36 | ||||
-rw-r--r-- | Firebase/Storage/FIRStorageMetadata.m | 48 | ||||
-rw-r--r-- | Firebase/Storage/FIRStorageReference.m | 16 | ||||
-rw-r--r-- | Firebase/Storage/FIRStorageUpdateMetadataTask.m | 36 | ||||
-rw-r--r-- | Firebase/Storage/FIRStorageUploadTask.m | 9 | ||||
-rw-r--r-- | Firebase/Storage/Private/FIRStorageConstants_Private.h | 1 | ||||
-rw-r--r-- | Firebase/Storage/Private/FIRStorageErrors.h | 18 | ||||
-rw-r--r-- | Firebase/Storage/Private/FIRStorageGetDownloadURLTask.h | 34 | ||||
-rw-r--r-- | Firebase/Storage/Private/FIRStorageGetDownloadURLTask_Private.h | 31 | ||||
-rw-r--r-- | Firebase/Storage/Public/FIRStorageMetadata.h | 14 |
15 files changed, 289 insertions, 186 deletions
diff --git a/Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m b/Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m index 8e826c9..b20108a 100644 --- a/Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m +++ b/Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m @@ -12,10 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#import <FirebaseStorage/FIRStorageMetadata.h> #import <XCTest/XCTest.h> -#import <math.h> - #import "FirebaseStorage.h" #import <FirebaseCore/FIRApp.h> @@ -381,7 +378,7 @@ NSTimeInterval kFIRStorageIntegrationTestTimeout = 30; /// Only allow 1kB size, which is smaller than our file [ref dataWithMaxSize:1 * 1024 completion:^(NSData *data, NSError *error) { - XCTAssertEqual(data, nil); + XCTAssertNil(data); XCTAssertEqual(error.code, FIRStorageErrorCodeDownloadSizeExceeded); [expectation fulfill]; }]; @@ -389,6 +386,33 @@ NSTimeInterval kFIRStorageIntegrationTestTimeout = 30; [self waitForExpectations]; } +- (void)testUnauthenticatedSimpleGetDownloadURL { + XCTestExpectation *expectation = + [self expectationWithDescription:@"testUnauthenticatedSimpleGetDownloadURL"]; + + FIRStorageReference *ref = [self.storage referenceWithPath:@"ios/public/1mb"]; + + // Download URL format is + // "https://firebasestorage.googleapis.com/v0/b/{bucket}/o/{path}?alt=media&token={token}" + NSString *downloadURLPattern = + @"^https:\\/\\/firebasestorage.googleapis.com\\/v0\\/b\\/[^\\/]*\\/o\\/" + @"ios%2Fpublic%2F1mb\\?alt=media&token=[a-z0-9-]*$"; + + [ref downloadURLWithCompletion:^(NSURL *downloadURL, NSError *error) { + XCTAssertNil(error); + NSRegularExpression *testRegex = + [NSRegularExpression regularExpressionWithPattern:downloadURLPattern options:0 error:nil]; + NSString *urlString = [downloadURL absoluteString]; + XCTAssertEqual([testRegex numberOfMatchesInString:urlString + options:0 + range:NSMakeRange(0, [urlString length])], + 1); + [expectation fulfill]; + }]; + + [self waitForExpectations]; +} + - (void)testUnauthenticatedSimpleGetFile { XCTestExpectation *expectation = [self expectationWithDescription:@"testUnauthenticatedSimpleGetData"]; diff --git a/Example/Storage/Tests/Unit/FIRStorageMetadataTests.m b/Example/Storage/Tests/Unit/FIRStorageMetadataTests.m index 84b5271..6a83741 100644 --- a/Example/Storage/Tests/Unit/FIRStorageMetadataTests.m +++ b/Example/Storage/Tests/Unit/FIRStorageMetadataTests.m @@ -15,6 +15,8 @@ #import <FirebaseStorage/FIRStorageMetadata.h> #import <XCTest/XCTest.h> +#import "FIRStorageGetDownloadURLTask.h" +#import "FIRStorageGetDownloadURLTask_Private.h" #import "FIRStorageMetadata.h" #import "FIRStorageMetadata_Private.h" #import "FIRStorageUtils.h" @@ -39,7 +41,6 @@ kFIRStorageMetadataContentLanguage : @"en-us", kFIRStorageMetadataContentType : @"application/octet-stream", kFIRStorageMetadataCustomMetadata : @{@"foo" : @{@"bar" : @"baz"}}, - kFIRStorageMetadataDownloadTokens : @"1234567890", kFIRStorageMetadataGeneration : @"12345", kFIRStorageMetadataMetageneration : @"67890", kFIRStorageMetadataName : @"path/to/object", @@ -58,12 +59,6 @@ XCTAssertEqualObjects(metadata.contentType, metaDict[kFIRStorageMetadataContentType]); XCTAssertEqualObjects(metadata.customMetadata, metaDict[kFIRStorageMetadataCustomMetadata]); XCTAssertEqualObjects(metadata.md5Hash, metaDict[kFIRStorageMetadataMd5Hash]); - NSString *URLFormat = @"https://firebasestorage.googleapis.com/v0/b/%@/o/%@?alt=media&token=%@"; - NSString *URLString = [NSString - stringWithFormat:URLFormat, metaDict[kFIRStorageMetadataBucket], - [FIRStorageUtils GCSEscapedString:metaDict[kFIRStorageMetadataName]], - metaDict[kFIRStorageMetadataDownloadTokens]]; - XCTAssertEqualObjects([metadata.downloadURL description], URLString); NSString *generation = [NSString stringWithFormat:@"%lld", metadata.generation]; XCTAssertEqualObjects(generation, metaDict[kFIRStorageMetadataGeneration]); NSString *metageneration = [NSString stringWithFormat:@"%lld", metadata.metageneration]; @@ -86,7 +81,6 @@ kFIRStorageMetadataContentLanguage : @"en-us", kFIRStorageMetadataContentType : @"application/octet-stream", kFIRStorageMetadataCustomMetadata : @{@"foo" : @{@"bar" : @"baz"}}, - kFIRStorageMetadataDownloadTokens : @"1234567890", kFIRStorageMetadataGeneration : @"12345", kFIRStorageMetadataMetageneration : @"67890", kFIRStorageMetadataName : @"path/to/object", @@ -97,7 +91,7 @@ }; FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] initWithDictionary:metaDict]; NSDictionary *dictRepresentation = [metadata dictionaryRepresentation]; - XCTAssertNotEqual(dictRepresentation, nil); + XCTAssertNotNil(dictRepresentation); XCTAssertEqualObjects(dictRepresentation[kFIRStorageMetadataBucket], metaDict[kFIRStorageMetadataBucket]); XCTAssertEqualObjects(dictRepresentation[kFIRStorageMetadataCacheControl], @@ -130,60 +124,28 @@ metaDict[kFIRStorageMetadataMd5Hash]); } -- (void)testInitialzeNoDownloadTokensGetToken { - NSDictionary *metaDict = @{ - kFIRStorageMetadataBucket : @"bucket", - kFIRStorageMetadataName : @"path/to/object", - }; - FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] initWithDictionary:metaDict]; - XCTAssertNotNil(metadata); - XCTAssertEqual(metadata.downloadURL, nil); - XCTAssertEqual(metadata.downloadURLs, nil); -} - -- (void)testInitialzeMultipleDownloadTokensGetToken { +- (void)testInitializeEmptyDownloadURL { NSDictionary *metaDict = @{ kFIRStorageMetadataBucket : @"bucket", - kFIRStorageMetadataDownloadTokens : @"12345,67890", kFIRStorageMetadataName : @"path/to/object", }; - FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] initWithDictionary:metaDict]; - XCTAssertNotNil(metadata); - NSString *URLformat = @"https://firebasestorage.googleapis.com/v0/b/%@/o/%@?alt=media&token=%@"; - NSString *URLString0 = [NSString - stringWithFormat:URLformat, metaDict[kFIRStorageMetadataBucket], - [FIRStorageUtils GCSEscapedString:metaDict[kFIRStorageMetadataName]], - @"12345"]; - NSString *URLString1 = [NSString - stringWithFormat:URLformat, metaDict[kFIRStorageMetadataBucket], - [FIRStorageUtils GCSEscapedString:metaDict[kFIRStorageMetadataName]], - @"67890"]; - XCTAssertEqualObjects([metadata.downloadURL absoluteString], URLString0); - XCTAssertEqualObjects([metadata.downloadURLs[0] absoluteString], URLString0); - XCTAssertEqualObjects([metadata.downloadURLs[1] absoluteString], URLString1); + NSURL *actualURL = [FIRStorageGetDownloadURLTask downloadURLFromMetadataDictionary:metaDict]; + XCTAssertNil(actualURL); } -- (void)testMultipleDownloadURLsGetToken { +- (void)testInitializeDownloadURLFromToken { NSDictionary *metaDict = @{ kFIRStorageMetadataBucket : @"bucket", + kFIRStorageMetadataDownloadTokens : @"12345,ignored", kFIRStorageMetadataName : @"path/to/object", }; - FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] initWithDictionary:metaDict]; NSString *URLformat = @"https://firebasestorage.googleapis.com/v0/b/%@/o/%@?alt=media&token=%@"; - NSString *URLString0 = [NSString + NSString *expectedURL = [NSString stringWithFormat:URLformat, metaDict[kFIRStorageMetadataBucket], [FIRStorageUtils GCSEscapedString:metaDict[kFIRStorageMetadataName]], @"12345"]; - NSString *URLString1 = [NSString - stringWithFormat:URLformat, metaDict[kFIRStorageMetadataBucket], - [FIRStorageUtils GCSEscapedString:metaDict[kFIRStorageMetadataName]], - @"67890"]; - NSURL *URL0 = [NSURL URLWithString:URLString0]; - NSURL *URL1 = [NSURL URLWithString:URLString1]; - NSArray *downloadURLs = @[ URL0, URL1 ]; - [metadata setValue:downloadURLs forKey:@"downloadURLs"]; - NSDictionary *newMetaDict = metadata.dictionaryRepresentation; - XCTAssertEqualObjects(newMetaDict[kFIRStorageMetadataDownloadTokens], @"12345,67890"); + NSURL *actualURL = [FIRStorageGetDownloadURLTask downloadURLFromMetadataDictionary:metaDict]; + XCTAssertEqualObjects([actualURL absoluteString], expectedURL); } - (void)testInitialzeMetadataWithFile { diff --git a/Firebase/Storage/CHANGELOG.md b/Firebase/Storage/CHANGELOG.md index 5054cf2..135de40 100644 --- a/Firebase/Storage/CHANGELOG.md +++ b/Firebase/Storage/CHANGELOG.md @@ -1,5 +1,9 @@ +# v3.0.0 +- [removed] Removed `downloadURLs` property on `StorageMetadata`. Use `StorageReference.downloadURL(completion:)` to obtain a current download URL. +- [changed] The `maxOperationRetryTime` timeout now applies to calls to `StorageReference.getMetadata(completion:)` and `StorageReference.updateMetadata(completion:)`. These calls previously used the `maxDownloadRetryTime` and `maxUploadRetryTime` timeouts. + # v2.2.0 -- [changed] Deprecated `downloadURLs` property on `StorageMetadata`. Use `StorageReference.downloadURLWithCompletion()` to obtain a current download URL. +- [changed] Deprecated `downloadURLs` property on `StorageMetadata`. Use `StorageReference.downloadURL(completion:)` to obtain a current download URL. # v2.1.3 - [changed] Addresses CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF warnings that surface in newer versions of Xcode and CocoaPods. diff --git a/Firebase/Storage/FIRStorageErrors.m b/Firebase/Storage/FIRStorageErrors.m index ecfae02..651bfd1 100644 --- a/Firebase/Storage/FIRStorageErrors.m +++ b/Firebase/Storage/FIRStorageErrors.m @@ -170,4 +170,21 @@ return clientError; } ++ (NSError *)errorWithInvalidRequest:(NSData *)request { + NSString *requestString = [[NSString alloc] initWithData:request encoding:NSUTF8StringEncoding]; + NSString *invalidDataString = + [NSString stringWithFormat:kFIRStorageInvalidDataFormat, requestString]; + NSDictionary *dict; + if (invalidDataString.length > 0) { + dict = @{NSLocalizedFailureReasonErrorKey : invalidDataString}; + } + return [FIRStorageErrors errorWithCode:FIRStorageErrorCodeUnknown infoDictionary:dict]; +} + ++ (NSError *)errorWithCustomMessage:(NSString *)errorMessage { + return [NSError errorWithDomain:FIRStorageErrorDomain + code:FIRStorageErrorCodeUnknown + userInfo:@{NSLocalizedDescriptionKey : errorMessage}]; +} + @end diff --git a/Firebase/Storage/FIRStorageGetDownloadURLTask.m b/Firebase/Storage/FIRStorageGetDownloadURLTask.m new file mode 100644 index 0000000..02d202e --- /dev/null +++ b/Firebase/Storage/FIRStorageGetDownloadURLTask.m @@ -0,0 +1,117 @@ +// Copyright 2018 Google +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#import "FIRStorageGetDownloadURLTask.h" + +#import "FIRStorageTask_Private.h" + +@implementation FIRStorageGetDownloadURLTask { + @private + FIRStorageVoidURLError _completion; +} + +@synthesize fetcher = _fetcher; +@synthesize fetcherCompletion = _fetcherCompletion; + +- (instancetype)initWithReference:(FIRStorageReference *)reference + fetcherService:(GTMSessionFetcherService *)service + completion:(FIRStorageVoidURLError)completion { + self = [super initWithReference:reference fetcherService:service]; + if (self) { + _completion = [completion copy]; + } + return self; +} + +- (void)dealloc { + [_fetcher stopFetching]; +} + ++ (NSURL *)downloadURLFromMetadataDictionary:(NSDictionary *)dictionary { + NSString *downloadTokens = dictionary[kFIRStorageMetadataDownloadTokens]; + + if (downloadTokens && downloadTokens.length > 0) { + NSArray<NSString *> *downloadTokenArray = [downloadTokens componentsSeparatedByString:@","]; + NSString *bucket = dictionary[kFIRStorageMetadataBucket]; + NSString *path = dictionary[kFIRStorageMetadataName]; + NSString *fullPath = [NSString stringWithFormat:kFIRStorageFullPathFormat, bucket, + [FIRStorageUtils GCSEscapedString:path]]; + + NSURLComponents *components = [[NSURLComponents alloc] init]; + components.scheme = kFIRStorageScheme; + components.host = kFIRStorageHost; + components.percentEncodedPath = fullPath; + + // The backend can return an arbitrary number of download tokens, but we only expose the first + // token via the download URL. + NSURLQueryItem *altItem = [[NSURLQueryItem alloc] initWithName:@"alt" value:@"media"]; + NSURLQueryItem *tokenItem = + [[NSURLQueryItem alloc] initWithName:@"token" value:downloadTokenArray[0]]; + components.queryItems = @[ altItem, tokenItem ]; + + return [components URL]; + } + + return nil; +} + +- (void)enqueue { + NSMutableURLRequest *request = [self.baseRequest mutableCopy]; + request.HTTPMethod = @"GET"; + request.timeoutInterval = self.reference.storage.maxOperationRetryTime; + + FIRStorageVoidURLError callback = _completion; + _completion = nil; + + GTMSessionFetcher *fetcher = [self.fetcherService fetcherWithRequest:request]; + _fetcher = fetcher; + fetcher.comment = @"GetDownloadURLTask"; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-retain-cycles" + _fetcherCompletion = ^(NSData *data, NSError *error) { + NSURL *downloadURL; + if (error) { + if (!self.error) { + self.error = [FIRStorageErrors errorWithServerError:error reference:self.reference]; + } + } else { + NSDictionary *responseDictionary = [NSDictionary frs_dictionaryFromJSONData:data]; + if (responseDictionary != nil) { + downloadURL = + [FIRStorageGetDownloadURLTask downloadURLFromMetadataDictionary:responseDictionary]; + if (!downloadURL) { + self.error = + [FIRStorageErrors errorWithCustomMessage:@"Failed to retrieve a download URL."]; + } + } else { + self.error = [FIRStorageErrors errorWithInvalidRequest:data]; + } + } + + if (callback) { + callback(downloadURL, self.error); + } + + self->_fetcherCompletion = nil; + }; +#pragma clang diagnostic pop + + __weak FIRStorageGetDownloadURLTask *weakSelf = self; + [fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) { + weakSelf.fetcherCompletion(data, error); + }]; +} + +@end diff --git a/Firebase/Storage/FIRStorageGetMetadataTask.m b/Firebase/Storage/FIRStorageGetMetadataTask.m index 2623652..752c410 100644 --- a/Firebase/Storage/FIRStorageGetMetadataTask.m +++ b/Firebase/Storage/FIRStorageGetMetadataTask.m @@ -46,7 +46,7 @@ - (void)enqueue { NSMutableURLRequest *request = [self.baseRequest mutableCopy]; request.HTTPMethod = @"GET"; - request.timeoutInterval = self.reference.storage.maxDownloadRetryTime; + request.timeoutInterval = self.reference.storage.maxOperationRetryTime; FIRStorageVoidMetadataError callback = _completion; _completion = nil; @@ -58,37 +58,23 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-retain-cycles" _fetcherCompletion = ^(NSData *data, NSError *error) { + FIRStorageMetadata *metadata; if (error) { if (!self.error) { self.error = [FIRStorageErrors errorWithServerError:error reference:self.reference]; } - if (callback) { - callback(nil, self.error); + } else { + NSDictionary *responseDictionary = [NSDictionary frs_dictionaryFromJSONData:data]; + if (responseDictionary != nil) { + metadata = [[FIRStorageMetadata alloc] initWithDictionary:responseDictionary]; + [metadata setType:FIRStorageMetadataTypeFile]; + } else { + self.error = [FIRStorageErrors errorWithInvalidRequest:data]; } - self->_fetcherCompletion = nil; - return; } - NSDictionary *responseDictionary = [NSDictionary frs_dictionaryFromJSONData:data]; - if (responseDictionary != nil) { - FIRStorageMetadata *metadata = - [[FIRStorageMetadata alloc] initWithDictionary:responseDictionary]; - [metadata setType:FIRStorageMetadataTypeFile]; - if (callback) { - callback(metadata, nil); - } - } else { - NSString *returnedData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - NSString *invalidDataString = - [NSString stringWithFormat:kFIRStorageInvalidDataFormat, returnedData]; - NSDictionary *dict; - if (invalidDataString.length > 0) { - dict = @{NSLocalizedFailureReasonErrorKey : invalidDataString}; - } - self.error = [FIRStorageErrors errorWithCode:FIRStorageErrorCodeUnknown infoDictionary:dict]; - if (callback) { - callback(nil, self.error); - } + if (callback) { + callback(metadata, self.error); } self->_fetcherCompletion = nil; }; diff --git a/Firebase/Storage/FIRStorageMetadata.m b/Firebase/Storage/FIRStorageMetadata.m index ab25076..764907c 100644 --- a/Firebase/Storage/FIRStorageMetadata.m +++ b/Firebase/Storage/FIRStorageMetadata.m @@ -41,7 +41,6 @@ _contentType = dictionary[kFIRStorageMetadataContentType]; _customMetadata = dictionary[kFIRStorageMetadataCustomMetadata]; _size = [dictionary[kFIRStorageMetadataSize] longLongValue]; - _downloadURLs = dictionary[kFIRStorageMetadataDownloadURLs]; _generation = [dictionary[kFIRStorageMetadataGeneration] longLongValue]; _metageneration = [dictionary[kFIRStorageMetadataMetageneration] longLongValue]; _timeCreated = [self dateFromRFC3339String:dictionary[kFIRStorageMetadataTimeCreated]]; @@ -50,26 +49,6 @@ // GCS "name" is our path, our "name" is just the last path component of the path _path = dictionary[kFIRStorageMetadataName]; _name = [_path lastPathComponent]; - NSString *downloadTokens = dictionary[kFIRStorageMetadataDownloadTokens]; - if (downloadTokens) { - NSArray<NSString *> *downloadStringArray = [downloadTokens componentsSeparatedByString:@","]; - NSMutableArray<NSURL *> *downloadURLArray = - [[NSMutableArray alloc] initWithCapacity:[downloadStringArray count]]; - [downloadStringArray enumerateObjectsUsingBlock:^(NSString *_Nonnull token, NSUInteger idx, - BOOL *_Nonnull stop) { - NSURLComponents *components = [[NSURLComponents alloc] init]; - components.scheme = kFIRStorageScheme; - components.host = kFIRStorageHost; - NSString *path = [FIRStorageUtils GCSEscapedString:self->_path]; - NSString *fullPath = - [NSString stringWithFormat:kFIRStorageFullPathFormat, self->_bucket, path]; - components.percentEncodedPath = fullPath; - components.query = [NSString stringWithFormat:@"alt=media&token=%@", token]; - - [downloadURLArray insertObject:[components URL] atIndex:idx]; - }]; - _downloadURLs = downloadURLArray; - } } return self; } @@ -147,29 +126,6 @@ metadataDictionary[kFIRStorageMetadataCustomMetadata] = _customMetadata; } - if (_downloadURLs) { - NSMutableArray *downloadTokens = [[NSMutableArray alloc] init]; - [_downloadURLs - enumerateObjectsUsingBlock:^(NSURL *_Nonnull URL, NSUInteger idx, BOOL *_Nonnull stop) { - NSArray *queryItems = [URL.query componentsSeparatedByString:@"&"]; - [queryItems enumerateObjectsUsingBlock:^(NSString *queryString, NSUInteger idx, - BOOL *_Nonnull stop) { - NSString *key; - NSString *value; - NSScanner *scanner = [NSScanner scannerWithString:queryString]; - [scanner scanUpToString:@"=" intoString:&key]; - [scanner scanString:@"=" intoString:NULL]; - [scanner scanUpToString:@"\n" intoString:&value]; - if ([key isEqual:@"token"]) { - [downloadTokens addObject:value]; - *stop = YES; - } - }]; - }]; - NSString *downloadTokenString = [downloadTokens componentsJoinedByString:@","]; - metadataDictionary[kFIRStorageMetadataDownloadTokens] = downloadTokenString; - } - if (_generation) { NSString *generationString = [NSString stringWithFormat:@"%lld", _generation]; metadataDictionary[kFIRStorageMetadataGeneration] = generationString; @@ -207,10 +163,6 @@ return _type == FIRStorageMetadataTypeFolder; } -- (nullable NSURL *)downloadURL { - return [_downloadURLs firstObject]; -} - #pragma mark - Private methods + (void)removeMatchingMetadata:(NSMutableDictionary *)metadata diff --git a/Firebase/Storage/FIRStorageReference.m b/Firebase/Storage/FIRStorageReference.m index 7bc1934..5b70a9c 100644 --- a/Firebase/Storage/FIRStorageReference.m +++ b/Firebase/Storage/FIRStorageReference.m @@ -17,6 +17,7 @@ #import "FIRStorageConstants_Private.h" #import "FIRStorageDeleteTask.h" #import "FIRStorageDownloadTask_Private.h" +#import "FIRStorageGetDownloadURLTask.h" #import "FIRStorageGetMetadataTask.h" #import "FIRStorageMetadata_Private.h" #import "FIRStorageReference_Private.h" @@ -319,16 +320,11 @@ } - (void)downloadURLWithCompletion:(FIRStorageVoidURLError)completion { - dispatch_queue_t callbackQueue = _storage.fetcherServiceForApp.callbackQueue; - if (!callbackQueue) { - callbackQueue = dispatch_get_main_queue(); - } - - return [self metadataWithCompletion:^(FIRStorageMetadata *metadata, NSError *error) { - dispatch_async(callbackQueue, ^{ - completion(metadata.downloadURL, error); - }); - }]; + FIRStorageGetDownloadURLTask *task = + [[FIRStorageGetDownloadURLTask alloc] initWithReference:self + fetcherService:_storage.fetcherServiceForApp + completion:completion]; + [task enqueue]; } #pragma mark - Metadata Operations diff --git a/Firebase/Storage/FIRStorageUpdateMetadataTask.m b/Firebase/Storage/FIRStorageUpdateMetadataTask.m index fa5955a..cea4e7d 100644 --- a/Firebase/Storage/FIRStorageUpdateMetadataTask.m +++ b/Firebase/Storage/FIRStorageUpdateMetadataTask.m @@ -48,7 +48,7 @@ NSDictionary *updateDictionary = [_updateMetadata updatedMetadata]; NSData *updateData = [NSData frs_dataFromJSONDictionary:updateDictionary]; request.HTTPMethod = @"PATCH"; - request.timeoutInterval = self.reference.storage.maxUploadRetryTime; + request.timeoutInterval = self.reference.storage.maxOperationRetryTime; request.HTTPBody = updateData; NSString *typeString = @"application/json; charset=UTF-8"; [request setValue:typeString forHTTPHeaderField:@"Content-Type"]; @@ -64,37 +64,23 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-retain-cycles" _fetcherCompletion = ^(NSData *data, NSError *error) { + FIRStorageMetadata *metadata; if (error) { if (!self.error) { self.error = [FIRStorageErrors errorWithServerError:error reference:self.reference]; } - if (callback) { - callback(nil, self.error); + } else { + NSDictionary *responseDictionary = [NSDictionary frs_dictionaryFromJSONData:data]; + if (responseDictionary) { + metadata = [[FIRStorageMetadata alloc] initWithDictionary:responseDictionary]; + [metadata setType:FIRStorageMetadataTypeFile]; + } else { + self.error = [FIRStorageErrors errorWithInvalidRequest:data]; } - self->_fetcherCompletion = nil; - return; } - NSDictionary *responseDictionary = [NSDictionary frs_dictionaryFromJSONData:data]; - if (responseDictionary) { - FIRStorageMetadata *metadata = - [[FIRStorageMetadata alloc] initWithDictionary:responseDictionary]; - [metadata setType:FIRStorageMetadataTypeFile]; - if (callback) { - callback(metadata, nil); - } - } else { - NSString *returnedData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - NSString *invalidDataString = - [NSString stringWithFormat:kFIRStorageInvalidDataFormat, returnedData]; - NSDictionary *dict; - if (invalidDataString.length > 0) { - dict = @{NSLocalizedFailureReasonErrorKey : invalidDataString}; - } - self.error = [FIRStorageErrors errorWithCode:FIRStorageErrorCodeUnknown infoDictionary:dict]; - if (callback) { - callback(nil, self.error); - } + if (callback) { + callback(metadata, self.error); } self->_fetcherCompletion = nil; }; diff --git a/Firebase/Storage/FIRStorageUploadTask.m b/Firebase/Storage/FIRStorageUploadTask.m index f84c2c7..2c4daa9 100644 --- a/Firebase/Storage/FIRStorageUploadTask.m +++ b/Firebase/Storage/FIRStorageUploadTask.m @@ -154,14 +154,7 @@ [metadata setType:FIRStorageMetadataTypeFile]; self.metadata = metadata; } else { - NSString *returnedData = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - NSString *invalidDataString = - [NSString stringWithFormat:kFIRStorageInvalidDataFormat, returnedData]; - NSDictionary *dict; - if (invalidDataString.length > 0) { - dict = @{NSLocalizedFailureReasonErrorKey : invalidDataString}; - } - self.error = [FIRStorageErrors errorWithCode:FIRStorageErrorCodeUnknown infoDictionary:dict]; + self.error = [FIRStorageErrors errorWithInvalidRequest:data]; } [self fireHandlersForStatus:FIRStorageTaskStatusSuccess snapshot:self.snapshot]; diff --git a/Firebase/Storage/Private/FIRStorageConstants_Private.h b/Firebase/Storage/Private/FIRStorageConstants_Private.h index 498c687..cf12337 100644 --- a/Firebase/Storage/Private/FIRStorageConstants_Private.h +++ b/Firebase/Storage/Private/FIRStorageConstants_Private.h @@ -55,7 +55,6 @@ FOUNDATION_EXPORT NSString *const kFIRStorageMetadataContentLanguage; FOUNDATION_EXPORT NSString *const kFIRStorageMetadataContentType; FOUNDATION_EXPORT NSString *const kFIRStorageMetadataCustomMetadata; FOUNDATION_EXPORT NSString *const kFIRStorageMetadataSize; -FOUNDATION_EXPORT NSString *const kFIRStorageMetadataDownloadURLs; FOUNDATION_EXPORT NSString *const kFIRStorageMetadataGeneration; FOUNDATION_EXPORT NSString *const kFIRStorageMetadataMetageneration; FOUNDATION_EXPORT NSString *const kFIRStorageMetadataTimeCreated; diff --git a/Firebase/Storage/Private/FIRStorageErrors.h b/Firebase/Storage/Private/FIRStorageErrors.h index 7c236d9..a76a6aa 100644 --- a/Firebase/Storage/Private/FIRStorageErrors.h +++ b/Firebase/Storage/Private/FIRStorageErrors.h @@ -44,11 +44,27 @@ NS_ASSUME_NONNULL_BEGIN * Creates a Firebase Storage error from a specific GCS error and FIRStorageReference. * @param error Server error to wrap and return as a Firebase Storage error. * @param reference FIRStorageReference which provides context about the request being made. - * @return Returns an Firebase Storage error, or nil if no error is provided. + * @return Returns a Firebase Storage error, or nil if no error is provided. */ + (nullable NSError *)errorWithServerError:(nullable NSError *)error reference:(nullable FIRStorageReference *)reference; +/** + * Creates a Firebase Storage error from an invalid request. + * + * @param request The NSData representation of the invalid user request. + * @return Returns the corresponding Firebase Storage error. + */ ++ (NSError *)errorWithInvalidRequest:(NSData *)request; + +/** + * Creates a Firebase Storage error with a custom error message. + * + * @param errorMessage A custom error message. + * @return Returns the corresponding Firebase Storage error. + */ ++ (NSError *)errorWithCustomMessage:(NSString *)errorMessage; + @end NS_ASSUME_NONNULL_END diff --git a/Firebase/Storage/Private/FIRStorageGetDownloadURLTask.h b/Firebase/Storage/Private/FIRStorageGetDownloadURLTask.h new file mode 100644 index 0000000..8cd9eb3 --- /dev/null +++ b/Firebase/Storage/Private/FIRStorageGetDownloadURLTask.h @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRStorageTask.h" + +@class GTMSessionFetcherService; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Task which provides the ability to get a download URL for an object in Firebase Storage. + */ +@interface FIRStorageGetDownloadURLTask : FIRStorageTask <FIRStorageTaskManagement> + +- (instancetype)initWithReference:(FIRStorageReference *)reference + fetcherService:(GTMSessionFetcherService *)service + completion:(FIRStorageVoidURLError)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Firebase/Storage/Private/FIRStorageGetDownloadURLTask_Private.h b/Firebase/Storage/Private/FIRStorageGetDownloadURLTask_Private.h new file mode 100644 index 0000000..0da04a4 --- /dev/null +++ b/Firebase/Storage/Private/FIRStorageGetDownloadURLTask_Private.h @@ -0,0 +1,31 @@ +/* + * Copyright 2018 Google + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FIRStorageGetDownloadURLTask.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Task which provides the ability to get a download URL for an object in Firebase Storage. + */ +@interface FIRStorageGetDownloadURLTask () + +/** Extracts a download URL from the StorageMetadata dictonary representation. */ ++ (nullable NSURL *)downloadURLFromMetadataDictionary:(NSDictionary *)dictionary; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Firebase/Storage/Public/FIRStorageMetadata.h b/Firebase/Storage/Public/FIRStorageMetadata.h index 2e3cc13..63b8798 100644 --- a/Firebase/Storage/Public/FIRStorageMetadata.h +++ b/Firebase/Storage/Public/FIRStorageMetadata.h @@ -113,12 +113,6 @@ NS_SWIFT_NAME(StorageMetadata) @property(strong, nonatomic, readonly, nullable) FIRStorageReference *storageReference; /** - * An array containing all download URLs available for the object. - */ -@property(strong, nonatomic, readonly, nullable) NSArray<NSURL *> *downloadURLs __deprecated_msg( - "Use `StorageReference.downloadURLWithCompletion()` to obtain a current download URL."); - -/** * Creates an instanece of FIRStorageMetadata from the contents of a dictionary. * @return An instance of FIRStorageMetadata that represents the contents of a dictionary. */ @@ -141,14 +135,6 @@ NS_SWIFT_NAME(StorageMetadata) */ @property(readonly, getter=isFolder) BOOL folder; -/** - * Retrieves a download URL for the given object, or nil if none exist. - * Note that if there are many valid download tokens, this will always return the first - * valid token created. - */ -- (nullable NSURL *)downloadURL __deprecated_msg( - "Use `StorageReference.downloadURLWithCompletion()` to obtain a current download URL."); - @end NS_ASSUME_NONNULL_END |