facebook - iOS - 通过分享对话框在 Facebook 上分享视频
问题描述
我的应用程序可以选择使用图形 API 将在线视频分享到 Facebook,并且一直运行到 2018 年 8 月。我刚刚发现 publish_action 已被弃用,我们无法使用图形 API 在 Facebook 上共享视频。所以我尝试了另一种解决方案:将视频下载到本地,将其复制到资产中,然后使用旧的 FBSDKShareDialog 进行分享(在 iOS bellow 11 上设置 url 并在 iOS >= 11 上设置资产),但 Facebook 上的帖子出现了没有视频,只有文字。然后我使用新的 ShareDialog 类尝试了它,因为它仅适用于视频 URL,在我将其复制到资产后,我无法获取其资产 URL,但它的文件 URL,因此我在日志中收到以下错误:
"Error while sharing video content Error Domain=com.facebook.sdk.share Code=2 "(null)" UserInfo={com.facebook.sdk:FBSDKErrorArgumentValueKey=file:///var/mobile/Media/DCIM/105APPLE/IMG_5953.MP4, com.facebook.sdk:FBSDKErrorDeveloperMessageKey=Must refer to an asset file., com.facebook.sdk:FBSDKErrorArgumentNameKey=videoURL}".
这是我的代码。请告诉我为了在 Facebook 上分享视频我应该改变什么。如果我分享 URL,那么它只显示帖子中的 URL,我无法显示下面的视频。提前致谢!
private func downloadVideoForUploadOnFacebook(urlString: String, videoId: Int, isMyVideo: Bool, successHandler: @escaping () -> Void, failureHandler: @escaping (String) -> Void) {
guard let url = URL(string: urlString) else {delegate.stopActivityIndicator(); return}
let request = Alamofire.request(URLRequest(url: url))
request.responseData {[weak self] (response) in
if let data = response.result.value {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let videoURL = documentsURL.appendingPathComponent("video.mp4")
do {
try data.write(to: videoURL)
self?.showShareDialog(localVideoUrl: videoURL, completion: {
print("success")
successHandler()
}, failure: { (error) in
print(error)
failureHandler(error)
})
} catch {
print("Something went wrong!")
}
}
}.downloadProgress { (progress) in
print(progress)
}
}
private func showShareDialog(localVideoUrl: URL, completion: @escaping () -> Void, failure: @escaping (String) -> Void) {
guard let navigationController = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController, let vc = navigationController.viewControllers.last else {return}
if PHPhotoLibrary.authorizationStatus() == .authorized {
showFacebookShareDialog(localVideoUrl: localVideoUrl, vc: vc, completion: completion, failure: failure)
} else {
PHPhotoLibrary.requestAuthorization({[weak self] (status) in
switch status {
case .authorized:
self?.showFacebookShareDialog(localVideoUrl: localVideoUrl, vc: vc, completion: completion, failure: failure)
default:
print(status)
failure("Authorization error")
}
})
}
}
private func showFacebookShareDialog(localVideoUrl: URL, vc: UIViewController, completion: @escaping () -> Void, failure: @escaping (String) -> Void) {
var placeHolder : PHObjectPlaceholder?
do {
try PHPhotoLibrary.shared().performChangesAndWait {
let creationRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: localVideoUrl )
placeHolder = creationRequest?.placeholderForCreatedAsset
}
}
catch {
print(error)
failure(error.localizedDescription)
}
let result = PHAsset.fetchAssets(withLocalIdentifiers: [placeHolder!.localIdentifier], options: nil)
if let phAsset = result.firstObject {
getURL(ofPhotoWith: phAsset, completionHandler: {[weak self] (url) in
guard let url = url else {return}
self?.showNewDialog(localVideoUrl: url, vc: vc, completion: completion, failure: failure)
// if #available(iOS 11.0, *) {
// self?.showOldDialog(asset: phAsset, vc: vc)
// } else {
// self?.showOldDialog(localVideoUrl: url, vc: vc)
// }
})
} else {
failure("Error at assets")
}
}
func showOldDialog(localVideoUrl: URL, vc: UIViewController) {
let video = FBSDKShareVideo()
video.videoURL = localVideoUrl
let content = FBSDKShareVideoContent()
content.video = video
let shareDialog: FBSDKShareDialog = FBSDKShareDialog()
shareDialog.shareContent = content
shareDialog.fromViewController = vc
DispatchQueue.main.async {
shareDialog.show()
}
}
func showOldDialog(asset: PHAsset, vc: UIViewController) {
let video = FBSDKShareVideo()
video.videoAsset = asset
let content = FBSDKShareVideoContent()
content.video = video
let shareDialog: FBSDKShareDialog = FBSDKShareDialog()
shareDialog.shareContent = content
shareDialog.fromViewController = vc
DispatchQueue.main.async {
shareDialog.show()
}
}
func showNewDialog(localVideoUrl: URL, vc: UIViewController, completion: @escaping () -> Void, failure: @escaping (String) -> Void) {
let video = FacebookShare.Video(url: localVideoUrl)
let content = VideoShareContent(video: video)
let shareDialog = ShareDialog(content: content)
shareDialog.mode = .native
shareDialog.failsOnInvalidData = true
shareDialog.presentingViewController = vc
shareDialog.completion = { result in
switch result {
case .success:
print("Share succeeded")
completion()
case .failed:
print(result)
failure("Error while sharing on facebook")
case .cancelled:
print("Share cancelled")
}
}
DispatchQueue.main.async {
do {
try shareDialog.show()
} catch {
print(error)
failure("Error while sharing video content \(error)")
}
}
}
解决方案
推荐阅读
- c++ - 使用 recvfrom 获取数据
- php - Codility 青蛙跳跃
- jquery - Bootstrap 的工具提示需要 Popper.js
- debugging - 错误:预期标识符或 '(' for (int i = 0; i < n; i++)
- c++ - “时间”库形式 Arduino 显示不正确的值
- react-native - CocoaPods 在 react-native-template-typescript 上失败:url_for_request:未初始化的常量 GhInspector::Sidekick::ERB (NameError)
- swift - UIImage.pngData() - 结构体还是闭包?
- dolphindb - DolphinDB 数据库笔记本中消失的变量
- c# - 任何 JSON 字符串转换为 C# 对象而不定义 pojo
- python - 我在最近一次通话中遇到了一些错误