iosswiftdownload-manager

Strange error after file downloading swift


I'm trying to download file from remote server. File is available and downloading also completes. File name I send to this function from collectionview with files, so name is correct. But I have some problems with file saving. Here is my way of file loading:

func testLoad(attachName:String) {
        let documentsUrl:URL =  (FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first as URL?)!
        let destinationFileUrl = documentsUrl.appendingPathComponent(attachName)
        
        
        var request = URLRequest(url: Pathes.init(endpoint: "message/\(mModel?.id ?? -1)/attachment/\(attachName)?type=\(mType ?? -1)").resourseUrl)
        
        request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
        request.setValue("Bearer " + UserDefaults.standard.string(forKey: "access_token")!, forHTTPHeaderField: "Authorization")
        
        let task = URLSession(configuration: URLSessionConfiguration.default).downloadTask(with: request) { (tempLocalUrl, response, error) in
            if let tempLocalUrl = tempLocalUrl, error == nil {
                
                print("\(tempLocalUrl) ---> \(destinationFileUrl)")
                
                if ((response as? HTTPURLResponse)?.statusCode) != nil {
                    do {
                        try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
                    } catch (let writeError) {
                        print("Error creating a file \(destinationFileUrl) : \(writeError)")
                    }
                }
                
            } else {
                print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
            }
        }
        task.resume()
        
    }

And below you can see my error:

Error creating a file file:///Users/angor/Library/Developer/CoreSimulator/Devices/B83E640A-8EC4-475A-B272-5D884B611A8B/data/Containers/Data/Application/3DE475CE-B2B3-4971-9382-1F272160B1A4/Downloads/paolo-nicolello-dqy5wtCdS4U-unsplash.jpg : Error Domain=NSCocoaErrorDomain Code=516 "“CFNetworkDownload_mw7QwY.tmp” couldn’t be copied to “Downloads” because an item with the same name already exists." UserInfo={NSSourceFilePathErrorKey=/Users/angor/Library/Developer/CoreSimulator/Devices/B83E640A-8EC4-475A-B272-5D884B611A8B/data/Containers/Data/Application/3DE475CE-B2B3-4971-9382-1F272160B1A4/tmp/CFNetworkDownload_mw7QwY.tmp, NSUserStringVariant=(
    Copy
), NSDestinationFilePath=/Users/angor/Library/Developer/CoreSimulator/Devices/B83E640A-8EC4-475A-B272-5D884B611A8B/data/Containers/Data/Application/3DE475CE-B2B3-4971-9382-1F272160B1A4/Downloads/paolo-nicolello-dqy5wtCdS4U-unsplash.jpg, NSFilePath=/Users/angor/Library/Developer/CoreSimulator/Devices/B83E640A-8EC4-475A-B272-5D884B611A8B/data/Containers/Data/Application/3DE475CE-B2B3-4971-9382-1F272160B1A4/tmp/CFNetworkDownload_mw7QwY.tmp, NSUnderlyingError=0x60000232c150 {Error Domain=NSPOSIXErrorDomain Code=17 "File exists"}}

I can't understand why it happens. The error says that my file exists but I don't see any new files in my Downloads directory. I think that that the problem is connected with temporary file which has to be copied to Downloads. I found this way of file downloading here maybe I did smth wrong?


Solution

  • I've managed to figure out where the problem is :) I added removing temporary created file from tmp folder and also moved all file downloading code to extension:

    extension UIViewController:URLSessionDownloadDelegate{
        public func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
            guard let url = downloadTask.originalRequest?.url else { return }
            let documentsPath = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask)[0]
            let destinationURL = documentsPath.appendingPathComponent(url.lastPathComponent)
           
            try? FileManager.default.removeItem(at: destinationURL)
            
            do {
                try FileManager.default.copyItem(at: location, to: destinationURL)
                
            } catch let error {
                print("Copy Error: \(error.localizedDescription)")
            }
        }
    }
    

    Maybe it will help someone else except me :)