Jack
Jack

Reputation: 324

UISaveVideoAtPathToSavedPhotosAlbum not saving video to camera roll

I'm trying to use glimpse to record a UIView. It successfully saves it to the app's documents folder, however I also need it to save to the user's camera roll. It isn't saving to the camera roll, I am presented with an alert to allow the app to access my camera roll but it's not saving in any albums.

I've tried a decent amount of code ranging from this:

[self.glimpse startRecordingView:self.view onCompletion:^(NSURL *fileOuputURL) {
        NSLog(@"DONE WITH OUTPUT: %@", fileOuputURL.absoluteString);


      UISaveVideoAtPathToSavedPhotosAlbum(fileOuputURL.absoluteString,nil,nil,nil);





    }];

To this:

 ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
        [library writeVideoAtPathToSavedPhotosAlbum:fileOuputURL
                                    completionBlock:^(NSURL *assetURL, NSError *error){NSLog(@"hello");}];

The log prints but it doesn't save the video to the camera roll.

If someone has any idea on my this isn't work please let me know! Thanks!

Upvotes: 3

Views: 6785

Answers (3)

Abhishek B
Abhishek B

Reputation: 187

One Issue I faced with UISaveVideoAtPathToSavedPhotosAlbum was the video path extension. For saving video from downloading in app and saving in to Photos if its "quicktime" video then it gives error ALAssetsLibraryErrorDomain / PHPhotosErrorDomain. Below work around worked for me. changing path video extension to ".mp4" solved my problem.

public func download(url: URL, completion: @escaping ((URL?, Error?) -> Void)) {
    let cachesDirectoryUrl = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
    let pathExtension = url.pathExtension == "quicktime" ? "mp4" : url.pathExtension
    var lastPathComponent = url.lastPathComponent.components(separatedBy: ".").first
        lastPathComponent = lastPathComponent?.appending(".\(pathExtension)")
   let destinationUrl = cachesDirectoryUrl.appendingPathComponent(lastPathComponent ?? "")
   
    if url.isFileURL {
        completion(nil, nil)
    } else if FileManager.default.fileExists(atPath: destinationUrl.path) {
        completion(destinationUrl, nil)
    } else {
        URLSession.shared.downloadTask(with: url) { (location, response, error) in
            guard let tempLocation = location, error == nil else {
                completion(nil, error)
                return
            }

            try? FileManager.default.removeItem(at: destinationUrl)
            do {
                try FileManager.default.moveItem(at: tempLocation, to: destinationUrl)
                completion(destinationUrl, nil)
            } catch let error as NSError {
                completion(nil, error)
            }
        }.resume()
    }
}

Upvotes: 0

khusboo suhasini
khusboo suhasini

Reputation: 303

Issue is your video path given as URL,So you have to check wheather your URL Path is compactible to save in video or not, and if you want to save video in camara roll then just pass the URL and follow this code:

-(void)saveVideo:(NSString *)videoData withCallBack:(void(^)(id))callBack{
library = [[ALAssetsLibrary alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSData *yourVideoData=[NSData dataWithContentsOfURL:[NSURL URLWithString:videoData]];
    if (yourVideoData) {
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];

        NSString  *filePath = [NSString stringWithFormat:@"%@/%@", documentsDirectory,@"video.mp4"];


                 if([yourVideoData writeToFile:filePath atomically:YES])
                 {
                     NSURL *capturedVideoURL = [NSURL URLWithString:filePath];
                    //Here you can check video is compactible to store in gallary or not
                     if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:capturedVideoURL]) {
                         // request to save video in photo roll.
                         [library writeVideoAtPathToSavedPhotosAlbum:capturedVideoURL completionBlock:^(NSURL *assetURL, NSError *error) {
                             if (error) {
                                 callBack(@"error while saving video");
                                 NSLog(@"error while saving video");
                             } else{

                                     callBack(@"Video has been saved in to album successfully !!!");

                    }
                         }];
                     }
                }

    }
});


}

Upvotes: 4

Vipin Johney
Vipin Johney

Reputation: 1333

The issue is with video path provided. Provide the relative path from the url.

if UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(fileUrl.relativePath) {
    UISaveVideoAtPathToSavedPhotosAlbum(fileUrl.relativePath, nil, nil, nil)
}

If you had added this UIVideoAtPathIsCompatibleWithSavedPhotosAlbum check the compiler would have shown you the issue with the file.

Upvotes: 22

Related Questions