2016-08-03 16 views
2

私は、URLからビデオをダウンロードしてディスクに書き込むiOSアプリケーションをswiftに書いています。私はデータを取得していますが、ディスクへの書き込みでこれまで失敗しています。以下のコードは次のとおりです。SwiftビデオにNSDataをギャラリーに書き込む

let yourURL = NSURL(string: "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4") 
    //Create a URL request 
    let urlRequest = NSURLRequest(URL: yourURL!) 
    //get the data 
    var theData = NSData(); 
    do{ 
     theData = try NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil) 
    } 
    catch let err as NSError 
    { 

    } 

    try! PHPhotoLibrary.sharedPhotoLibrary().performChangesAndWait({()-> Void in 
     if #available(iOS 9.0, *) { 
      PHAssetCreationRequest.creationRequestForAsset().addResourceWithType(PHAssetResourceType.Video, data: theData, options: nil) 

      print("SUCESS"); 
     } else { 

     }; 

    }); 

私は、感謝任意の洞察力を、次のエラーが発生します:

fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=-1 "(null)": file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.1/src/swift/stdlib/public/core/ErrorType.swift, line 54 
+0

'try!'を使用するのではなく、 'do'-' try' -catch'パターンを使用して、結果の 'error'オブジェクトを出力します。より意味のあるエラーメッセージが表示される場合があります。 – Rob

+0

エラードメイン= NSCocoaErrorDomainコード= -1 "(null)" – user2658229

+0

私はiOSプログラミングを初めて習っているので、私はまだ勉強中です。申し訳ありませんが、あなたが参照しているlocalizedDescriptionとuserInfoは何ですか?そして、はい、アプリは写真ライブラリをリクエストしてアクセスしました。 – user2658229

答えて

0

1つの問題は、あなたがメモリに(非常に大きくなる可能性が)ビデオをロードしようとしているということですNSDataにあります。代わりに、永続ストレージ内のファイルとの間でストリーミングできる場合は、はるかに優れています。これは、非推奨のNSURLConnectionメソッド、sendSynchronousRequestを使用するのではなく、NSURLSessionダウンロードタスクを使用して行うことができます。

NSURLSessionダウンロードタスクを使用すると、一度に大きなビデオをメモリに保持しようとするのではなく、ビデオを永続ストレージに直接ストリームすることになります。 (つまり、非推奨メソッドNSURLConnectionsendSynchronousRequestと同じメモリフットプリントの問題を抱えているように、NSURLSessionデータタスクを使用しないでください。)

NSURLSessionダウンロードタスクが永続ストレージにダウンロード直接ストリーミングされたら、あなたはできますファイルを一時ファイルに移動してからaddResourceWithTypeを使用して、NSDataではなくファイルURLを再度入力します。

私は(といくつかの他の有用なエラーチェックを追加する)、正常に動作するように見えたということでした:

// make sure it's authorized 

PHPhotoLibrary.requestAuthorization { authorizationStatus in 
    guard authorizationStatus == .Authorized else { 
     print("cannot proceed without permission") 
     return 
    } 

    self.downloadVideo() 
} 

func downloadVideo() { 
    let fileManager = NSFileManager.defaultManager() 

    // create request 

    let url = NSURL(string: "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4")! 
    let task = NSURLSession.sharedSession().downloadTaskWithURL(url) { location, response, error in 
     // make sure there weren't any fundamental networking errors 

     guard location != nil && error == nil else { 
      print(error) 
      return 
     } 

     // make sure there weren't and web server errors 

     guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else { 
      print(response) 
      return 
     } 

     // move the file to temporary folder 

     let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory()) 
      .URLByAppendingPathComponent(url.lastPathComponent!) 

     do { 
      try fileManager.moveItemAtURL(location!, toURL: fileURL) 
     } catch { 
      print(error) 
      return 
     } 

     // now save it in our photo library 

     PHPhotoLibrary.sharedPhotoLibrary().performChanges({ 
      PHAssetCreationRequest.creationRequestForAsset().addResourceWithType(.Video, fileURL: fileURL, options: nil) 
     }, completionHandler: { success, error in 
      defer { 
       do { 
        try fileManager.removeItemAtURL(fileURL) 
       } catch let removeError { 
        print(removeError) 
       } 
      } 

      guard success && error == nil else { 
       print(error) 
       return 
      } 

      print("SUCCESS") 
     }) 
    } 
    task.resume() 
} 

注意、NSURLSessionを確認することについて、より厳格であるため、あなたは安全でないリクエストを実行しないで、info.plistを更新することができます(右クリックして "Open As" - "Source Code"を選択してください)。

<dict> 
    <key>NSExceptionDomains</key> 
    <dict> 
     <key>sample-videos.com</key> 
     <dict> 
      <!--Include to allow subdomains--> 
      <key>NSIncludesSubdomains</key> 
      <true/> 
      <!--Include to allow HTTP requests--> 
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> 
      <true/> 
      <!--Include to specify minimum TLS version--> 
      <key>NSTemporaryExceptionMinimumTLSVersion</key> 
      <string>TLSv1.1</string> 
     </dict> 
    </dict> 
</dict> 

しかし、私がそのすべてをやったとき、ビデオはダウンロードされ、自分の写真ライブラリに正常に追加されました。また、同期リクエスト(ほとんどメイン・キューにはない)を実行したくないので、ここですべての同期リクエスト(NSURLSessionperformChangesのように非同期です)を削除しました。

関連する問題