web-dev-qa-db-ja.com

Alamofire 4でファイルをダウンロードし、Documentsディレクトリに保存するにはどうすればよいですか?

Alamofire4Swift3を使用しようとしています。 .mp3ファイルをダウンロードし、Documentsディレクトリに保存する必要があります。現在のコードは次のとおりです。

func downloadAudioFromURL(url: String, completion: ((_ status: ResponseStatus, _ audioLocalURL: URL?) -> Void)?) {


        let fileManager = FileManager.default
        let directoryURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let audioFullURL = String.ensureFullURLPath(url)


        alamoManager.download(audioFullURL)
            .validate { request, response, temporaryURL, destinationURL in

                var pathComponent = response.suggestedFilename!
                if pathComponent == "m4a.mp4" {
                    // Due to the old Android audio files without a filename
                    // Assign a unique name so audio files don't overwrite each other
                    pathComponent = "\(NSUUID().uuidString).mp4"
                }
                let localURL = directoryURL.appendingPathComponent(pathComponent)

                if response.statusCode == 200 {
                    completion?(.success, localURL)
                } else {
                    completion?(.failure, nil)
                }
                return .success
            }

            .responseJSON { response in
                debugPrint(response)
                print(response.temporaryURL)
                print(response.destinationURL)
        }
    }

ただし、保存後にlocalURLから実際にファイルにアクセスすることはできません。また、localURLは、ダウンロードしようとするさまざまなファイルでまったく同じであることに気付きました(上書きされている可能性があります)。例:file:///Users/testuser/Library/Developer/CoreSimulator/Devices/D4254AEA-76DD-4F01-80AF-F1AF3BE8A204/data/Containers/Data/Application/29755154-DD21-4D4C-B340-6628607DC053/Documents/file1.mp3

ここで私が間違っていることはありますか?

コードを次のように編集しました。

func downloadAudioFromURL(url: String, completion: ((_ status: ResponseStatus, _ audioLocalURL: URL?) -> Void)?) {

        let destination: DownloadRequest.DownloadFileDestination = { _, _ in
            var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

            documentsURL.appendPathComponent("Audiofile.mp3")
            return (documentsURL, [.removePreviousFile])
        }

        Alamofire.download(url, to: destination).response { response in

            if let localURL = response.destinationURL {

                completion?(.success, localURL)

            } else {

                completion?(.failure, nil)
            }

        }
}

しかし、m4a.mp4をどのように確認しますか?

11
Kex

なぜあなたは.validate?ダウンロード後、現在のコードにデータを保存していません。 Alamofireでは、ダウンロード後にファイルを直接保存できます

let destination: DownloadRequest.DownloadFileDestination = { _, _ in
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    let fileURL = documentsURL.appendPathComponent("pig.png")

    return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}

Alamofire.download(urlString, to: destination).response { response in
    print(response)

    if response.result.isSuccess, let imagePath = response.destinationURL?.path {
        let image = UIImage(contentsOfFile: imagePath)
    }
}

ところで、downloadメソッドで提供しているダウンロードパスは、ドキュメントディレクトリへのローカルURLであり、サーバーのURLではありません。

14
ezcoding

Swift 3.xおよびAlamofire 4.xバージョン

確かに、Alamofire自身が投稿したAlamofireの例にはバグがあります。 fileURLVoidを返すため、returnステートメントのパラメーターとして使用することはできません。

ダウンロードしたファイルのディレクトリが必要ない場合は、returnステートメントのオプションリストから.createIntermediateDirectoriesも削除します

[〜#〜] edit [〜#〜]
ファイルのタイプを知りたい場合は、最後のコンポーネント部分を取得し、StringNSStringに変換して、NSStringがこれらの機能を持つようにします。

//audioUrl should be of type URL
let audioFileName = String((audioUrl?.lastPathComponent)!) as NSString

//path extension will consist of the type of file it is, m4a or mp4
let pathExtension = audioFileName.pathExtension

let destination: DownloadRequest.DownloadFileDestination = { _, _ in
    var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

    // the name of the file here I kept is yourFileName with appended extension
    documentsURL.appendPathComponent("yourFileName."+pathExtension)
    return (documentsURL, [.removePreviousFile])
}

Alamofire.download("yourAudioUrl", to: destination).response { response in
            if response.destinationURL != nil {
                print(response.destinationURL!)
            }
        }

出力は

file:///Users/rajan/Library/Developer/CoreSimulator/Devices/92B4AB6E-92C0-4864-916F-9CB8F9443014/data/Containers/Data/Application/781AA5AC-9BE7-46BB-8DD9-564BBB343F3B/Documents/yourFileName.mp3

これは、ファイルが保存されている実際のファイルのパスです。

8

目的:サーバーからダウンロードしたgif、pdf、Zipなどのファイルは、指定したフォルダー名内に保存されます。

名前が「ZipFiles」のような独自のフォルダ構造を保存する場合

呼び出します。

self downloadZipFileFromServer(downloadFolderName: "ZipFiles");

ダウンロードしたZipデータは、document/ZiFiles/abc.Zip内に保存されます

これは、ドキュメント内にフォルダを作成するだけです

func createFolder(folderName:String)

Alamofire 4
Swift 4
/******Download image/Zip/pdf  from the server and save in specific Dir********/
func downloadZipFileFromServer(downloadFolderName: string)
{
    let destination: DownloadRequest.DownloadFileDestination = { _, _ in
        var fileURL = self.createFolder(folderName: downloadFolderName)
        let fileName = URL(string : "www.xymob.com/abc.Zip")
        fileURL = fileURL.appendingPathComponent((fileName?.lastPathComponent)!)
        return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
    }
    Alamofire.download("www.xymob.com/abc.Zip", to: destination).response(completionHandler: { (DefaultDownloadResponse) in                
        print("res ",DefaultDownloadResponse.destinationURL!);
    })
}        

func createFolder(folderName:String)->URL
{
    var paths: [Any] = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
    let documentsDirectory: String = paths[0] as? String ?? ""
    let dataPath: String = URL(fileURLWithPath: documentsDirectory).appendingPathComponent(folderName).absoluteString
    if !FileManager.default.fileExists(atPath: dataPath) {
        try? FileManager.default.createDirectory(atPath: dataPath, withIntermediateDirectories: false, attributes: nil)
    }
    let fileURL = URL(string: dataPath)
    return fileURL!
}
1
tikamchandrakar