Download file from server using Swift

后端 未结 2 1186
醉梦人生
醉梦人生 2020-12-05 16:15

Hi I have a whole bunch of .mp3 files I want to use with NSFileManager and store in the documents folder. Is there a way I can download the .mp3 files online and then have i

相关标签:
2条回答
  • 2020-12-05 16:45

    edit/update: Xcode 11.5 • Swift 5.2

    import UIKit
    import AVFoundation
    
    class ViewController: UIViewController {
        var player: AVPlayer!
        override func viewDidLoad() {
            super.viewDidLoad()
            let alarm = URL(string: "https://www.ringtonemobi.com/storage/upload/user_id_1/iphone-5-alarm-2016-08-21-01-49-25.mp3")!
            do {
                try alarm.download(to: .documentDirectory) { url, error in
                    guard let url = url else { return }
                    self.player = AVPlayer(url: url)
                    self.player.play()
                }
            } catch {
                print(error)
            }
        }
    }
    

    import Foundation
    extension URL {
        func download(to directory: FileManager.SearchPathDirectory, using fileName: String? = nil, overwrite: Bool = false, completion: @escaping (URL?, Error?) -> Void) throws {
            let directory = try FileManager.default.url(for: directory, in: .userDomainMask, appropriateFor: nil, create: true)
            let destination: URL
            if let fileName = fileName {
                destination = directory
                    .appendingPathComponent(fileName)
                    .appendingPathExtension(self.pathExtension)
            } else {
                destination = directory
                .appendingPathComponent(lastPathComponent)
            }
            if !overwrite, FileManager.default.fileExists(atPath: destination.path) {
                completion(destination, nil)
                return
            }
            URLSession.shared.downloadTask(with: self) { location, _, error in
                guard let location = location else {
                    completion(nil, error)
                    return
                }
                do {
                    if overwrite, FileManager.default.fileExists(atPath: destination.path) {
                        try FileManager.default.removeItem(at: destination)
                    }
                    try FileManager.default.moveItem(at: location, to: destination)
                    completion(destination, nil)
                } catch {
                    print(error)
                }
            }.resume()
        }
    }
    


    Original answer

    Xcode 8.3.2 • Swift 3.1

    if let audioUrl = URL(string: "http://freetone.org/ring/stan/iPhone_5-Alarm.mp3") {
        // create your document folder url
        let documentsUrl = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        // your destination file url
        let destination = documentsUrl.appendingPathComponent(audioUrl.lastPathComponent)
        print(destination)
        // check if it exists before downloading it
        if FileManager.default.fileExists(atPath: destination.path) {
            print("The file already exists at path")
        } else {
            //  if the file doesn't exist
            //  just download the data from your url
            URLSession.shared.downloadTask(with: audioUrl, completionHandler: { (location, response, error) in
                // after downloading your data you need to save it to your destination url
                guard
                    let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                    let mimeType = response?.mimeType, mimeType.hasPrefix("audio"),
                    let location = location, error == nil
                    else { return }
                do {
                    try FileManager.default.moveItem(at: location, to: destination)
                    print("file saved")
                } catch {
                    print(error)
                }
            }).resume()
        }
    }
    
    0 讨论(0)
  • 2020-12-05 16:59

    Xcode 10.1, Swift 4

    I used the example above from @leo-dabus but broke up the code a bit into two functions. One flaw I found in that approach was that it did not handle the case where the file is already downloaded.

    This example will remove any previous file that was already downloaded and write the latest version.

    /// Downloads a file asynchronously
    func loadFileAsync(url: URL, completion: @escaping (Bool) -> Void) {
    
        // create your document folder url
        let documentsUrl = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    
        // your destination file url
        let destination = documentsUrl.appendingPathComponent(url.lastPathComponent)
    
        log.info(m: "downloading file from URL: \(url.absoluteString)")
        if FileManager().fileExists(atPath: destination.path) {
            print("The file already exists at path, deleting and replacing with latest")
    
            if FileManager().isDeletableFile(atPath: destination.path){
                do{
                    try FileManager().removeItem(at: destination)
                    print("previous file deleted")
                    self.saveFile(url: url, destination: destination) { (complete) in
                        if complete{
                            completion(true)
                        }else{
                            completion(false)
                        }
                    }
                }catch{
                    print("current file could not be deleted")
                }
            }
        // download the data from your url
        }else{
            self.saveFile(url: url, destination: destination) { (complete) in
                if complete{
                    completion(true)
                }else{
                    completion(false)
                }
            }
        }
    }
    
    
    func saveFile(url: URL, destination: URL, completion: @escaping (Bool) -> Void){
        URLSession.shared.downloadTask(with: url, completionHandler: { (location, response, error) in
            // after downloading your data you need to save it to your destination url
            guard
                let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200,
                let location = location, error == nil
                else { print("error with the url response"); completion(false); return}
            do {
                try FileManager.default.moveItem(at: location, to: destination)
                print("new file saved")
                completion(true)
            } catch {
                print("file could not be saved: \(error)")
                completion(false)
            }
        }).resume()
    }
    
    0 讨论(0)
提交回复
热议问题