9 Replies
      Latest reply on Jun 8, 2019 6:57 AM by Pendragon
      Pendragon Level 1 Level 1 (0 points)

        Not sure if I have to do this programmatically or if there is something I should specifically use but I want to display a Progress Indicator when copying / moving files including the ability to cancel ?

         

        Also making the copy Async.

         

        (local hdd not web)

        • Re: Filemanager file copy progress with cancel ?
          eskimo Apple Staff Apple Staff (11,495 points)

          Getting progress for a file copy operation is surprisingly tricky, as discussed in this post.

          With regards cancellation, you have a couple of options:

          • At the FileManager level, you can implement the fileManager(_:shouldCopyItemAt:to:) delegate method and just continuously return false when you want to cancel.

          • With the lower-level copyfile API (learn more about this in its man page), your callback function can return COPYFILE_QUIT.

          Share and Enjoy

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

            • Re: Filemanager file copy progress with cancel ?
              Pendragon Level 1 Level 1 (0 points)

              I forgot this post existed ... How can I blast "shouldCopyItemAt" ? There's no way to send a bool.

                • Re: Filemanager file copy progress with cancel ?
                  eskimo Apple Staff Apple Staff (11,495 points)

                  How can I blast shouldCopyItemAt ?

                  I don’t understand what “blast” means in this context.

                  Share and Enjoy

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

                    • Re: Filemanager file copy progress with cancel ?
                      Pendragon Level 1 Level 1 (0 points)

                      As you said "just continuously return false when you want to cancel."

                        • Re: Filemanager file copy progress with cancel ?
                          eskimo Apple Staff Apple Staff (11,495 points)

                          You are implementing a delegate method, which means you have access to instance properties.  Add an instance property called shouldContinue, set it up to true, and then, when you want to cancel, change it to false.

                          The only gotcha relates to threads.  If you want to use another thread to cancel, you’ll have to protect this property with a lock.

                          Share and Enjoy

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

                            • Re: Filemanager file copy progress with cancel ?
                              Pendragon Level 1 Level 1 (0 points)

                              Still not sure what you mean, the FileManagerDelegate doesn't have this property. If I set up a property without overriding anything what is it's dependency ?

                              • Re: Filemanager file copy progress with cancel ?
                                Pendragon Level 1 Level 1 (0 points)

                                Just have to check ... Are you meaning this will cancel the current copy or the next ?

                                  • Re: Filemanager file copy progress with cancel ?
                                    eskimo Apple Staff Apple Staff (11,495 points)

                                    I’m suggesting something like this:

                                    class Copier: NSObject, FileManagerDelegate {
                                    
                                        init(source: URL, destination: URL) {
                                            self.source = source
                                            self.destination = destination
                                            self.fm = FileManager()
                                            super.init()
                                            self.fm.delegate = self
                                        }
                                    
                                        let source: URL
                                        let destination: URL
                                        private let fm: FileManager
                                        private let shouldContinue = true
                                    
                                        func run() throws {
                                            try fm.copyItem(at: self.source, to: self.destination)
                                        }
                                    
                                        func fileManager(_ fileManager: FileManager, shouldCopyItemAt srcURL: URL, to dstURL: URL) -> Bool {
                                            return self.shouldContinue
                                        }
                                    }

                                    Please note that I haven’t tested this (busy with WWDC stuff this week).

                                    Share and Enjoy

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

                                      • Re: Filemanager file copy progress with cancel ?
                                        Pendragon Level 1 Level 1 (0 points)

                                        Thanks, I would let you know how it gets on but encountered a problem when trying to copy from an External HDD. I tried a local to local file but I don't have a file big enough for it to take enough time, however the problem is it seems to hang / freeze the iMac I thought had crashed it but after waiting long enough carries on, and the file does actually copy.

                                         

                                        I was on an earlier version of both XCode & Swift, I think was 10.1 and 4.2, up until not long ago. I used copy & move and both worked fine before and no idea what the problem could be.

                                         

                                        Any advice ?

                                        ...

                                        I reinstalled XCode but still having same problem, although with Swift 5 temporarily hangs the whole UI (finder etc.) but with 4.2 only the App.

                                        ...

                                        Another update, when copying from Local HDD to External everything works fine.

                                        ...

                                        The method to cancel unfortunately does not work for file in transit because it's only called once at start.

                                        ...

                                        Also don't know if it's related but loading time for AVMetadata is much slower.

                                        ...

                                        Last test, between external volumes also works fine. The hang seems to last as long as it does to copy the file, so it seems as if it's copying it twice.