1

downloadTaskWithURL関数は、存在しないファイルに対してnil以外の場所を返すことがあります。Swift:downloadTaskWithURLは、ファイルが存在しないにもかかわらず非正常な場所で「成功」することがあります。

テスト環境でhttp://192.168.0.102:3000/p/1461224691.mp4にファイルがありません。

予想エラーメッセージにこのURL結果に downloadTaskWithURLを呼び出す

時間のほとんどを、:

Error downloading message during network operation. Download URL: http://192.168.0.102:3000/p/1461224691.mp4 . Location: nil. Error: Optional(Error Domain=NSURLErrorDomain Code=-1100 "The requested URL was not found on this server." UserInfo=0x17547b640 {NSErrorFailingURLKey= http://192.168.0.102:3000/p/1461224691.mp4 , NSLocalizedDescription=The requested URL was not found on this server., NSErrorFailingURLStringKey= http://192.168.0.102:3000/p/1461224691.mp4 })

時折、非決定論的な方法で、downloadTaskWithURLは、ファイルが存在すると考えているとlocation変数に何かを書き込み。その結果、ガード条件は失敗せず、コードは実行し続けます。

fileManager.moveItemAtURL(location!, toURL: fileURL)で作成された永続ファイルは、1バイトのみであり、ネットワークファイルが最初に存在しなかったことを確認します。

なぜdownloadTaskWithURLはこのように動作しますか?

func download() { 
    // Verify <networkURL> 
    guard let downloadURL = NSURL(string: networkURL) where !networkURL.isEmpty else { 
     print("Error downloading message: invalid download URL. URL: \(networkURL)") 
     return 
    } 

    // Generate filename for storing locally 
    let suffix = (networkURL as NSString).pathExtension 
    let localFilename = getUniqueFilename("." + suffix) 

    // Create download request 
    let task = NSURLSession.sharedSession().downloadTaskWithURL(downloadURL) { location, response, error in 
     guard location != nil && error == nil else { 
      print("Error downloading message during network operation. Download URL: \(downloadURL). Location: \(location). Error: \(error)") 
      return 
     } 

     // If here, no errors so save message to permanent location 
     let fileManager = NSFileManager.defaultManager() 
     do { 
      let documents = try fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false) 
      let fileURL = documents.URLByAppendingPathComponent(localFilename) 
      try fileManager.moveItemAtURL(location!, toURL: fileURL) 
      self.doFileDownloaded(fileURL, localFilename: localFilename) 
      print("Downloaded file @ \(localFilename). Download URL: \(downloadURL)") 
     } catch { 
      print("Error downloading message during save operation. Network URL: \(self.networkURL). Filename: \(localFilename). Error: \(error)") 
     } 
    } 

    // Start download 
    print("Starting download @ \(downloadURL)") 
    task.resume() 
} 

答えて

1

サーバは404を返していますが、ダウンロードタスクは基本的に空のファイルを返していますか?そして、サーバーが実際に(サーバーログを確認することによって)エラーコードを返したことは確かですか?

いずれにしても、レスポンスオブジェクトのステータスコードを確認することをお勧めします。それが200でない場合、おそらくダウンロード・タスクはエラー・ページの応答本体をダウンロードしただけです。または、ステータスコードが0の場合、接続はタイムアウトします。いずれにせよ、それを失敗として扱う。

これをすべて1つのスレッドで実行し、非決定性がなくなるかどうかを確認することもできます。

+0

ありがとう、良いアイデア。それらを試して結果を報告します! – Crashalot

関連する問題