0
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.

Adam
  • 104
  • 10
  • You cannot use `String()` to convert a NSURL to a file path string, similar problem here: http://stackoverflow.com/questions/34850587/swift-reading-a-plist-from-mainbundle-and-writing-directly-to-documents-fails. – Martin R Jan 20 '16 at 10:53

4 Answers4

1

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:

Wain
  • 118,658
  • 15
  • 128
  • 151
1

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)
Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

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

    }
}
Dharmesh Kheni
  • 71,228
  • 33
  • 160
  • 165
0

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)
RebecaMartin
  • 163
  • 11