2016-10-05 21 views
5

Swift3Alamofire4を使用しようとしています。私はダウンロードする必要があります。 mp3ファイルを開き、Documentsディレクトリに保存します。現在のコードはそうのようなものです:Alamofire 4でファイルをダウンロードして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) 
      } 

     } 
} 

がどのように私もm4​​a.mp4をチェックするのでしょうか?

答えて

5

.validateはなぜ実行していますか?現在のコードでダウンロードしたデータは保存していません。 Alamofire allows you to store a file directly after download:

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方法で提供しているダウンロードパスは、DocumentsディレクトリとサーバーのないURLにローカルなURLです。

+1

戻り値行には、「タイプ()の戻り式をタイプURLに変換できません」というエラーがあります。また、ダウンロードする前にパスコンポーネントを設定していますが、実際には推奨されるパスコンポーネントを使用したいと考えています。 – Kex

+0

@Kexこの修正のための私の答えを見てください。タイプ()の戻り式をタイプURLに変換できません。 –

+0

@Kex名前を知らないと、後でそのファイルにどのようにアクセスしますか?ファイルが1つしかない場合でも、自分で名前を入力することを強くお勧めします。私が提供した答えはAlamofireの推薦された方法です。私はそれを使用しようとしたときとは違った使い方をしようとしているのではない。 – ezcoding

3

スウィフト3.xおよびAlamofire 4.xのバージョン

まあ確かにAlamofire自体によって投稿Alamofireの例では、バグがあります。 fileURLVoidを返すので、returnステートメントではパラメータとして使用できません。あなたは、ファイルの任意のディレクトリを使用しない場合は

また、あなたは、ファイルの種類を知りたい場合は、単に最後の要素をつかむあなたは

EDIT
をダウンロードreturn文のオプションリストから.createIntermediateDirectoriesを削除StringNSStringNSStringとしてこれらの官能基を有するものとする。

//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 

です。

+0

m4aまたはmp4のどちらのファイルタイプをチェックしたいですか? 私はあなたがそのURLをヒットしていると信じています。そのURLから、あなたはmp4またはm4aを教えてくれる最後のコンポーネントに簡単にアクセスすることができます –

+0

@Kex audioURLから拡張子を取得し、それに応じてファイルを保存するためのドキュメントパスを作成できます。編集を参照してください。 –

+0

あなたはすでに "documentsURL.appendPathComponent"という行にこのエラーがありますか: "libC++ abi.dylib:タイプrealm :: IncorrectThreadExceptionの不正な例外で終了:不正なスレッドからアクセスされたレルム"? –

関連する問題