Swift 3.0 FileManager.fileExistsatPath always return false
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
When FileManager.default.fileExists(atPath:) always returns false, the most common cause is passing a URL object (or URL string with file:// prefix) instead of a plain file path string. fileExists(atPath:) expects a POSIX path like /Users/name/file.txt, not a URL like file:///Users/name/file.txt. Other causes include sandbox restrictions (iOS apps can only access their own containers), incorrect bundle resource paths, and case sensitivity on certain file systems.
The Most Common Cause: URL vs Path
The difference:
fileURL.absoluteString→"file:///var/mobile/Containers/.../data.json"(URL)fileURL.path→"/var/mobile/Containers/.../data.json"(path)
Checking Bundle Resources
iOS Sandbox: Correct Directories
iOS apps can only access their own sandbox directories:
Debugging File Existence
Writing Then Reading a File
macOS: Permissions and Sandboxing
Using URL-Based APIs Instead
Modern Swift APIs prefer URLs over paths:
Common Pitfalls
- Using
url.absoluteStringinstead ofurl.path:absoluteStringincludes thefile://scheme prefix, whichfileExists(atPath:)does not understand. Always use.pathto get a plain POSIX path from a URL. - Hardcoding file paths on iOS: iOS app container paths change between installs and simulator runs. Never hardcode paths like
/var/mobile/Containers/.... Always construct paths dynamically usingFileManager.urls(for:in:). - Checking for a bundle resource that was not added to the target: If a file is in the project navigator but not in the target's "Copy Bundle Resources" build phase, it is not included in the app bundle. Verify the file is listed under Build Phases in Xcode.
- Testing on the simulator with a case-insensitive file system: macOS (the simulator's host) uses a case-insensitive file system by default, so
"Data.json"and"data.json"both resolve. On a real device, the file system is case-sensitive, and mismatched casing returnsfalse. - Not handling the
isDirectoryparameter:fileExists(atPath:)returnstruefor both files and directories. If you specifically need a file (not a directory), usefileExists(atPath:isDirectory:)and check theObjCBooloutput parameter.
Summary
- Use
url.path(noturl.absoluteString) when passing a URL tofileExists(atPath:) - Use
Bundle.main.path(forResource:ofType:)to locate bundle resources - Build paths dynamically with
FileManager.urls(for:in:)— never hardcode iOS paths - Debug by printing the full path and listing the parent directory contents
- Prefer URL-based APIs (
checkResourceIsReachable()) over path-based ones in modern Swift
Related reading
- Swift 3.0 Result of call is unused
- Swift 3.0 Result of call is unused
- Swift 3 - Comparing Date objects
- Swift 3 - device tokens are now being parsed as '32BYTES
- Swift Compiler Error Expression too complex on a string concatenation
- Swift Compiler Error Expression too complex on a string concatenation
- Swift 3 Decimal, NSDecimal and NSDecimalNumber
- Swift 3 for loop with increment
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.