Adam
Adam

Reputation: 204

writeToFile doesn't work for saving photo

func fetchFromInternet(){
    let i = Int(DISPATCH_QUEUE_PRIORITY_HIGH.value)
    let que = dispatch_get_global_queue(i, 0)
    dispatch_async(que){
        if let url = NSURL(string: "http://www.hdwallpapers.in/walls/some_are_different-wide.jpg"){
            if let data = NSData(contentsOfURL: url){
                if let image = UIImage(data: data){
                    dispatch_async(dispatch_get_main_queue()){
                        self.spinner.stopAnimating()
                        self.imageContainer.image = image
                        let manager = NSFileManager.defaultManager()
                        var fileUrl = manager.URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: .UserDomainMask).first
                        fileUrl = fileUrl?.URLByAppendingPathComponent("photos")
                        do{
                            try manager.createDirectoryAtURL(fileUrl!, withIntermediateDirectories: false, attributes: nil)
                        }
                        catch{}
                        fileUrl = fileUrl?.URLByAppendingPathComponent("photo.jpg")
                        print(fileUrl)

                        if data.writeToFile(String(fileUrl!), atomically: true) {
                            print("saved to file")
                        }
                        else {
                            print("saving failed")
                        }
                    }
                }
            }
        }
    }
}

I have problem with this code. It always prints "saving failed". I'm just trying to save photo from internet. Im using some random photo here. Have no idea what I'm doing wrong. Code seems simple and correct.

Upvotes: 0

Views: 1148

Answers (4)

RebecaMartin
RebecaMartin

Reputation: 163

First of all, check that 'data' and 'fileURL' are not nil. In this case, I think that 'fileUrl' is your problem because is NSURL. writeToFile func requieres a String as input so you need to use .absoluteString property.

data.writeToFile(fileUrl!.absoluteString, atomically: true)

Upvotes: 0

Dharmesh Kheni
Dharmesh Kheni

Reputation: 71854

Here is the complete code to download image from Internet and store it to Document directory and you can access it too.

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageContainer: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        //get image from URL
        if let checkedUrl = NSURL(string: "http://www.hdwallpapers.in/walls/some_are_different-wide.jpg") {
            imageContainer.contentMode = .ScaleAspectFit
            downloadImage(checkedUrl)
        }
    }

    func getDocumentsURL() -> NSURL {
        let documentsURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
        return documentsURL
    }

    func fileInDocumentsDirectory(filename: String) -> String {

        let fileURL = getDocumentsURL().URLByAppendingPathComponent(filename)
        return fileURL.path!

    }

    func downloadImage(url: NSURL){
        print("Download Started")
        print("lastPathComponent: " + (url.lastPathComponent ?? ""))
        getDataFromUrl(url) { (data, response, error)  in
            dispatch_async(dispatch_get_main_queue()) { () -> Void in
                guard let data = data where error == nil else { return }
                print(response?.suggestedFilename ?? "")
                print("Download Finished")
                self.imageContainer.image = UIImage(data: data)

                let myImageName = "image.png"
                let imagePath = self.fileInDocumentsDirectory(myImageName)

                //Store that image into Document directory
                if let image = self.imageContainer.image {
                    self.saveImage(image, path: imagePath)
                } else { print("some error message") }

                //Retrive image from document directory
                if let loadedImage = self.loadImageFromPath(imagePath) {
                    print(" Loaded Image: \(loadedImage)")
                } else { print("some error message 2") }
            }
        }
    }

    func getDataFromUrl(url:NSURL, completion: ((data: NSData?, response: NSURLResponse?, error: NSError? ) -> Void)) {
        NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
            completion(data: data, response: response, error: error)
            }.resume()
    }

    func saveImage (image: UIImage, path: String ) -> Bool{

        let pngImageData = UIImagePNGRepresentation(image)
        //let jpgImageData = UIImageJPEGRepresentation(image, 1.0)   // if you want to save as JPEG
        let result = pngImageData!.writeToFile(path, atomically: true)

        return result

    }

    func loadImageFromPath(path: String) -> UIImage? {

        let image = UIImage(contentsOfFile: path)

        if image == nil {

            print("missing image at: \(path)")
        }
        print("Loading image from path: \(path)") // this is just for you to see the path in case you want to go to the directory, using Finder.
        return image

    }
}

Upvotes: 0

Rob
Rob

Reputation: 437432

The call to:

data.writeToFile(String(fileUrl!), atomically: true)

Should either be:

data.writeToFile(fileUrl!.path, atomically: true)

Or, better:

data.writeToURL(fileUrl!, atomically: true)

Upvotes: 1

Wain
Wain

Reputation: 119031

It's your responsibility to ensure that the folder exists before you try to write files into it. The file save method won't create it for you and will fail if it doesn't exist.

Use NSFileManager createDirectoryAtURL: withIntermediateDirectories:attributes:error:

Upvotes: 1

Related Questions