Ryan Knopp
Ryan Knopp

Reputation: 612

NSURLDownload: Assertion failed ([path isAbsolutePath]) troubles

I'm trying to download a file off the internet and place it in the application name directory under the Application Support directory and I keep getting a

Assertion failed: ([path isAbsolutePath]), function -[NSURLDownload     setDestination:allowOverwrite:], file /SourceCache/CFNetwork/CFNetwork-720.5.7/Foundation/NSURLDownload.mm, line 370.

Here's the code that I wrote:

    var imageRequest = NSURLRequest(URL: self.source)
    var imageDownload = NSURLDownload(request: imageRequest, delegate:self)
    var error: NSError? = NSError()

    /* does path exist */
    let directoryPath = self.destination.stringByDeletingLastPathComponent
    let fileMgr = NSFileManager();
    fileMgr.createDirectoryAtPath(directoryPath, withIntermediateDirectories: true, attributes: nil, error: &error)
    imageDownload.setDestination(self.destination, allowOverwrite: true);

When I step through the code everything looks correct. self.source is (https:/remoteDomain.com/img/downloadimage.jpg) a NSURL

self.destination is the full path in my system (file:/Users/ryan/Library/Application%20Support/AppName/downloadimage.jpg)

Any Ideas?

Upvotes: 0

Views: 302

Answers (1)

mangerlahn
mangerlahn

Reputation: 4966

To answer the question to your specific topic: The error message says that your path is invalid. The right way to create the path for your image is the following:

let fileManager = NSFileManager.defaultManager()

var folder = "~/Library/Application Support/[APPNAME]/someFolder" as NSString
folder = folder.stringByExpandingTildeInPath

if fileManager.fileExistsAtPath(folder as String) == false {
    do {
        try fileManager.createDirectoryAtPath(folder as String, withIntermediateDirectories: true, attributes: nil)
    }

    catch {
       //Deal with the error
    }
}

BUT @jtbandes is right. You should use NSURLSessionDownloadTask to download your files. It is part of the Foundation.framework, which is available on OS X, iOS and watchOS.

The reason to use it is that Apple keeps updating this Api to meet the latest standards. For example, you don't need to worry about IPv4 or IPv6 etc. This avoids crashes and weird behavior in your app.

This is how you use it (Swift):

var imageRequest = NSURLRequest(URL: self.source)
let session = NSURLSession.sharedSession()
let downloadTask = session.downloadTaskWithRequest(imageRequest) { (url: NSURL?, response: NSURLResponse?, error: NSError?) -> Void in
    //Work with data
}

downloadTask.resume()

Note that url is the path to the downloaded image.

Upvotes: 1

Related Questions