@react-native-firebase/storage 26.4.0 → 27.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/RNFBStorage.podspec +9 -4
- package/android/build.gradle +3 -0
- package/android/src/main/java/io/invertase/firebase/storage/RNFBStorageTaskRegistry.kt +88 -0
- package/android/src/test/java/io/invertase/firebase/storage/RNFBStorageTaskRegistryTest.java +25 -0
- package/dist/module/index.js +1 -2
- package/dist/module/index.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/lib/index.d.ts +1 -1
- package/dist/typescript/lib/types/internal.d.ts +2 -3
- package/dist/typescript/lib/types/internal.d.ts.map +1 -1
- package/dist/typescript/lib/version.d.ts +1 -1
- package/ios/RNFBStorage/RNFBStorageCommon.m +17 -98
- package/ios/RNFBStorage/RNFBStorageErrorCodeMapper.swift +122 -0
- package/ios/RNFBStorage/RNFBStorageErrorSnapshotDictBuilder.swift +70 -0
- package/ios/RNFBStorage/RNFBStorageTaskRegistry.m +28 -35
- package/ios/RNFBStorage/RNFBStorageTaskRegistryStorage.swift +87 -0
- package/ios/RNFBStorage/RNFBStorageTaskStatusMapper.swift +57 -0
- package/ios/RNFBStorage.xcodeproj/project.pbxproj +26 -0
- package/ios/RNFBStorageUnitTests/RNFBStorageErrorCodeMapperFacadeTests.m +91 -0
- package/ios/RNFBStorageUnitTests/RNFBStorageErrorCodeMapperTests.swift +211 -0
- package/ios/RNFBStorageUnitTests/RNFBStorageErrorSnapshotDictBuilderFacadeTests.m +125 -0
- package/ios/RNFBStorageUnitTests/RNFBStorageTaskRegistryStorageTests.swift +154 -0
- package/ios/RNFBStorageUnitTests/RNFBStorageTaskStatusMapperFacadeTests.m +52 -0
- package/ios/RNFBStorageUnitTests/RNFBStorageTaskStatusMapperTests.swift +58 -0
- package/ios/RNFBStorageUnitTests/RNFBStorageUnitTests.xcodeproj/project.pbxproj +50 -0
- package/lib/index.ts +1 -1
- package/lib/types/internal.ts +5 -4
- package/lib/version.ts +1 -1
- package/package.json +4 -4
- package/android/src/main/java/io/invertase/firebase/storage/RNFBStorageTaskRegistry.java +0 -93
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import Foundation
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Error payload attachment previously inline in
|
|
21
|
+
* `+[RNFBStorageCommon buildErrorSnapshotDict:taskSnapshotDict:]` and
|
|
22
|
+
* `+[RNFBStorageCommon buildErrorSnapshotDictFromCodeAndMessage:taskSnapshotDict:]`.
|
|
23
|
+
*
|
|
24
|
+
* Mutates `taskSnapshotDict` in place and returns the same instance (or nil when
|
|
25
|
+
* the snapshot dict is nil — matching ObjC nil-messaging).
|
|
26
|
+
*/
|
|
27
|
+
@objc(RNFBStorageErrorSnapshotDictBuilder)
|
|
28
|
+
public final class RNFBStorageErrorSnapshotDictBuilder: NSObject {
|
|
29
|
+
@objc(buildErrorSnapshotDict:taskSnapshotDict:)
|
|
30
|
+
public static func buildErrorSnapshotDict(
|
|
31
|
+
_ error: NSError?,
|
|
32
|
+
taskSnapshotDict: NSMutableDictionary?
|
|
33
|
+
) -> NSDictionary? {
|
|
34
|
+
guard let taskSnapshotDict else {
|
|
35
|
+
return nil
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let codeAndMessage = RNFBStorageErrorCodeMapper.codeAndMessage(for: error)
|
|
39
|
+
var errorPayload: [String: Any] = [
|
|
40
|
+
"code": codeAndMessage[0],
|
|
41
|
+
"message": codeAndMessage[1],
|
|
42
|
+
]
|
|
43
|
+
// Pre-port ObjC always set this key from `[error localizedDescription]`.
|
|
44
|
+
if let error {
|
|
45
|
+
errorPayload["nativeErrorMessage"] = error.localizedDescription
|
|
46
|
+
} else {
|
|
47
|
+
errorPayload["nativeErrorMessage"] = NSNull()
|
|
48
|
+
}
|
|
49
|
+
taskSnapshotDict["error"] = errorPayload
|
|
50
|
+
return taskSnapshotDict
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@objc(buildErrorSnapshotDictFromCodeAndMessage:taskSnapshotDict:)
|
|
54
|
+
public static func buildErrorSnapshotDictFromCodeAndMessage(
|
|
55
|
+
_ codeAndMessage: [Any]?,
|
|
56
|
+
taskSnapshotDict: NSMutableDictionary?
|
|
57
|
+
) -> NSDictionary? {
|
|
58
|
+
guard let taskSnapshotDict else {
|
|
59
|
+
return nil
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Pre-port ObjC indexed without bounds checks; callers always pass [code, message].
|
|
63
|
+
let pair = codeAndMessage!
|
|
64
|
+
taskSnapshotDict["error"] = [
|
|
65
|
+
"code": pair[0],
|
|
66
|
+
"message": pair[1],
|
|
67
|
+
]
|
|
68
|
+
return taskSnapshotDict
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -23,8 +23,18 @@
|
|
|
23
23
|
#import "RNFBApp/RNFBHandleMap.h"
|
|
24
24
|
#endif
|
|
25
25
|
|
|
26
|
+
#if __has_include(<RNFBStorage/RNFBStorage-Swift.h>)
|
|
27
|
+
#import <RNFBStorage/RNFBStorage-Swift.h>
|
|
28
|
+
#elif __has_include("RNFBStorage-Swift.h")
|
|
29
|
+
#import "RNFBStorage-Swift.h"
|
|
30
|
+
#elif __has_include("RNFBHandleMapStorage-Swift.inc")
|
|
31
|
+
#import "RNFBHandleMapStorage-Swift.inc"
|
|
32
|
+
#else
|
|
33
|
+
#error "RNFBStorageTaskRegistryStorage Swift interface not found"
|
|
34
|
+
#endif
|
|
35
|
+
|
|
26
36
|
@interface RNFBStorageTaskRegistry ()
|
|
27
|
-
@property(nonatomic, strong)
|
|
37
|
+
@property(nonatomic, strong) RNFBStorageTaskRegistryStorage *storage;
|
|
28
38
|
@end
|
|
29
39
|
|
|
30
40
|
@implementation RNFBStorageTaskRegistry
|
|
@@ -32,63 +42,46 @@
|
|
|
32
42
|
- (instancetype)init {
|
|
33
43
|
self = [super init];
|
|
34
44
|
if (self) {
|
|
35
|
-
|
|
45
|
+
_storage = [[RNFBStorageTaskRegistryStorage alloc] init];
|
|
36
46
|
}
|
|
37
47
|
return self;
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
- (void)rnfb_cancelHandle:(id)handle {
|
|
41
|
-
if (handle && [handle respondsToSelector:@selector(cancel)]) {
|
|
42
|
-
[handle cancel];
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
50
|
- (BOOL)put:(id)key value:(id)value error:(NSError **)error {
|
|
47
|
-
|
|
51
|
+
if (![self.storage putIfAbsent:key value:value]) {
|
|
52
|
+
if (error != nil) {
|
|
53
|
+
NSString *message = [NSString stringWithFormat:@"Handle id already registered: %@", key];
|
|
54
|
+
*error = [NSError errorWithDomain:RNFBHandleMapErrorDomain
|
|
55
|
+
code:RNFBHandleMapErrorCollision
|
|
56
|
+
userInfo:@{NSLocalizedDescriptionKey : message}];
|
|
57
|
+
}
|
|
58
|
+
return NO;
|
|
59
|
+
}
|
|
60
|
+
return YES;
|
|
48
61
|
}
|
|
49
62
|
|
|
50
63
|
- (BOOL)putOrDiscard:(id)key value:(id)value {
|
|
51
|
-
|
|
52
|
-
return YES;
|
|
53
|
-
}
|
|
54
|
-
[self rnfb_cancelHandle:value];
|
|
55
|
-
return NO;
|
|
64
|
+
return [self.storage putOrDiscard:key value:value];
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
- (id)get:(id)key {
|
|
59
|
-
return [self.
|
|
68
|
+
return [self.storage get:key];
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
- (id)take:(id)key {
|
|
63
|
-
return [self.
|
|
72
|
+
return [self.storage take:key];
|
|
64
73
|
}
|
|
65
74
|
|
|
66
75
|
- (id)takeIf:(id)key when:(BOOL (^)(id))condition {
|
|
67
|
-
return [self.
|
|
76
|
+
return [self.storage takeIf:key when:condition];
|
|
68
77
|
}
|
|
69
78
|
|
|
70
79
|
- (BOOL)takeAndCancel:(id)key {
|
|
71
|
-
|
|
72
|
-
// FIRStorage*Task cancel is void (no BOOL), so there is no keep-on-false path; always
|
|
73
|
-
// identity-take after cancel. Production setTaskStatus cancel uses takeIf then cancel
|
|
74
|
-
// (RNFBStorageHelper) — identity-safe; this helper matches Android ordering for registry/tests.
|
|
75
|
-
id handle = [self.map get:key];
|
|
76
|
-
if (handle == nil) {
|
|
77
|
-
return NO;
|
|
78
|
-
}
|
|
79
|
-
[self rnfb_cancelHandle:handle];
|
|
80
|
-
[self.map takeIf:key
|
|
81
|
-
when:^BOOL(id value) {
|
|
82
|
-
return value == handle;
|
|
83
|
-
}];
|
|
84
|
-
return YES;
|
|
80
|
+
return [self.storage takeAndCancel:key];
|
|
85
81
|
}
|
|
86
82
|
|
|
87
83
|
- (void)cancelAll {
|
|
88
|
-
|
|
89
|
-
for (id handler in handlers) {
|
|
90
|
-
[self rnfb_cancelHandle:handler];
|
|
91
|
-
}
|
|
84
|
+
[self.storage cancelAll];
|
|
92
85
|
}
|
|
93
86
|
|
|
94
87
|
@end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import Foundation
|
|
18
|
+
|
|
19
|
+
#if canImport(RNFBApp)
|
|
20
|
+
import RNFBApp
|
|
21
|
+
#endif
|
|
22
|
+
|
|
23
|
+
/// Pending upload/download task map storage. Composes `RNFBHandleMapStorage`.
|
|
24
|
+
/// `putOrDiscard` is first-wins and calls `cancel` on the incoming value on collision.
|
|
25
|
+
/// Unique `put` collision errors stay on the ObjC façade.
|
|
26
|
+
@objc(RNFBStorageTaskRegistryStorage)
|
|
27
|
+
public final class RNFBStorageTaskRegistryStorage: NSObject {
|
|
28
|
+
private static let cancelSelector = Selector(("cancel"))
|
|
29
|
+
|
|
30
|
+
private let storage = RNFBHandleMapStorage()
|
|
31
|
+
|
|
32
|
+
private func cancelHandle(_ handle: AnyObject?) {
|
|
33
|
+
guard let handle = handle, handle.responds(to: Self.cancelSelector) else {
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
_ = handle.perform(Self.cancelSelector)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/// First-wins store without discarding the incoming value. Used by façade `put`.
|
|
40
|
+
@objc(putIfAbsent:value:)
|
|
41
|
+
public func putIfAbsent(_ key: AnyObject, value: AnyObject) -> Bool {
|
|
42
|
+
storage.putIfAbsent(key, value: value)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// Unique put. On collision, `cancel`s the incoming value and leaves the existing mapping.
|
|
46
|
+
@objc(putOrDiscard:value:)
|
|
47
|
+
public func putOrDiscard(_ key: AnyObject, value: AnyObject) -> Bool {
|
|
48
|
+
if storage.putIfAbsent(key, value: value) {
|
|
49
|
+
return true
|
|
50
|
+
}
|
|
51
|
+
cancelHandle(value)
|
|
52
|
+
return false
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@objc(get:)
|
|
56
|
+
public func get(_ key: AnyObject) -> AnyObject? {
|
|
57
|
+
storage.get(key)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@objc(take:)
|
|
61
|
+
public func take(_ key: AnyObject) -> AnyObject? {
|
|
62
|
+
storage.take(key)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@objc(takeIf:when:)
|
|
66
|
+
public func takeIf(_ key: AnyObject, when condition: (AnyObject) -> Bool) -> AnyObject? {
|
|
67
|
+
storage.takeIf(key, when: condition)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/// get → cancel → identity take (Android shape). FIRStorage cancel is void (no keep-on-false).
|
|
71
|
+
@objc(takeAndCancel:)
|
|
72
|
+
public func takeAndCancel(_ key: AnyObject) -> Bool {
|
|
73
|
+
guard let handle = storage.get(key) else {
|
|
74
|
+
return false
|
|
75
|
+
}
|
|
76
|
+
cancelHandle(handle)
|
|
77
|
+
_ = storage.takeIf(key, when: { $0 === handle })
|
|
78
|
+
return true
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
@objc
|
|
82
|
+
public func cancelAll() {
|
|
83
|
+
for handle in storage.takeAll() {
|
|
84
|
+
cancelHandle(handle)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import Foundation
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* `FIRStorageTaskStatus` raw value → JS task-state string mapping previously
|
|
21
|
+
* inline in `+[RNFBStorageCommon getTaskStatus:]`.
|
|
22
|
+
*
|
|
23
|
+
* Raw ints from Firebase Storage `StorageTaskStatus`
|
|
24
|
+
* (`@objc(FIRStorageTaskStatus)` in `StorageConstants.swift`):
|
|
25
|
+
* - unknown = 0, resume = 1, progress = 2, pause = 3, success = 4, failure = 5
|
|
26
|
+
*
|
|
27
|
+
* Hardcoded so the Storage unit target does not need FirebaseStorage.
|
|
28
|
+
*/
|
|
29
|
+
@objc(RNFBStorageTaskStatusMapper)
|
|
30
|
+
public final class RNFBStorageTaskStatusMapper: NSObject {
|
|
31
|
+
/// `FIRStorageTaskStatusResume`
|
|
32
|
+
private static let statusResume = 1
|
|
33
|
+
/// `FIRStorageTaskStatusProgress`
|
|
34
|
+
private static let statusProgress = 2
|
|
35
|
+
/// `FIRStorageTaskStatusPause`
|
|
36
|
+
private static let statusPause = 3
|
|
37
|
+
/// `FIRStorageTaskStatusSuccess`
|
|
38
|
+
private static let statusSuccess = 4
|
|
39
|
+
/// `FIRStorageTaskStatusFailure`
|
|
40
|
+
private static let statusFailure = 5
|
|
41
|
+
|
|
42
|
+
@objc(stringForTaskStatus:)
|
|
43
|
+
public static func string(forTaskStatus status: Int) -> String {
|
|
44
|
+
if status == statusResume || status == statusProgress {
|
|
45
|
+
return "running"
|
|
46
|
+
} else if status == statusPause {
|
|
47
|
+
return "paused"
|
|
48
|
+
} else if status == statusSuccess {
|
|
49
|
+
return "success"
|
|
50
|
+
} else if status == statusFailure {
|
|
51
|
+
return "error"
|
|
52
|
+
} else {
|
|
53
|
+
// `FIRStorageTaskStatusUnknown` (0) and any other raw value
|
|
54
|
+
return "unknown"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
27A35B652268E118005BE5A8 /* RNFBStorageDownloadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A35B642268E118005BE5A8 /* RNFBStorageDownloadTask.m */; };
|
|
13
13
|
27A35B682268E138005BE5A8 /* RNFBStorageUploadTask.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A35B672268E138005BE5A8 /* RNFBStorageUploadTask.m */; };
|
|
14
14
|
27A35B6B2268E1BE005BE5A8 /* RNFBStorageCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 27A35B6A2268E1BE005BE5A8 /* RNFBStorageCommon.m */; };
|
|
15
|
+
RNFBSTOR0000000000000001 /* RNFBStorageTaskRegistry.m in Sources */ = {isa = PBXBuildFile; fileRef = RNFBSTOR0000000000000002 /* RNFBStorageTaskRegistry.m */; };
|
|
16
|
+
RNFBSTOR0000000000000003 /* RNFBStorageTaskRegistryStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBSTOR0000000000000004 /* RNFBStorageTaskRegistryStorage.swift */; };
|
|
17
|
+
RNFBSTOR0000000000000006 /* RNFBStorageTaskStatusMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBSTOR0000000000000007 /* RNFBStorageTaskStatusMapper.swift */; };
|
|
18
|
+
RNFBSTOR0000000000000008 /* RNFBStorageErrorCodeMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBSTOR0000000000000009 /* RNFBStorageErrorCodeMapper.swift */; };
|
|
19
|
+
RNFBSTOR000000000000000A /* RNFBStorageErrorSnapshotDictBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = RNFBSTOR000000000000000B /* RNFBStorageErrorSnapshotDictBuilder.swift */; };
|
|
15
20
|
/* End PBXBuildFile section */
|
|
16
21
|
|
|
17
22
|
/* Begin PBXCopyFilesBuildPhase section */
|
|
@@ -38,6 +43,12 @@
|
|
|
38
43
|
27A35B692268E143005BE5A8 /* RNFBStorageUploadTask.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNFBStorageUploadTask.h; sourceTree = "<group>"; };
|
|
39
44
|
27A35B6A2268E1BE005BE5A8 /* RNFBStorageCommon.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNFBStorageCommon.m; sourceTree = "<group>"; };
|
|
40
45
|
27A35B6C2268E1C8005BE5A8 /* RNFBStorageCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNFBStorageCommon.h; sourceTree = "<group>"; };
|
|
46
|
+
RNFBSTOR0000000000000005 /* RNFBStorageTaskRegistry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBStorageTaskRegistry.h; path = RNFBStorage/RNFBStorageTaskRegistry.h; sourceTree = SOURCE_ROOT; };
|
|
47
|
+
RNFBSTOR0000000000000002 /* RNFBStorageTaskRegistry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBStorageTaskRegistry.m; path = RNFBStorage/RNFBStorageTaskRegistry.m; sourceTree = SOURCE_ROOT; };
|
|
48
|
+
RNFBSTOR0000000000000004 /* RNFBStorageTaskRegistryStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBStorageTaskRegistryStorage.swift; path = RNFBStorage/RNFBStorageTaskRegistryStorage.swift; sourceTree = SOURCE_ROOT; };
|
|
49
|
+
RNFBSTOR0000000000000007 /* RNFBStorageTaskStatusMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBStorageTaskStatusMapper.swift; path = RNFBStorage/RNFBStorageTaskStatusMapper.swift; sourceTree = SOURCE_ROOT; };
|
|
50
|
+
RNFBSTOR0000000000000009 /* RNFBStorageErrorCodeMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBStorageErrorCodeMapper.swift; path = RNFBStorage/RNFBStorageErrorCodeMapper.swift; sourceTree = SOURCE_ROOT; };
|
|
51
|
+
RNFBSTOR000000000000000B /* RNFBStorageErrorSnapshotDictBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RNFBStorageErrorSnapshotDictBuilder.swift; path = RNFBStorage/RNFBStorageErrorSnapshotDictBuilder.swift; sourceTree = SOURCE_ROOT; };
|
|
41
52
|
/* End PBXFileReference section */
|
|
42
53
|
|
|
43
54
|
/* Begin PBXFrameworksBuildPhase section */
|
|
@@ -64,6 +75,12 @@
|
|
|
64
75
|
children = (
|
|
65
76
|
2744B98421F45429004F8E3F /* RNFBStorageModule.h */,
|
|
66
77
|
2744B98521F45429004F8E3F /* RNFBStorageModule.mm */,
|
|
78
|
+
RNFBSTOR0000000000000005 /* RNFBStorageTaskRegistry.h */,
|
|
79
|
+
RNFBSTOR0000000000000002 /* RNFBStorageTaskRegistry.m */,
|
|
80
|
+
RNFBSTOR0000000000000004 /* RNFBStorageTaskRegistryStorage.swift */,
|
|
81
|
+
RNFBSTOR0000000000000007 /* RNFBStorageTaskStatusMapper.swift */,
|
|
82
|
+
RNFBSTOR0000000000000009 /* RNFBStorageErrorCodeMapper.swift */,
|
|
83
|
+
RNFBSTOR000000000000000B /* RNFBStorageErrorSnapshotDictBuilder.swift */,
|
|
67
84
|
27A35B612268E0AB005BE5A8 /* RNFBStorageTask.m */,
|
|
68
85
|
27A35B632268E0CD005BE5A8 /* RNFBStorageTask.h */,
|
|
69
86
|
27A35B642268E118005BE5A8 /* RNFBStorageDownloadTask.m */,
|
|
@@ -142,6 +159,11 @@
|
|
|
142
159
|
isa = PBXSourcesBuildPhase;
|
|
143
160
|
buildActionMask = 2147483647;
|
|
144
161
|
files = (
|
|
162
|
+
RNFBSTOR0000000000000003 /* RNFBStorageTaskRegistryStorage.swift in Sources */,
|
|
163
|
+
RNFBSTOR0000000000000006 /* RNFBStorageTaskStatusMapper.swift in Sources */,
|
|
164
|
+
RNFBSTOR0000000000000008 /* RNFBStorageErrorCodeMapper.swift in Sources */,
|
|
165
|
+
RNFBSTOR000000000000000A /* RNFBStorageErrorSnapshotDictBuilder.swift in Sources */,
|
|
166
|
+
RNFBSTOR0000000000000001 /* RNFBStorageTaskRegistry.m in Sources */,
|
|
145
167
|
27A35B622268E0AB005BE5A8 /* RNFBStorageTask.m in Sources */,
|
|
146
168
|
27A35B6B2268E1BE005BE5A8 /* RNFBStorageCommon.m in Sources */,
|
|
147
169
|
2744B98621F45429004F8E3F /* RNFBStorageModule.mm in Sources */,
|
|
@@ -172,6 +194,7 @@
|
|
|
172
194
|
CODE_SIGN_STYLE = Automatic;
|
|
173
195
|
COPY_PHASE_STRIP = NO;
|
|
174
196
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
|
197
|
+
DEFINES_MODULE = YES;
|
|
175
198
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
|
176
199
|
GCC_DYNAMIC_NO_PIC = NO;
|
|
177
200
|
GCC_OPTIMIZATION_LEVEL = 0;
|
|
@@ -188,6 +211,7 @@
|
|
|
188
211
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
189
212
|
SDKROOT = iphoneos;
|
|
190
213
|
SKIP_INSTALL = YES;
|
|
214
|
+
SWIFT_VERSION = 5.10;
|
|
191
215
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
192
216
|
};
|
|
193
217
|
name = Debug;
|
|
@@ -211,6 +235,7 @@
|
|
|
211
235
|
CODE_SIGN_STYLE = Automatic;
|
|
212
236
|
COPY_PHASE_STRIP = NO;
|
|
213
237
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
238
|
+
DEFINES_MODULE = YES;
|
|
214
239
|
ENABLE_NS_ASSERTIONS = NO;
|
|
215
240
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
|
216
241
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
|
@@ -222,6 +247,7 @@
|
|
|
222
247
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
223
248
|
SDKROOT = iphoneos;
|
|
224
249
|
SKIP_INSTALL = YES;
|
|
250
|
+
SWIFT_VERSION = 5.10;
|
|
225
251
|
TARGETED_DEVICE_FAMILY = "1,2";
|
|
226
252
|
VALIDATE_PRODUCT = YES;
|
|
227
253
|
};
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this library except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
#import <XCTest/XCTest.h>
|
|
18
|
+
|
|
19
|
+
#import "RNFBHandleMapStorage-Swift.inc"
|
|
20
|
+
|
|
21
|
+
@interface RNFBStorageErrorCodeMapperFacadeTests : XCTestCase
|
|
22
|
+
@end
|
|
23
|
+
|
|
24
|
+
@implementation RNFBStorageErrorCodeMapperFacadeTests
|
|
25
|
+
|
|
26
|
+
- (NSError *)errorWithCode:(NSInteger)code description:(NSString *)description {
|
|
27
|
+
return [NSError errorWithDomain:@"FIRStorageErrorDomain"
|
|
28
|
+
code:code
|
|
29
|
+
userInfo:@{NSLocalizedDescriptionKey : description}];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
- (void)testObjCSelectorNilAndKnownCodes {
|
|
33
|
+
NSArray *nilPair = [RNFBStorageErrorCodeMapper codeAndMessageForError:nil];
|
|
34
|
+
XCTAssertEqualObjects(nilPair[0], @"unknown");
|
|
35
|
+
XCTAssertEqualObjects(nilPair[1], @"An unknown error has occurred.");
|
|
36
|
+
|
|
37
|
+
// FIRStorageErrorCodeObjectNotFound
|
|
38
|
+
NSArray *notFound = [RNFBStorageErrorCodeMapper codeAndMessageForError:[self errorWithCode:-13010
|
|
39
|
+
description:@"x"]];
|
|
40
|
+
XCTAssertEqualObjects(notFound[0], @"object-not-found");
|
|
41
|
+
XCTAssertEqualObjects(notFound[1], @"No object exists at the desired reference.");
|
|
42
|
+
|
|
43
|
+
// FIRStorageErrorCodeCancelled
|
|
44
|
+
NSArray *cancelled = [RNFBStorageErrorCodeMapper
|
|
45
|
+
codeAndMessageForError:[self errorWithCode:-13040 description:@"x"]];
|
|
46
|
+
XCTAssertEqualObjects(cancelled[0], @"cancelled");
|
|
47
|
+
XCTAssertEqualObjects(cancelled[1], @"User cancelled the operation.");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
- (void)testObjCSelectorUnknownPermissionAndResponseBody {
|
|
51
|
+
// Permission-denied underlying → invalid-device-file-path
|
|
52
|
+
NSError *underlying = [NSError
|
|
53
|
+
errorWithDomain:NSPOSIXErrorDomain
|
|
54
|
+
code:1
|
|
55
|
+
userInfo:@{
|
|
56
|
+
NSLocalizedDescriptionKey : @"The operation couldn’t be completed. Permission denied"
|
|
57
|
+
}];
|
|
58
|
+
NSError *permissionError = [NSError errorWithDomain:@"FIRStorageErrorDomain"
|
|
59
|
+
code:-13000
|
|
60
|
+
userInfo:@{NSUnderlyingErrorKey : underlying}];
|
|
61
|
+
NSArray *permissionPair = [RNFBStorageErrorCodeMapper codeAndMessageForError:permissionError];
|
|
62
|
+
XCTAssertEqualObjects(permissionPair[0], @"invalid-device-file-path");
|
|
63
|
+
XCTAssertEqualObjects(permissionPair[1],
|
|
64
|
+
@"The specified device file path is invalid or is restricted.");
|
|
65
|
+
|
|
66
|
+
// ResponseBody → formatted unknown message
|
|
67
|
+
NSError *bodyError = [NSError errorWithDomain:@"FIRStorageErrorDomain"
|
|
68
|
+
code:-13000
|
|
69
|
+
userInfo:@{@"ResponseBody" : @"backend detail"}];
|
|
70
|
+
NSArray *bodyPair = [RNFBStorageErrorCodeMapper codeAndMessageForError:bodyError];
|
|
71
|
+
XCTAssertEqualObjects(bodyPair[0], @"unknown");
|
|
72
|
+
XCTAssertEqualObjects(bodyPair[1],
|
|
73
|
+
@"An unknown error has occurred. (underlying reason 'backend detail')");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
- (void)testObjCSelectorDefaultKeepsLocalizedDescription {
|
|
77
|
+
// FIRStorageErrorCodeInvalidArgument
|
|
78
|
+
NSArray *pair = [RNFBStorageErrorCodeMapper
|
|
79
|
+
codeAndMessageForError:[self errorWithCode:-13050 description:@"keep me"]];
|
|
80
|
+
XCTAssertEqualObjects(pair[0], @"unknown");
|
|
81
|
+
XCTAssertEqualObjects(pair[1], @"keep me");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
- (void)testFacadePublicSelectorUnchanged {
|
|
85
|
+
XCTAssertTrue([RNFBStorageErrorCodeMapper respondsToSelector:@selector(codeAndMessageForError:)]);
|
|
86
|
+
NSMethodSignature *signature =
|
|
87
|
+
[RNFBStorageErrorCodeMapper methodSignatureForSelector:@selector(codeAndMessageForError:)];
|
|
88
|
+
XCTAssertEqual(strcmp(signature.methodReturnType, @encode(id)), 0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@end
|