Ein Problem ist, dass Sie das Video zu laden versuchen (was ziemlich groß sein kann) in dem Speicher in einer NSData
. Es ist viel besser, wenn Sie stattdessen Dateien im persistenten Speicher zu und von Dateien streamen können. Sie können dies erreichen, indem Sie die Download-Aufgabe NSURLSession
verwenden und nicht die veraltete Methode NSURLConnection
, sendSynchronousRequest
.
Mithilfe von NSURLSession
Download-Aufgabe, vermeiden Sie versuchen, ein großes Video im Speicher auf einmal zu halten, und es wird stattdessen das Video direkt in den persistenten Speicher streamen. (Beachten Sie, verwenden Sie keine NSURLSession
Daten Aufgabe, als dass die gleichen Speicherbedarf Probleme als veraltet Methode sendSynchronousRequest
von NSURLConnection
haben.)
Sobald die NSURLSession
Download-Aufgabe der Download direkt auf den persistenten Speicher gestreamt hat, können Sie dann Verschieben Sie die Datei in die temporäre Datei und verwenden Sie dann addResourceWithType
, wobei Sie wiederum eine Datei-URL anstelle einer NSData
angeben.
Als ich das tat, dass (und das Hinzufügen einiger andere nützliche Fehlerprüfung), schien es gut zu funktionieren:
// make sure it's authorized
PHPhotoLibrary.requestAuthorization { authorizationStatus in
guard authorizationStatus == .Authorized else {
print("cannot proceed without permission")
return
}
self.downloadVideo()
}
Wo:
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()
}
Hinweis, weil NSURLSession
strenger ist darum, sicherzustellen, Wenn Sie keine unsicheren Anforderungen ausführen, aktualisieren Sie möglicherweise die (klicken Sie mit der rechten Maustaste darauf und wählen Sie "Öffnen als" - "Quellcode") und fügen Sie sie der Datei hinzu:
<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>
Aber als ich das alles gemacht habe, wurde das Video heruntergeladen und meiner Fotogalerie erfolgreich hinzugefügt. Und beachte, dass ich hier alle synchronen Anfragen ausgeschnitten habe (NSURLSession
ist asynchron, wie auch performChanges
), da du fast nie synchrone Anfragen ausführen willst (und sicherlich nie in der Hauptwarteschlange).
Anstatt 'try!' Zu verwenden, verwenden Sie 'do' -try'-'catch' und drucken das resultierende' error' Objekt. Es kann Ihnen eine aussagekräftigere Fehlermeldung geben. – Rob
Ich bekomme einen ähnlichen Fehler, wenn ich das versuche: Fehler Domain = NSCoaErrorDomain Code = -1 "(null)" – user2658229
Ich bin neu in iOS-Programmierung, so dass ich noch lerne, wie ich gehe. Es tut mir leid, aber was ist localizedDescription und userInfo, auf die Sie sich beziehen? Und ja, die App hat angefordert und hat Zugriff auf die Fotothek. – user2658229