2016-08-03 36 views
2

我正在編寫一個swift上的iOS應用程序,用於從URL下載視頻並將其寫入磁盤。我正在獲取這些數據,但迄今爲止還沒有成功寫入磁盤。下面是代碼: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!',使用''''''''''''''''''模式並打印出結果錯誤'對象。它可能會給你一個更有意義的錯誤信息。 – Rob

+0

當我嘗試時出現類似的錯誤:錯誤域= NSCocoaErrorDomain代碼= -1「(null)」 – user2658229

+0

我是iOS編程新手,所以我仍在學習,因爲我要去。我很抱歉,您所指的是localizedDescription和userInfo是什麼?是的,該應用程序已請求並訪問照片庫。 – user2658229

回答

0

的一個問題是,你要加載的視頻(這是相當大的)到內存在NSData。相反,如果您可以在持久性存儲中傳輸文件和從文件傳輸文件,則會更好。您可以使用NSURLSession下載任務而不是使用已棄用的NSURLConnection方法,即sendSynchronousRequest來完成此操作。

通過使用NSURLSession下載任務,您避免了一次試圖在內存中保存大型視頻,而是直接將視頻流傳輸到持久性存儲。 (注意,不要使用NSURLSession數據的任務,因爲這將有相同的內存佔用問題的方法已過時的NSURLConnectionsendSynchronousRequest

一旦NSURLSession下載任務流的直接下載到永久存儲,然後你可以將文件移動到臨時文件,然後使用addResourceWithType,再次提供文件URL而不是NSData

當我這樣做(和添加一些其他有用的錯誤檢查),它似乎很好地工作:

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

但是,當我做了所有這些,視頻被下載併成功添加到我的照片庫。請注意,我在此刪除了所有同步請求(NSURLSession是異步的,因爲是performChanges),因爲您幾乎不想執行同步請求(並且絕對不會在主隊列中)。