I'm trying to save a video file from the application's documents folder to the device's Camera Roll. The error occurs when the albumChangeRequest tries to copy the asset to the Camera Roll. It fails to copy the file to the album, and gives back an error message (Domain=NSCocoaErrorDomain Code=-1 "(null)", The operation couldn't be completed). I previously used a deprecated method (writeVideoAtPathToSavedPhotosAlbum) to copy the video, and it also used the same file path, so the problem should not be the file path url.
...
PHPhotoLibrary *photoLibrary = [PHPhotoLibrary sharedPhotoLibrary];
NSURL *filePathURL = [NSURL fileURLWithPath:videoPath isDirectory:NO];
__block NSString* assetURL = nil;
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
PHAssetCollection* album = fetchResult.firstObject;
if (album) {
[photoLibrary performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:filePathURL];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album];
PHObjectPlaceholder *assetChangePlaceHolder = assetChangeRequest.placeholderForCreatedAsset;
assetURL = [assetChangePlaceHolder localIdentifier];
[albumChangeRequest addAssets:@[assetChangePlaceHolder]];
} completionHandler:^(BOOL success, NSError * error) {
if ( success ){
NSString* urlSubStr = [assetURL substringToIndex:36];
// Handle the result asset id in urlSubStr.
} else {
// Copy failed.
}
}];
}
...
Swift 3.0
let photoLibrary = PHPhotoLibrary.shared()
let filePathURL = URL(fileURLWithPath: videoPath, isDirectory: false)
var assetURL: String! = nil
let fetchResult = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.smartAlbum, subtype: PHAssetCollectionSubtype.smartAlbumUserLibrary, options: nil)
if let album = fetchResult.firstObject {
photoLibrary.performChanges({
if let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputFileURL),
let albumChangeRequest = PHAssetCollectionChangeRequest(for: album),
let assetChangePlaceholder = assetChangeRequest.placeholderForCreatedAsset {
assetURL = assetChangePlaceholder.localIdentifier
albumChangeRequest.addAssets(assetChangePlaceholder as! NSFastEnumeration)
}
}, completionHandler: { (succeed, error) in
if succeed {
let index = assetURL.index(assetURL.startIndex, offsetBy: 36)
let urlSubStr = assetURL.substring(to: index)
}
else {
// Copy failed
}
})
}
}