2016-08-03 2 views
2

나는 스위프트에 iOS 어플리케이션을 작성하여 URL에서 비디오를 다운로드하고 디스크에 씁니다. 데이터를 가져 오는 중이지만 지금까지 디스크에 쓰는 데 실패했습니다. 아래는 코드입니다 : 나는 다음과 같은 오류를 수신하고스위프트 스위프트 비디오에 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

하나의 문제는 당신이 메모리에 비디오를 (매우 클 수 있음)로드하려고하는 것입니다 NSData입니다. 대신에 영구 저장 장치에서 파일을주고받을 수 있다면 훨씬 좋습니다. 더 이상 사용되지 않는 NSURLConnection 메서드 인 sendSynchronousRequest을 사용하는 대신 NSURLSession 다운로드 작업을 사용하여이 작업을 수행 할 수 있습니다.

NSURLSession 다운로드 작업을 사용하면 한 번에 큰 비디오를 메모리에 보관하는 것을 피할 수 있으며 대신 비디오를 영구 저장소로 직접 스트리밍합니다. (즉, 사용되지 않는 방법 NSURLConnectionsendSynchronousRequest와 같은 메모리 풋 프린트 문제가되므로, NSURLSession 데이터 작업을 사용하지 마십시오.)

NSURLSession 다운로드 작업이 영구 저장 장치에 다운로드 직접 스트리밍되면, 당신은 다음 수 파일을 임시 파일로 이동 한 다음 NSData이 아닌 파일 URL을 다시 제공하여 addResourceWithType을 사용하십시오.

나는 잘 작동하는 듯 (그리고 확인 다른 유용한 오류 추가)했을 때 : NSURLSession 확실히 만드는 방법에 대한 더 엄격한 때문에

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() 
} 

참고 :

// make sure it's authorized 

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

    self.downloadVideo() 
} 

당신은 안전하지 않은 요청을 수행하지 않으므로 info.plist (오른쪽 클릭하고 "다른 이름으로 열기"- "소스 코드"를 선택하십시오)를 업데이트하여 파일에 추가하십시오 :

<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))을 제거했습니다.