NSFileManager.defaultManager().fileExistsAtPath returns false instead of true
(The code in this answer has been updated for Swift 3 and later.)
Apparently your path
variable is a NSURL
(describing a file path). To get the path as
a string, use the path
property, not absoluteString
:
let exists = FileManager.default.fileExists(atPath: path.path)
absoluteString
returns the URL in a string format, including
the file:
scheme etc.
Example:
let url = URL(fileURLWithPath: "/path/to/foo.txt")
// This is what you did:
print(url.absoluteString)
// Output: file:///path/to/foo.txt
// This is what you want:
print(url.path)
// Output: /path/to/foo.txt
NSFileManager fileExistsAtPath returns true and false for the same path in two different classes after a segue (and the file exists)
To answer to Raymond26 and other who might have similar issue, I finally understood that you should never make any assumption on a file path outside your app's sandbox, like "/var/mobile/Media/DCIM/100APPLE/IMG_0045.JPG"
Instead, you should use the PHAsset API to read and write these files, and if you really need a file path (like I did as I was doing processing with a C library on the file) you should copy the file to your app's temp directory before doing so.
static func copyToTemp(asset: PHAsset, desFileName: NSURL, requestedMaxSize: Int) throws
{
NSLog("copying asset to thumb for editing to: \(desFileName.path) with max size \(requestedMaxSize)")
// Clean temp as iOS doesnt do much overwriting in general
if(NSFileManager.defaultManager().fileExistsAtPath(desFileName.path!))
{
try NSFileManager.defaultManager().removeItemAtURL(desFileName)
}
if(requestedMaxSize < 0) // No resizing, just copy
{
let options = PHImageRequestOptions()
options.synchronous = true
PHImageManager.defaultManager().requestImageDataForAsset(asset, options: options, resultHandler: { (data: NSData?, name: String?, orientation: UIImageOrientation, stuff: [NSObject: AnyObject]?) in
do
{
try data?.writeToURL(desFileName, options: NSDataWritingOptions.AtomicWrite)
}
catch
{
NSLog("error writing full-sized to temp: \(error)")
}
})
}
else // Copy and resize
{
let size = CGSizeMake(CGFloat(requestedMaxSize), CGFloat(requestedMaxSize))
let options = PHImageRequestOptions()
options.synchronous = true
options.deliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat
options.resizeMode = PHImageRequestOptionsResizeMode.Exact
PHImageManager.defaultManager().requestImageForAsset(asset, targetSize: size, contentMode: PHImageContentMode.AspectFit, options: options, resultHandler:
{
(image: UIImage?, obj: [NSObject: AnyObject]?) -> Void in
do
{
try UIImageJPEGRepresentation(image!, 0.8)!.writeToURL(desFileName, options: NSDataWritingOptions.AtomicWrite)
}
catch
{
NSLog("error writing resized to temp: \(error)")
}
})
}
}
FileManager.default.fileExists says documents directory does not exist
Turns out one should use documentsURL.path
, instead of any sort of URL.
The path begins with /var/mobile...
whereas the URLs begin with file:///var...
NSFileManager.defaultManager().fileExistsAtPath returns false when using iOS device
Applications are only allowed to access their own directory. Access to other parts is denied, so naturally all queries for files will say they don't exist.
The internal components like media playing have access to other directories also, otherwise you wouldn't be able to play items from the camera roll at all inside applications.
Seems the simulator doesn't enforce the permissions at all.
More information about filesystem on iOS.
NSFileManager.defaultManager().createFileAtPath() returning false
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var image: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let url = NSURL(string: "http://7-themes.com/data_images/out/3/6776407-beautiful-scenery-pictures.jpg")!
let urlRequest = NSURLRequest(URL: url)
let task = NSURLSession.sharedSession().dataTaskWithRequest(urlRequest, completionHandler: { (data, response, error) -> Void in
// you should always do it from the main queue otherwise you will experience a big delay when trying to display your image
dispatch_async(dispatch_get_main_queue()) {
// unwrap your data
if let data = data {
print(data.length)
// get your caches directory URL
let cachesDirectory = try! NSFileManager().URLForDirectory(.CachesDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)
// create your local file url by appending your url last path component
let fileUrl = cachesDirectory.URLByAppendingPathComponent(url.lastPathComponent!)
// save downloaded data to disk
if data.writeToURL(fileUrl, atomically: true) {
print(true)
// load your saved image from disk
self.image.image = UIImage(contentsOfFile: fileUrl.path!)
}
}
}
})
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Note you will need to edit your plist as follow:
How to avoiding file:// in URL.absoluteString in swift4
You can use path: String?
property of your URL instance
if url.isFileURL, let path = url.path {
print(path)
} else {
print("Not file URL")
}
Related Topics
How to Export Uiimage Array as a Movie
How to Force a Uiviewcontroller to Portrait Orientation in iOS 6
Status Bar and Navigation Bar Issue in Ios7
Objective-C Arc: Strong VS Retain and Weak VS Assign
How to Create Dispatch Queue in Swift 3
Get Button Click Inside Uitableviewcell
Swift Png Image Being Saved With Incorrect Orientation
Max Size of an iOS Application
Iphone Hide Navigation Bar Only on First Page
How to Hide Keyboard When Using Swiftui
How to Input Currency Format on a Text Field (From Right to Left) Using Swift
How to Detect When Someone Shakes an Iphone
Remove HTML Tags from an Nsstring on the Iphone
How to Check If a String Contains Another String in Objective-C
How to Make a Simple Collection View With Swift
How to Change the Background Color of a Uibutton While It's Highlighted