-
Notifications
You must be signed in to change notification settings - Fork 5.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[expo-file-system][next] Add download function. #30841
Conversation
The Pull Request introduced fingerprint changes against the base commit: 9bba2fe Fingerprint diff[
{
"op": "changed",
"source": {
"type": "dir",
"filePath": "../../packages/expo-file-system/android",
"reasons": [
"expoAutolinkingAndroid"
],
"hash": "d82cffb9b98d8fa3d17b1504eb3cf5bff7d9e516"
}
},
{
"op": "changed",
"source": {
"type": "dir",
"filePath": "../../packages/expo-file-system/ios",
"reasons": [
"expoAutolinkingIos"
],
"hash": "92f1b0f73ad303ed8a7c63a0e341b735ef87a8cf"
}
},
{
"op": "changed",
"source": {
"type": "dir",
"filePath": "../../packages/expo-modules-core",
"reasons": [
"expoAutolinkingIos",
"expoAutolinkingAndroid"
],
"hash": "a4c3c84f7eff58977cc1662c607eea45b6ba7f8f"
}
}
] Generated by PR labeler 🤖 |
2b40b10
to
a23ffff
Compare
@@ -12,3 +14,9 @@ internal class MoveDirectoryToFileException: Exception { | |||
"Unable to move a directory to a file" | |||
} | |||
} | |||
|
|||
internal class UnableToDownloadException: GenericException<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this OK, or should we make several reasons (no response, invalid response code (300/400), other)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could consider that in the future, but for now I think we don't have a very good mechanism for handling exceptions on the JS side – we should have our own Error class that can contain some custom data (like the response code) etc. and works well with error chaining
.../expo-file-system/android/src/main/java/expo/modules/filesystem/next/FileSystemNextModule.kt
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Android part looks good!
...ges/expo-modules-core/android/src/main/java/expo/modules/kotlin/devtools/OkHttpExtensions.kt
Outdated
Show resolved
Hide resolved
...o-file-system/android/src/main/java/expo/modules/filesystem/next/FileSystemNextExceptions.kt
Outdated
Show resolved
Hide resolved
@@ -6,6 +6,40 @@ public final class FileSystemNextModule: Module { | |||
public func definition() -> ModuleDefinition { | |||
Name("FileSystemNext") | |||
|
|||
AsyncFunction("download") { (url: URL, to: FileSystemPath, promise: Promise) in | |||
let downloadTask = URLSession.shared.downloadTask(with: url) { urlOrNil, responseOrNil, errorOrNil in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be great if there is an async/await version of that function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not resolved 😅 But I think it might be hard to make an async version of downloadTask(with:)
as opposed to the already existing download(from:)
. The latter doesn't seem to support downloading when the app is suspended though.
const directory = new Directory(testDirectory); | ||
const output = await download(url, directory); | ||
const file = new File( | ||
testDirectory + (Platform.OS === 'android' ? 'jpeg.jpg' : 'jpeg.jpeg') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we use the same extension on all platforms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We rely on OS functions to get a filename based on URL headers – I don't want to write my own now, but can look into that a bit more in the future.
https://developer.android.com/reference/android/webkit/URLUtil#guessFileName(java.lang.String,%20java.lang.String,%20java.lang.String)
8b2d4a5
to
a64b846
Compare
@@ -12,3 +14,9 @@ internal class MoveDirectoryToFileException: Exception { | |||
"Unable to move a directory to a file" | |||
} | |||
} | |||
|
|||
internal class UnableToDownloadException: GenericException<String> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could consider that in the future, but for now I think we don't have a very good mechanism for handling exceptions on the JS side – we should have our own Error class that can contain some custom data (like the response code) etc. and works well with error chaining
@@ -6,6 +6,40 @@ public final class FileSystemNextModule: Module { | |||
public func definition() -> ModuleDefinition { | |||
Name("FileSystemNext") | |||
|
|||
AsyncFunction("download") { (url: URL, to: FileSystemPath, promise: Promise) in | |||
let downloadTask = URLSession.shared.downloadTask(with: url) { urlOrNil, responseOrNil, errorOrNil in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not resolved 😅 But I think it might be hard to make an async version of downloadTask(with:)
as opposed to the already existing download(from:)
. The latter doesn't seem to support downloading when the app is suspended though.
@@ -6,6 +6,40 @@ public final class FileSystemNextModule: Module { | |||
public func definition() -> ModuleDefinition { | |||
Name("FileSystemNext") | |||
|
|||
AsyncFunction("download") { (url: URL, to: FileSystemPath, promise: Promise) in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest I think this should return a shared object (like the download task) that you can then pause/resume/cancel/listen to progress. It might be better to call it downloadFile
(Async?) (since it returns a File instance) and then we can introduce more powerful download
/downloadTask
in the future.
…ilesystem/next/FileSystemNextExceptions.kt Co-authored-by: Łukasz Kosmaty <[email protected]>
…kotlin/devtools/OkHttpExtensions.kt Co-authored-by: Łukasz Kosmaty <[email protected]>
Co-authored-by: Expo Bot <[email protected]>
9276c7e
to
3401835
Compare
# Why We allow downloading files and immediately getting a `File` instance to read the downloaded file. # How Added a module-level `download` function. We accept both target files and directories (we try to get the filename from correct headers) # Test Plan Added test cases. # Checklist <!-- Please check the appropriate items below if they apply to your diff. This is required for changes to Expo modules. --> - [ ] Documentation is up to date to reflect these changes (eg: https://docs.expo.dev and README.md). - [ ] Conforms with the [Documentation Writing Style Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md) - [ ] This diff will work correctly for `npx expo prebuild` & EAS Build (eg: updated a module plugin). --------- Co-authored-by: Expo Bot <[email protected]> Co-authored-by: Łukasz Kosmaty <[email protected]>
Why
We allow downloading files and immediately getting a
File
instance to read the downloaded file.How
Added a module-level
download
function. We accept both target files and directories (we try to get the filename from correct headers)Test Plan
Added test cases.
Checklist
npx expo prebuild
& EAS Build (eg: updated a module plugin).