2017-04-19 13 views
0

파일의 ID를 전송하여 서버에서 파일을 다운로드하려고합니다. 몇 가지 시도했지만 파일이 CFNetworkDownload.tmp 파일로 다운로드되고 있습니다.요청 파일 다운로드가 작동하지 않는 Swift downloadTask

존재하는 파일로 저장하고 싶습니다. 파일 형식은 PNG, JPEG, PDF, DOCX, PPTX, XLSX가 될 수 있습니다. 많은 것을 시도했지만 헛된. 나는 그것이 내가 여기에서 이해하기 위해 놓치고있는 간단한 무엇이어야 할 것임에 틀림 없다라고 확신한다

시도해 보았다. 차이점은 대부분의 예에서 파일 이름은 URL에 있습니다. 하지만 ID를 보내고 응답으로 파일을 가져옵니다.

How To Download Multiple Files Sequentially using NSURLSession downloadTask in Swift

How to download file in swift?

다음은 내 코드입니다.

func downloadFile(id : String, fileName : String) -> Void { 


    let session = URLSession.shared 
    let url = URL(string: qaDownloadURL+id)! 

    var request = URLRequest(url: url) 
    request.httpMethod = "POST" 

    let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in 
     if let tempLocalUrl = tempLocalUrl, error == nil { 
      // Success 
      if let statusCode = (response as? HTTPURLResponse)?.statusCode { 
       print("Success: \(statusCode)") 
      } 

      do { 



//     let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first 
//      
//     self.savePath = documentsUrl!.absoluteString + "/" + fileName 
//      
//     let fileURL = URL(fileURLWithPath: self.savePath) 
//      
//     let dataFromURL = NSData(contentsOf: tempLocalUrl) 
//     dataFromURL?.write(to: fileURL, atomically: true) 

       var documentsDirectory: String? 

       let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 

       if paths.count > 0 
       { 
        documentsDirectory = paths.first! 
       } 

       self.savePath = documentsDirectory!// + "/" + fileName 

       let fileURL = URL(fileURLWithPath: self.savePath) 


       let dataFromURL = NSData(contentsOf: tempLocalUrl) 
       dataFromURL?.write(to: fileURL, atomically: true) 


       // try FileManager.default.copyItem(at: tempLocalUrl, to: fileURL) 


       DispatchQueue.main.async { 

        let documentController = UIDocumentInteractionController.init(url: fileURL) 
        documentController.delegate = self 
        documentController.presentPreview(animated: true) 

       } 

      } catch (let writeError) { 
       print("error writing file \(self.savePath) : \(writeError)") 
      } 

     } else { 
      print("Failure: %@", error?.localizedDescription); 
     } 
    } 
    task.resume() 

} 
+0

예 저는 그걸 또한 시도했습니다. 작동하지 않습니다 : ( –

+0

문제는 "가져 오기"대신 "POST"방법을 사용하고 있습니다 .BTW는 URL 만 사용해야합니다. POST가 아닌 무언가를 얻고 싶을 때 URLRequest를 사용할 필요가 없습니다. –

+0

BTW this 도움이됩니다 http://stackoverflow.com/a/27643660/2303865 –

답변

1

, 파일 이름을 포함한 전체 경로를 지정해야합니다. 당신이

do { 
      let documentFolderURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 
      let fileURL = documentFolderURL.appendingPathComponent(fileName) 
      try FileManager.default.copyItem(at: tempLocalUrl, to: fileURL) 

      DispatchQueue.main.async { 

       let documentController = UIDocumentInteractionController.init(url: fileURL) 
       documentController.delegate = self 
       documentController.presentPreview(animated: true) 

      }  
     } 

으로 전체 do 블록을 교체하거나 임시 위치에 파일을 다운로드하는 것보다 원시 데이터를 오히려 반환 URLSessionDataTask를 사용하는 예를

에 대한 직접 Data을 절약 할 수 현대 URL 관련 API를 사용하여

let task = session.dataTask(with: request) { (data, response, error) in 
    guard error == nil else { 
     print(error!) 
     return 
    } 
    // Success 
    if let statusCode = (response as? HTTPURLResponse)?.statusCode { 
     print("Success: \(statusCode)") 
    } 

    do { 
     let documentFolderURL = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) 
     let fileURL = documentFolderURL.appendingPathComponent(fileName) 
     try data!.write(to: fileURL) 

     DispatchQueue.main.async { 

      let documentController = UIDocumentInteractionController.init(url: fileURL) 
      documentController.delegate = self 
      documentController.presentPreview(animated: true) 

     } 

    } catch { 
     print("error writing file \(fileName) : \(error)") 
    } 
} 
task.resume() 

그래도 작동하지 않으면 오류가 다른 곳에서 발생합니다.

+0

하지만 왜 tempLocalUrl에서 .tmp 파일을 다운로드합니까? 어떤 생각? –

+0

URLSessionDataTask 시도하고 저장했습니다. 데이터가 작동합니다. 그 대답을 받아 들일 수 있도록 조금 더 설명해 주시겠습니까 –

+0

@SharanyaKM 문제는 "가져 오기"대신 "POST"방법을 사용하는 것입니다 .BTW는 URL을 사용해야합니다. 사용할 필요가 없습니다. URLRequest (POST가 아님)를 얻으 려 할 때 –

0

이 같이 할 수있다 :이 도움이

/************************************************************************** 
    TAP FOR DOWNLOAD : DOWNLOAD REMOTE DATA AND SAVE TO DOC DIRECTORY 
    ***************************************************************************/ 
    cell.loadingIcon.startAnimating() 
    let indexPath = self.songTableView.indexPath(for: cell) 
    let song = filteredList?.object(at: (indexPath?.row)!) as! CKSong 

    let songURL = NSURL(string : song.url as! String) 

    let downloadTask : URLSessionDownloadTask = self.downloadsSession.downloadTask(with: songURL as! URL) { (location, response, error) in 

     if (error == nil) { 

      let time = NSNumber(value:(NSDate().timeIntervalSince1970 * 1000)) 
      let fileName = NSString(format:"%@_music.mp3",time) 
      let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL! 
      let destinationFileUrl = documentsUrl.appendingPathComponent(fileName as String) 

      do { 
       try FileManager.default.copyItem(at: location!, to: destinationFileUrl) 
      } catch (let writeError) { 
       print("Error creating a file \(destinationFileUrl) : \(writeError)") 
      } 

      print("DOWNLOAD FINISHED \(location)") 
      print("DOWNLOAD FINISHED \(destinationFileUrl)") 

      song.localURL = destinationFileUrl.path as NSString? 
     } 
     DispatchQueue.main.async { 
      cell.playButton.isEnabled = (song.localURL != nil) 
      cell.loadingIcon.stopAnimating() 
     } 
    } 

    downloadTask.resume() 
} 

//==================================================================================================================================== 
// SONG DOWNLOAD TASK : NSURLSESSION 
//==================================================================================================================================== 

lazy var downloadsSession: URLSession = { 
    let configuration = URLSessionConfiguration.default 
    let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil) 
    return session 
}() 

희망을.

참조 : 당신은 디렉토리를 나타내는 위치에 데이터를 기록 할 수 없습니다https://github.com/Abhishek9634/CokeStudio/blob/CHANGE_BRANCH/CokeStudio/CokeStudio/CKSongsListVC.swift#L164

+0

아니 ...이 나던 작품 ... –