Jean Pierre
Jean Pierre

Reputation: 211

Post Video to Facebook with swift SDK

I have been trying to figure this out all day and yesterday night, but no luck. I can confirm that the LinkShareContent works but when I try to share a video file. It gives me an error code "reserved" but nothing else.

This is the code for the link

var content = LinkShareContent(url: URL(string: "https://google.com")!)
showShareDialog(content)

and this is the code for the video that does not work at all.

 let video = Video(url: url)
 var content = VideoShareContent(video: video, previewPhoto: Photo(image: inProgressItem.firstImage, userGenerated: true))
 showShareDialog(content)

This will show the share Sheet on the controller

  Func showShareDialog<C: ContentProtocol>(_ content: C, mode: ShareDialogMode = .shareSheet) {
        let dialog = ShareDialog(content: content)
        dialog.presentingViewController = self
        dialog.mode = mode

        do{
            try dialog.show()
        }
        catch (let error){
            print(error)
        }
    }

I have confirmed that the video is on the local path and I'm testing the app on iPhone 8 11.1.2

Upvotes: 7

Views: 1694

Answers (2)

Taras
Taras

Reputation: 1909

I use PHPickerViewController instead of UIPickerController.

private lazy var videoPickerController: PHPickerViewController = {
        let photoLibrary = PHPhotoLibrary.shared()
        var configuration = PHPickerConfiguration(photoLibrary: photoLibrary)
        configuration.selectionLimit = 1
        configuration.filter = .any(of: [.videos])
        let picker = PHPickerViewController(configuration: configuration)
        picker.delegate = self
        return picker
    }()

Then using PHAsset for initialisation ShareVideo(videoAsset:).

private func facebookShare(content: Content) {
        guard let schemaUrl = URL(string: "fb://") else {
            return
        }
        if UIApplication.shared.canOpenURL(schemaUrl) {
            let video = ShareVideo(videoAsset: content)
            let content = ShareVideoContent()
            content.video = video
            let dialog = ShareDialog(
                viewController: self,
                content: content,
                delegate: self
            )
            
            do {
                try dialog.validate()
            } catch let error as NSError {
                presentAlert(message: (error.userInfo[ErrorDeveloperMessageKey] as? String) ?? error.localizedDescription)
            } catch {
                presentAlert(message: error.localizedDescription)
            }
            if dialog.canShow {
                dialog.show()
            }
        } else {
            presentAlert(message: "FB app not installed")
        }
    }

And PHPickerViewControllerDelegate looks something like this (I always select only 1 asset that's why I use fetchResult.firstObject)

 func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true)
        
        let identifiers = results.compactMap(\.assetIdentifier)
        let fetchResult = PHAsset.fetchAssets(withLocalIdentifiers: identifiers, options: nil)
        guard let videoAsset = fetchResult.firstObject else { return }
}

This solution works for iOS 14 and higher and if on your device Facebook app installed. Also before upload video I login via FB.

Upvotes: 0

Tung Fam
Tung Fam

Reputation: 8167

Had exactly the same issue. It was working for LinkShareContent but didn't work for VideoShareContent.

The solution: Make sure you are getting the right URL for the video. The right one is the URL for key "UIImagePickerControllerReferenceURL" from info dictionary that comes from UIImagePickerController delegate method.

Working Code:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String: Any]) {
    picker.dismiss(animated: true)
    if let videoURL = info["UIImagePickerControllerReferenceURL"] as? URL {
        let video = Video(url: videoURL)
        let content = VideoShareContent(video: video)
        let dialog = ShareDialog(content: content)
        dialog.failsOnInvalidData = true
        dialog.mode = .native
        dialog.presentingViewController = self
        do {
            try dialog.show()
        } catch {
           print(error)
        }
    }
}

Extra info: initially I did not use this key "UIImagePickerControllerReferenceURL" cuz it's deprecated. Apple advises using UIImagePickerControllerPHAsset instead. But the URL from there also returns reserved error. Another try was to use key "UIImagePickerControllerMediaURL", but it also didn't succeed.

Upvotes: 3

Related Questions