expo-file-system 16.0.6 → 16.0.7
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 +7 -0
- package/android/build.gradle +2 -2
- package/ios/FileSystemExceptions.swift +18 -0
- package/ios/FileSystemHelpers.swift +42 -0
- package/ios/FileSystemModule.swift +12 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 16.0.7 — 2024-02-27
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- [iOS] Fix downloadAsync for local files. ([#27187](https://github.com/expo/expo/pull/27187) by [@gabrieldonadel](https://github.com/gabrieldonadel))
|
|
18
|
+
- On `iOS`, fix an issue with `copyAsync` where the copy fails if it is a photo library asset. ([#27208](https://github.com/expo/expo/pull/27208) by [@alanjhughes](https://github.com/alanjhughes))
|
|
19
|
+
|
|
13
20
|
## 16.0.6 — 2024-02-06
|
|
14
21
|
|
|
15
22
|
### 🐛 Bug fixes
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '16.0.
|
|
6
|
+
version = '16.0.7'
|
|
7
7
|
|
|
8
8
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
9
9
|
if (expoModulesCorePlugin.exists()) {
|
|
@@ -94,7 +94,7 @@ android {
|
|
|
94
94
|
namespace "expo.modules.filesystem"
|
|
95
95
|
defaultConfig {
|
|
96
96
|
versionCode 30
|
|
97
|
-
versionName "16.0.
|
|
97
|
+
versionName "16.0.7"
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -8,6 +8,12 @@ final class FileNotExistsException: GenericException<String> {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
final class FileAlreadyExistsException: GenericException<String> {
|
|
12
|
+
override var reason: String {
|
|
13
|
+
"File '\(param)' already exists"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
final class DirectoryNotExistsException: GenericException<String> {
|
|
12
18
|
override var reason: String {
|
|
13
19
|
"Directory '\(param)' does not exist"
|
|
@@ -79,3 +85,15 @@ final class FailedToAccessDirectoryException: Exception {
|
|
|
79
85
|
"Failed to access `Caches` directory"
|
|
80
86
|
}
|
|
81
87
|
}
|
|
88
|
+
|
|
89
|
+
final class FailedToCopyAssetException: GenericException<String> {
|
|
90
|
+
override var reason: String {
|
|
91
|
+
"Failed to copy photo library asset: \(param)"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
final class FailedToFindAssetException: GenericException<String> {
|
|
96
|
+
override var reason: String {
|
|
97
|
+
"Failed to find photo library asset: \(param)"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// Copyright 2023-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
import ExpoModulesCore
|
|
4
|
+
import Photos
|
|
5
|
+
|
|
6
|
+
private let assetIdentifier = "ph://"
|
|
4
7
|
|
|
5
8
|
internal func ensureFileDirectoryExists(_ fileUrl: URL) throws {
|
|
6
9
|
let directoryPath = fileUrl.deletingLastPathComponent()
|
|
@@ -64,3 +67,42 @@ internal func ensurePathPermission(_ appContext: AppContext?, path: String, flag
|
|
|
64
67
|
throw flag == .read ? FileNotReadableException(path) : FileNotWritableException(path)
|
|
65
68
|
}
|
|
66
69
|
}
|
|
70
|
+
|
|
71
|
+
internal func isPHAsset(path: String) -> Bool {
|
|
72
|
+
return path.contains(assetIdentifier)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
internal func copyPHAsset(fromUrl: URL, toUrl: URL, with resourceManager: PHAssetResourceManager, promise: Promise) {
|
|
76
|
+
if isPhotoLibraryStatusAuthorized() {
|
|
77
|
+
if FileManager.default.fileExists(atPath: toUrl.path) {
|
|
78
|
+
promise.reject(FileAlreadyExistsException(toUrl.path))
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let identifier = fromUrl.absoluteString.replacingOccurrences(of: assetIdentifier, with: "")
|
|
83
|
+
|
|
84
|
+
guard let asset = PHAsset.fetchAssets(withLocalIdentifiers: [identifier], options: nil).firstObject else {
|
|
85
|
+
promise.reject(FailedToFindAssetException(fromUrl.absoluteString))
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let firstResource = PHAssetResource.assetResources(for: asset).first
|
|
90
|
+
if let firstResource {
|
|
91
|
+
resourceManager.writeData(for: firstResource, toFile: toUrl, options: nil) { error in
|
|
92
|
+
if let error {
|
|
93
|
+
promise.reject(FailedToCopyAssetException(fromUrl.absoluteString))
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
promise.reject(FailedToCopyAssetException(fromUrl.absoluteString))
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
internal func isPhotoLibraryStatusAuthorized() -> Bool {
|
|
103
|
+
if #available(iOS 14, tvOS 14, *) {
|
|
104
|
+
let status = PHPhotoLibrary.authorizationStatus(for: .readWrite)
|
|
105
|
+
return status == .authorized || status == .limited
|
|
106
|
+
}
|
|
107
|
+
return PHPhotoLibrary.authorizationStatus() == .authorized
|
|
108
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright 2023-present 650 Industries. All rights reserved.
|
|
2
2
|
|
|
3
3
|
import ExpoModulesCore
|
|
4
|
+
import Photos
|
|
4
5
|
|
|
5
6
|
private let EVENT_DOWNLOAD_PROGRESS = "expo-file-system.downloadProgress"
|
|
6
7
|
private let EVENT_UPLOAD_PROGRESS = "expo-file-system.uploadProgress"
|
|
@@ -8,6 +9,7 @@ private let EVENT_UPLOAD_PROGRESS = "expo-file-system.uploadProgress"
|
|
|
8
9
|
public final class FileSystemModule: Module {
|
|
9
10
|
private lazy var sessionTaskDispatcher = EXSessionTaskDispatcher(sessionHandler: ExpoAppDelegate.getSubscriberOfType(FileSystemBackgroundSessionHandler.self))
|
|
10
11
|
private lazy var taskHandlersManager = EXTaskHandlersManager()
|
|
12
|
+
private lazy var resourceManager = PHAssetResourceManager()
|
|
11
13
|
|
|
12
14
|
private lazy var backgroundSession = createUrlSession(type: .background, delegate: sessionTaskDispatcher)
|
|
13
15
|
private lazy var foregroundSession = createUrlSession(type: .foreground, delegate: sessionTaskDispatcher)
|
|
@@ -100,6 +102,11 @@ public final class FileSystemModule: Module {
|
|
|
100
102
|
AsyncFunction("copyAsync") { (options: RelocatingOptions, promise: Promise) in
|
|
101
103
|
let (fromUrl, toUrl) = try options.asTuple()
|
|
102
104
|
|
|
105
|
+
if isPHAsset(path: fromUrl.absoluteString) {
|
|
106
|
+
copyPHAsset(fromUrl: fromUrl, toUrl: toUrl, with: resourceManager, promise: promise)
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
103
110
|
try ensurePathPermission(appContext, path: fromUrl.path, flag: .read)
|
|
104
111
|
try ensurePathPermission(appContext, path: toUrl.path, flag: .write)
|
|
105
112
|
|
|
@@ -134,6 +141,11 @@ public final class FileSystemModule: Module {
|
|
|
134
141
|
try ensureFileDirectoryExists(localUrl)
|
|
135
142
|
try ensurePathPermission(appContext, path: localUrl.path, flag: .write)
|
|
136
143
|
|
|
144
|
+
if sourceUrl.isFileURL {
|
|
145
|
+
try ensurePathPermission(appContext, path: sourceUrl.path, flag: .read)
|
|
146
|
+
EXFileSystemLocalFileHandler.copy(from: sourceUrl, to: localUrl, resolver: promise.resolver, rejecter: promise.legacyRejecter)
|
|
147
|
+
return
|
|
148
|
+
}
|
|
137
149
|
let session = options.sessionType == .background ? backgroundSession : foregroundSession
|
|
138
150
|
let request = createUrlRequest(url: sourceUrl, headers: options.headers)
|
|
139
151
|
let downloadTask = session.downloadTask(with: request)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-file-system",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.7",
|
|
4
4
|
"description": "Provides access to the local file system on the device.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -41,5 +41,5 @@
|
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"expo": "*"
|
|
43
43
|
},
|
|
44
|
-
"gitHead": "
|
|
44
|
+
"gitHead": "e94e2aac39cbb7f8788869cd6798bbdeadc58f42"
|
|
45
45
|
}
|