10 Replies
      Latest reply: Jan 31, 2017 3:46 PM by jquinterito RSS
      johnkx Level 1 Level 1 (0 points)

        Hi there, I've been looking for sample codes on how to save image and load image with document directory, but most of it that I found couldn't be use with Swift 3.. Is there anyone could refer me to a link or can help me out??

        • Re: Swift 3 - Save image and load image with document directory
          johnkx Level 1 Level 1 (0 points)

          I'm currently trying to change the code usable to Swift 3 by Dharmesh Kheni from

          http://stackoverflow.com/questions/30953070/get-image-name-uiimagepickercontroller-in-swift
          

           

          But I don't actually know how to do it, all I need is some tips or link on how to do it.. Help please..

          • Re: Swift 3 - Save image and load image with document directory
            eskimo Apple Staff Apple Staff (7,180 points)

            Here’s a trivial example of writing an image to disk as a PNG and then reading it back.

            let imageData = UIImagePNGRepresentation(image)!
            let docDir = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            let imageURL = docDir.appendingPathComponent("tmp.png")
            try! imageData.write(to: imageURL)
            
            let newImage = UIImage(contentsOfFile: imageURL.path)!
            

            I’ve left out all the error handling.  Specifically, you really want to handle any errors you get writing (line 4) or reading (line 6) the image.

            This uses a PNG representation, which is convenient but may not be the best option.  For JPEG you could use UIImageJPEGRepresentation instead.  For anything more complex, or for more control in general, check out the ImageIO framework.

            Share and Enjoy

            Quinn “The Eskimo!”
            Apple Developer Relations, Developer Technical Support, Core OS/Hardware
            let myEmail = "eskimo" + "1" + "@apple.com"

              • Re: Swift 3 - Save image and load image with document directory
                Qlogic Level 1 Level 1 (0 points)

                This is good, thanks.

                Now if you want to skipBackup (addSkipBackupAttributeToItemAtURL...) for this file

                what would that look like in Swift 3 ?

                  • Re: Swift 3 - Save image and load image with document directory
                    goldsdad Level 4 Level 4 (580 points)

                    There's an example for Swift 2 at https://developer.apple.com/library/content/qa/qa1719/_index.html and in Xcode docs.

                     

                    Try this translation to Swift 3:

                     

                    func addSkipBackupAttributeToItem(atPath path: String) -> Bool {
                       
                        var url = URL(fileURLWithPath: path)
                       
                        assert(FileManager.default.fileExists(atPath: path), "File \(path) does not exist")
                       
                        var success: Bool
                        do {
                            var resourceValues = URLResourceValues()
                            resourceValues.isExcludedFromBackup = true
                            try url.setResourceValues(resourceValues)
                            success = true
                        } catch let error as NSError {
                            success = false
                            print("Error excluding \(url.lastPathComponent) from backup \(error)");
                        }
                       
                        return success
                    }
                    

                     

                    URL is a struct (NSURL is a class), hence the var so its resource values can be modified.

                      • Re: Swift 3 - Save image and load image with document directory
                        Qlogic Level 1 Level 1 (0 points)

                        Great, This helps a lot.

                        I had read Technical Q&A QA1719 and some post but I was being a little slow on the uptake.

                        I did an in line version too;

                         

                        let directory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)

                                var storeUrl = directory.appendingPathComponent("MyApp.sqlite")

                              

                                var resourceValues = URLResourceValues()

                                resourceValues.isExcludedFromBackup = true

                                try! storeUrl.setResourceValues (resourceValues)

                                print("excluding \(storeUrl.lastPathComponent) from backup ")

                         

                        How's that.

                        Thanks.

                          • Re: Swift 3 - Save image and load image with document directory
                            goldsdad Level 4 Level 4 (580 points)

                            Why not create a function which can be reused and which will make the code that calls it easier to read and maintain?

                            Also, why use "try!" which will result in your program crashing if an error is thrown?

                              • Re: Swift 3 - Save image and load image with document directory
                                Qlogic Level 1 Level 1 (0 points)

                                Ok, you are right about the try! I'll fix that.

                                But when I use func addSkipBackupAttributeToItem(atPath path: String)...

                                where do I call it from?

                                 

                                if I call from the AppDelegate ...didFinishLaunchingWithOptions.. I get a Swift Compiler Warning-- 'Result of call to 'addSkipBackupAttributeToItem(atPath:)' is unused'

                                 

                                If called for after;

                                var storeUrl = directory.appendingPathComponent()

                                I get an Compiler Error -- Use of instance member 'addSkipBackupAttributeToItem' on type 'AppDelegate'; did you mean to use a value of type 'AppDelegate' instead?

                                 

                                That why I went with in-line.

                                  • Re: Swift 3 - Save image and load image with document directory
                                    QuinceyMorris Level 7 Level 7 (3,960 points)

                                    Goldsdad gave you a very literal translation of that QA1719 method, but that method does not follow current Swift or API conventions:

                                     

                                    — The method name does not follow current Swift naming conventions.

                                     

                                    — It should not have a path string parameter. The parameter should already be a URL.

                                     

                                    — It should not return a Bool result, but should throw an error if it fails.

                                     

                                    — It should not test for the existence of the file, but should simply go ahead and try setting the resource values, which will (correctly) throw an error if the file does not exist.

                                     

                                    — It doesn't need to handle the error, since the caller should handle it.

                                     

                                    Putting those things together, the translation becomes this:

                                     

                                    func addSkipBackupAttribute (toItemAt url: URL) throws { 
                                         var resourceValues = URLResourceValues() 
                                         resourceValues.isExcludedFromBackup = true 
                                         try url.setResourceValues(resourceValues) 
                                    }
                                    

                                     

                                    You can call this from your app delegate's "didFinishLaunching…" method. Because it can throw, you will need to use "try!" (to crash if it fails) or "try" (inside a do/catch block), depending on how you want to handle any error.

                                    • Re: Swift 3 - Save image and load image with document directory
                                      goldsdad Level 4 Level 4 (580 points)

                                      Similar to Quincey's response, you can add the following extension to URL:

                                       

                                      extension URL {
                                          mutating func excludeFromBackup(_ value: Bool) throws {    
                                              var resourceValues = URLResourceValues()
                                              resourceValues.isExcludedFromBackup = value
                                              try self.setResourceValues(resourceValues)
                                          }
                                      }
                                      
                                      

                                       

                                      Then when you have a URL for the item that's not to be backed up, you can write something like:

                                       

                                      do {
                                          try someURL.excludeFromBackup(true)
                                      } catch {
                                          ...
                                      }
                                      
                                      
                          • Re: Swift 3 - Save image and load image with document directory
                            jquinterito Level 1 Level 1 (0 points)

                            Did you solve the issue?