1つの問題は、あなたがメモリに(非常に大きくなる可能性が)ビデオをロードしようとしているということですNSData
にあります。代わりに、永続ストレージ内のファイルとの間でストリーミングできる場合は、はるかに優れています。これは、非推奨のNSURLConnection
メソッド、sendSynchronousRequest
を使用するのではなく、NSURLSession
ダウンロードタスクを使用して行うことができます。
NSURLSession
ダウンロードタスクを使用すると、一度に大きなビデオをメモリに保持しようとするのではなく、ビデオを永続ストレージに直接ストリームすることになります。 (つまり、非推奨メソッドNSURLConnection
のsendSynchronousRequest
と同じメモリフットプリントの問題を抱えているように、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>
しかし、私がそのすべてをやったとき、ビデオはダウンロードされ、自分の写真ライブラリに正常に追加されました。また、同期リクエスト(ほとんどメイン・キューにはない)を実行したくないので、ここですべての同期リクエスト(NSURLSession
はperformChanges
のように非同期です)を削除しました。
出典
2016-08-03 04:33:04
Rob
'try!'を使用するのではなく、 'do'-' try' -catch'パターンを使用して、結果の 'error'オブジェクトを出力します。より意味のあるエラーメッセージが表示される場合があります。 – Rob
エラードメイン= NSCocoaErrorDomainコード= -1 "(null)" – user2658229
私はiOSプログラミングを初めて習っているので、私はまだ勉強中です。申し訳ありませんが、あなたが参照しているlocalizedDescriptionとuserInfoは何ですか?そして、はい、アプリは写真ライブラリをリクエストしてアクセスしました。 – user2658229