Skip to content
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

iOS path usage with FileManager.default.urls #1128

Closed
vanniktech opened this issue Jul 4, 2022 · 2 comments
Closed

iOS path usage with FileManager.default.urls #1128

vanniktech opened this issue Jul 4, 2022 · 2 comments

Comments

@vanniktech
Copy link
Contributor

vanniktech commented Jul 4, 2022

I've got a wrapper aound FileSystem as I want to support other systems (mainly Amazon S3) as well:

class FileSystemFileHandler(
 root: String,
 private val fileSystem: FileSystem,
) : FileHandler {
 private val root = root.toPath()

 override fun write(path: String, source: Source) {
   val okioPath = root / path
   okioPath.parent?.let { fileSystem.createDirectories(it) }

   source.buffer().use { input ->
     fileSystem.sink(okioPath).buffer().use { output ->
       output.writeAll(input)
     }
   }
 }
}

On Android, I do:

FileSystemFileHandler(filesDir.absolutePath, FileSystem.SYSTEM)

On iOS, I do:

FileSystemFileHandler(
  root: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString,
  fileSystem: OkioFileSystem.Companion().SYSTEM
)

The problem with iOS is though that:

FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString

returns

file:https:///Users/niklas/Library/Developer/CoreSimulator/Devices/A4BE2A42-D3FB-48D7-8D3B-C5C154A0F214/data/Containers/Data/Application/E095BAD5-33A5-499C-93A9-E10530F8A041/Documents/

Which isn't handled. When trying to write a file I get an error message saying that the file system is read only.

The fix is:

-FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString
+FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString.removePrefix("file:https://")

Is Path just not handling file:https:// prefix correctly? Should it be lenient and automatically remove the prefix or is it a valid case to distinguish between /Users/niklas/ and file:https:///Users/niklas/?

@swankjesse
Copy link
Member

Path expects a path and not a URL so your fix is correct. I don't think we should remove this prefix automatically; it's possible you actually want the literal interpretation of the string file:https:///foo which is a surprising but not impossible file path equivalent to file:/foo.

We could was also build behavior to convert file:-schemed URLs to paths. Removing the prefix is completely sufficient in your situation but not on Windows and not in general.
https://datatracker.ietf.org/doc/html/rfc8089#appendix-E

@vanniktech
Copy link
Contributor Author

There's a simpler solution, URL has a path property which returns what okio wants 🤦 .

+FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString.removePrefix("file:https://")
-FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].path

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants