30

I've been learning swift rather quickly, and I'm trying to develop an OS X application that downloads images.

I've been able to parse the JSON I'm looking for into an array of URLs as follows:

func didReceiveAPIResults(results: NSArray) {
    println(results)
    for link in results {
        let stringLink = link as String
        //Check to make sure that the string is actually pointing to a file
        if stringLink.lowercaseString.rangeOfString(".jpg") != nil {2

            //Convert string to url
            var imgURL: NSURL = NSURL(string: stringLink)!

            //Download an NSData representation of the image from URL
            var request: NSURLRequest = NSURLRequest(URL: imgURL)

            var urlConnection: NSURLConnection = NSURLConnection(request: request, delegate: self)!
            //Make request to download URL
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: { (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
                if !(error? != nil) {
                    //set image to requested resource
                    var image = NSImage(data: data)

                } else {
                    //If request fails...
                    println("error: \(error.localizedDescription)")
                }
            })
        }
    }
}

So at this point I have my images defined as "image", but what I'm failing to grasp here is how to save these files to my local directory.

Any help on this matter would be greatly appreciated!

Thanks,

tvick47

Tyler
  • 889
  • 1
  • 11
  • 17

6 Answers6

40

In Swift 3:

Write

do {
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let fileURL = documentsURL.appendingPathComponent("\(fileName).png")
    if let pngImageData = UIImagePNGRepresentation(image) {
    try pngImageData.write(to: fileURL, options: .atomic)
    }
} catch { }

Read

let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let filePath = documentsURL.appendingPathComponent("\(fileName).png").path
if FileManager.default.fileExists(atPath: filePath) {
    return UIImage(contentsOfFile: filePath)
}
JPetric
  • 3,838
  • 28
  • 26
27

The following code would write a UIImage in the Application Documents directory under the filename 'filename.jpg'

var image = ....  // However you create/get a UIImage
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let destinationPath = documentsPath.stringByAppendingPathComponent("filename.jpg")
UIImageJPEGRepresentation(image,1.0).writeToFile(destinationPath, atomically: true)
shim
  • 9,289
  • 12
  • 69
  • 108
kurtn718
  • 751
  • 6
  • 5
  • 1
    Thanks for the response! However, whenever I try to build with that code I receive the error: `Use of unresolved identifier 'UIImageJPEGRepresentation'` – Tyler Oct 03 '14 at 02:34
  • 1
    That function exists on iOS. Here's how to do it using Mac APIs in Objective-C. Will post Swift version http://stackoverflow.com/questions/3038820/how-to-save-a-nsimage-as-a-new-file – kurtn718 Oct 03 '14 at 22:43
  • 1
    Thanks for the update! Although I do understand a bit further, a swift version would really help me out. Thanks! – Tyler Oct 04 '14 at 19:19
  • 1
    String doesn't have `stringByAppendingPathComponent` – Gargo Sep 16 '17 at 17:48
17

In swift 2.0, stringByAppendingPathComponent is unavailable, so the answer changes a bit. Here is what I've done to write a UIImage out to disk.

documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first!
if let image = UIImage(data: someNSDataRepresentingAnImage) {
    let fileURL = documentsURL.URLByAppendingPathComponent(fileName+".png")
    if let pngImageData = UIImagePNGRepresentation(image) {
        pngImageData.writeToURL(fileURL, atomically: false)
    }
}
Mario Hendricks
  • 727
  • 8
  • 7
1

UIImagePNGRepresentaton() function had been deprecated. try image.pngData()

0
@IBAction func savePhoto(_ sender: Any) {

        let imageData = UIImagePNGRepresentation(myImg.image!)
        let compresedImage = UIImage(data: imageData!)
        UIImageWriteToSavedPhotosAlbum(compresedImage!, nil, nil, nil)

        let alert = UIAlertController(title: "Saved", message: "Your image has been saved", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "Ok", style: .default)
        alert.addAction(okAction)
        self.present(alert, animated: true)
    }   
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
M Hamayun zeb
  • 448
  • 4
  • 10
0

Update for swift 5

just change filename.png to something else

func writeImageToDocs(image:UIImage){
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String

    let destinationPath = URL(fileURLWithPath: documentsPath).appendingPathComponent("filename.png")

    debugPrint("destination path is",destinationPath)

    do {
        try image.pngData()?.write(to: destinationPath)
    } catch {
        debugPrint("writing file error", error)
    }
}

func readImageFromDocs()->UIImage?{
    let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String

    let filePath = URL(fileURLWithPath: documentsPath).appendingPathComponent("filename.png").path
    if FileManager.default.fileExists(atPath: filePath) {
        return UIImage(contentsOfFile: filePath)
    } else {
        return nil
    }
}
Nic Wanavit
  • 2,363
  • 5
  • 19
  • 31