What is the difference between a file URL and a web URL, and URL(fileURLWithPath:) and URL(string:)?
Predict first
What does this print?
print(URL(string: "/tmp/x")!.isFileURL, URL(fileURLWithPath: "/tmp/x").isFileURL)
- true true
- false true
- false false
Predict first
What does this print?
let u = URL(fileURLWithPath: "/a/b")
print(u.path, u.absoluteString)
- /a/b /a/b
- /a/b file:///a/b
Mental model. A file path is a street address inside your own building. A web URL includes the city and the country.
URL(fileURLWithPath:) takes a file system path, adds the file:// scheme, resolves a relative path against the current directory, and escapes characters as needed. URL(string:) parses URL text as is: "/tmp/x" has no scheme, so it is not a file URL, and opening it will go wrong.
Read a file’s path with url.path (or path(percentEncoded: false)), not absoluteString, which is the escaped file:///… form. User-picked files outside your sandbox need a security-scoped URL: call startAccessingSecurityScopedResource() and balance it with stop…. On Apple platforms a path can also appear as /private/var/… or /var/…, so compare with resolvingSymlinksInPath().
Only the second form knows the text is a file path, so only it adds the file:// scheme.
path is the plain path; absoluteString is the full escaped URL.
Common traps
- Using
URL(string:)for a path. You get a URL with no scheme, and file APIs reject it. - Showing
absoluteStringto a user. They see%20for every space. Show the last path component or the decoded path.
They might follow up with
- What is a security-scoped bookmark? Saved access to a user-chosen file that survives relaunch, created from a picker URL.
- How do you tell files from folders? Ask for
.isDirectoryKeyin the resource values, or passisDirectory:when you know.
Related questions
- 2.3.1 What is a URL in Foundation, and what does URL(string:) accept?
- 2.3.6 Where should an iOS app put files: Documents, Application Support, Caches or tmp?
← What is a URL in Foundation, and what does URL(string:) accept? How do you build, change and resolve URL paths safely? →