Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: The file...doesn't exist when calling writeToFile on imageData

I am trying to write data to a file with the following code in a completion block for NSURLSessionDownloadTask:

   void (^completionBlock)(NSURLResponse *response, NSURL *filePath, NSError *error) = ^void (NSURLResponse *response, NSURL *filePath, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (!error){
                NSData *imageData = [NSData dataWithContentsOfURL:filePath];
                if(imageData) NSLog(@"image is not null");

                if(pic == 1) self.imageView.image = [UIImage imageWithData:imageData];
                else if(pic==2) self.imageView2.image = [UIImage imageWithData:imageData];

                NSArray *paths = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
                NSURL *documentsDirectoryURL = [paths lastObject];
                NSURL *saveLocation;
                if(pic == 1) saveLocation = [documentsDirectoryURL URLByAppendingPathComponent:self.pictureName1];
                else if (pic == 2) saveLocation = [documentsDirectoryURL URLByAppendingPathComponent:self.pictureName2];
                else saveLocation = [documentsDirectoryURL URLByAppendingPathComponent:self.pictureName3];

                NSLog(@"for # %d writing to file %@", pic, saveLocation);

                NSError *error = nil;                
                [imageData writeToFile:[saveLocation absoluteString] options:NSAtomicWrite error: &error];
                if(error){
                    NSLog(@"FAILED\n\n\n %@ \n\n\n", [error description]);
                }
     }

I am able to display the downloaded images in UIImageViews and my null check on imageData likewise confirms it's not null. However, when I try to write the data to a file, My NSLog prints out the following error indicating that the write failed:

(log statements)
# 3 writing to file file:///var/mobile/Containers/Data/Application/3743A163-7EE1-4A5A-BF81-7D1344D6DA45/Documents/pic3.png
Error Domain=NSCocoaErrorDomain Code=4 "The file “pic1.jpg” doesn’t exist." 
UserInfo={NSFilePath=file:///var/mobile/Containers/Data/Application/3743A163-7EE1-
4A5A-BF81-7D1344D6DA45/Documents/pic1.jpg, NSUnderlyingError=0x16d67200 {Error
Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}} 

I haven't been able to find another question on SO indicating this error message for this file, and I'm finding the error message quite counterintuitive. Where is my error?

like image 351
helloB Avatar asked Sep 22 '15 12:09

helloB


3 Answers

Instead of [saveLocation absoluteString], use [saveLocation path]. Basically the former gives you "file:///path/filename" while the latter gives you "/path/filename", which is the correct format.

like image 187
superarts.org Avatar answered Oct 24 '22 03:10

superarts.org


You may be having an issue with an intermediate directory that doesn't exist. If any sub directories (folders) don't exist when writing a file, it will fail.

Here is a handly function to create a single directory of any name in the documents folder. If you try to write to this after running this it should be fine.

static func createDirIfNeeded(dirName: String) {
        let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent(dirName + "/")
        do {
            try FileManager.default.createDirectory(atPath: dir.path, withIntermediateDirectories: true, attributes: nil)
        } catch {
            print(error.localizedDescription)
        }
    }
like image 40
paul_f Avatar answered Oct 24 '22 03:10

paul_f


Got Woking.. Thank you @superstart swift code below :

let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first
let fileNameString = fileURL.absoluteString.stringByReplacingOccurrencesOfString("/", withString: "");
let destinationUrl = documentsUrl!.URLByAppendingPathComponent("check.m4a")

let request: NSURLRequest = NSURLRequest(URL: fileURL)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{ (response: NSURLResponse?, datas: NSData?, error: NSError?) in
    if error == nil
    {
       // datas?.writeToFile(destinationUrl.absoluteString, atomically: false);

        do
        {
            let result = try Bool(datas!.writeToFile(destinationUrl.path!, options: NSDataWritingOptions.DataWritingAtomic))
            print(result);
        }
        catch let errorLoc as NSError
        {
            print(errorLoc.localizedDescription)
        }
    }
    else
    {
        print(error?.localizedDescription);
    }
}
like image 5
Antony Ouseph Avatar answered Oct 24 '22 02:10

Antony Ouseph