FBSDKShareDialog not appearing in case of video share - ios

I am working on a project where I need to share an image and a video together on Facebook, but facing undefined behaviour.
Issue: When I am trying to share a video using FBSDKShareMediaContent class (using below code), the FBSDKShareDialog is not appearing, but it appears when I share only an image.
My code:
let photo: FBSDKSharePhoto = FBSDKSharePhoto.init(image: imageToShare, userGenerated: true)
let vid: FBSDKShareVideo = FBSDKShareVideo.init(videoURL: URL(string:vidUrl!.path))
// FBSDKShareDialog not appearing in this case
let shareContent: FBSDKShareMediaContent = FBSDKShareMediaContent()
shareContent.media = [photo, vid]
/*
// FBSDKShareDialog appearing
let shareContent: FBSDKShareMediaContent = FBSDKShareMediaContent()
shareContent.media = [photo] */
FBSDKShareDialog.show(from: self.getCurrentViewController(), with: shareContent, delegate: nil)
Video URL: file:///var/mobile/Containers/Data/Application/2E0E48B7-30E5-4567-8C0B-ACAC100AE389/Documents/AppName/1499773278.555753.mp4
Please help.

The solution i found is, the url path i was assigning is wrong as per the Facebook guidelines of sharing video.
The video URL videoURL must be an asset URL. You can get a video asset URL e.g. from UIImagePickerController.
See video sharing section inside the link.
UPDATE:
Final Solution to share image, video together using picker or document directory path whichever, this works.
let shareText = "Upload video, image and text."
let vc = UIActivityViewController(activityItems: [shareText, vidUrl, imageToShare], applicationActivities: [])
present(vc, animated: true)

Related

Why Share Extension is not working on iOS 13?

I was using a Share extension in my app in order to import audio files and it was working on iOS12. Now in iOS 13 is not working anymore, when I press the share button my app doesn't appear in the share sheet.
I think that maybe something has changed in the plist or similar but I coudn't find any information.
Does anyone have the same problem?
NB: I don't wanna use the copy - paste strategies, only the share extension.
Try this for iOS 13
DispatchQueue.main.async {
let activityItem = URL.init(fileURLWithPath: Bundle.main.path(forResource: "audio", ofType: "mp3")!)
let activityVC = UIActivityViewController(activityItems: [activityItem],applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = self.view
self.present(activityVC, animated: true, completion: nil)
}
For IOS 13 you Should add below code inside your open url method.
UISceneOpenExternalURLOptions * options = [[UISceneOpenExternalURLOptions alloc] init];
options.universalLinksOnly = false;

Share image and text to whatsapp in single share in swift 4

Could anyone suggest me how to share image with text to whatsaap or any alternative for the same.I have tried it using UIActivityViewController but its possible to share image+text simultaneously on mail bt not on whatsaap .
Help will be appreciated.
Thank you :)
code is as follows:
let textToShare = "Hello world"
let myWebsite = NSURL(string:"https://www.apple.com/")
let img = UIImage(named:"BookImg")
let shareall = [img!,textToShare,myWebsite!] as [Any]
let vc = UIActivityViewController(activityItems: shareall, applicationActivities: nil)
vc.popoverPresentationController?.sourceView = self.view
self.present(vc, animated: true, completion: nil)
Sorry, but you can't post Images and Text together on WhatsApp. However, you can post one at a time. As Whatsapp does not provide any API you can add captions and post images with text.
For your reference , WhatsApp:
http://www.whatsapp.com/faq/en/iphone/23559013
An easy alternative is handing the image part from your server side. Host it and share the link along with the caption. the image will be shown automatically through the URL you are sharing.
It will appear like below,
SS: https://ibb.co/7tpqm8S

XCODE / IOS - Share audio file to whatsapp with a direct opening

I am trying to share an audio file from my ios app to whatsapp, but with a direct opening of whatsapp, and not an opening of the sharing menu with all the tiles.
Here is what i have now:
// Getting the original file
let fileName = #MY FILE NAME#
let filePath = Bundle.main.path(forResource: fileName, ofType: "mp3")!
let urlData = URL.init(fileURLWithPath: filePath)
let nsData = NSData(contentsOf: urlData)
if (nsData != nil){
// Creating the temporary file to share in the accessible ressources
let newFileName = "file.mp3"
let newFilePath = "\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/\(newFileName)"
nsData?.write(toFile: newFilePath, atomically: true)
let newUrlData = URL.init(fileURLWithPath: newFilePath)
// Sharing the file to whatsapp
// Possibility 1 (does not work yet)
// let documentController = UIDocumentInteractionController(url: newUrlData)
// documentController.uti = "net.whatsapp.audio"
// documentController.presentOpenInMenu(from: CGRect.zero, in: self.view, animated: true)
// Possibility 2 (works only with the sharing menu)
let activityVC = UIActivityViewController(activityItems: [NSURL(fileURLWithPath: newFilePath)], applicationActivities: nil)
self.present(activityVC, animated: true, completion: nil)
}
As I do this, sharing an audio file to whatsapp works, but it first open the sharing menu, with the messenger tile, message tile, notes tile, ... (and it doesn't works for the messenger app). In the end I would like to be able to share on messenger AND whatsapp.
As explicated here in the whatsapp documentation, I want to open directly the whatsapp application when I try to share the file:
Alternatively, if you want to show only WhatsApp in the application list (instead of WhatsApp plus any other public/*-conforming apps) you can specify a file of one of aforementioned types saved with the extension that is exclusive to WhatsApp:
images - «.wai» which is of type net.whatsapp.image
videos - «.wam» which is of type net.whatsapp.movie
audio files - «.waa» which is of type net.whatsapp.audio
When triggered, WhatsApp will immediately present the user with the contact/group picker screen. The media will be automatically sent to a selected contact/group.
So I tried to change the line :
let newFileName = "file.mp3"
To one of these :
let newFileName = "file.mp3.waa"
let newFileName = "file.waa"
let newFileName = "file.waa.mp3"
But it still shows the same sharing menu (and can't read the audiofile if it ends with the .waa extension).
-> 1) Is it possible to do what I want to do ?
-> 2) If not, is there a way to share to messenger & whatsapp with the same code keeping one sharing menu
-> 3) If not, is there a way to reduce the sharing menu to only one tile depending on different calling event, so there is no confusing choosing of tiles
Thanks,
Antoine
Cf: XCODE / IOS - How to use exclusive extension to immediately present whatsapp (.wai, .waa, .wam)
FYI: As I went through a lot of tests with this, I couldn't find any solution yet.
Whatsapp recognize the file extension, but cannot even read it. Once shared, when you click on it, it's written ".whatsapp audio file", nothing more (And it's not even shared directly).
I sent a email to whatsapp developper team, they said they have others problem to fix currently, so it's not even on their to do list.
Wait & see..

Sharing Video PHAsset via UIActivityController

I am trying to share video PHAsset via UIActivityController using requestAVAsset. This works with Messaging, but not with AirDrop, indicating as 'Failed'.
PHCachingImageManager.default().requestAVAsset(forVideo: asset, options: nil, resultHandler:
{ (givenAsset, audioMix, info) in
let videoAsset = givenAsset as! AVURLAsset
let videoURL = videoAsset.url
DispatchQueue.main.async {
let activityViewController = UIActivityViewController(
activityItems: [videoURL],
applicationActivities: nil)
activityViewController.excludedActivityTypes = [UIActivityType.saveToCameraRoll]
if let popoverPresentationController = activityViewController.popoverPresentationController {
popoverPresentationController.barButtonItem = (sender)
}
self.present(activityViewController, animated: true, completion: nil)
}
})
This seems to properly put up UIActivityController and only work with certain activities:
Messaging - ✔️Works, properly exports video.
AirDrop - ✖️Shows "Failed"
Dropbox - ✖️Puts up the proper Dropbox View, yet says "Unknown error occurred"
I've run into similarly odd behavior when working with PHAssets. My guess is this is a (purposely) undocumented security/sandboxing restriction.
I was able to work around this problem by copying the underlying file to a user directory, and then performing the operation on the copied file.
I did this in a loop. Occasionally, the copy fails with a vague file permissions error. When it does, I retry it after a few seconds (using DispatchQueue.main.asyncAfter). Eventually, it works!

How to convert a video NSURL to an ALAsset?

Facebook sharing requires an ALAsset such as the following:
let content = FBSDKShareVideoContent()
//The videos must be less than 12MB in size.
let bundle = NSBundle.mainBundle()
let path = bundle.URLForResource("a", withExtension: "mp4")
let video = FBSDKShareVideo()
// doesn't work; needs to be an "asset url" (ALAsset)
//video.videoURL = path
content.video = video
let dialog = FBSDKShareDialog()
dialog.shareContent = content
dialog.show()
How is it possible to take a local bundle document, or an NSData object, and convert it to an ALAsset?
(My initial thinking was saving the video to the local camera roll, and then loading the list and selecting it, but that is unnecessary interface steps)
The documentation for an ALAsset states that
An ALAsset object represents a photo or a video managed by the Photo application.
so I'm pretty sure that you have to write the video to the camera roll before using it as an ALAsset. However, you don't need to open the camera roll and have a user pick the asset in order to use it. When writing to the ALAssetLibrary using
library.writeVideoAtPathToSavedPhotosAlbum(movieURL, completionBlock: { (newURL, error) -> Void
you get the asset url in that newUrl completion block variable. Use it in the Facebook sharing call
let content = FBSDKShareVideoContent()
content.video = FBSDKShareVideo(videoURL: newURL)
FBSDKShareAPI.shareWithContent(content, delegate: self)
NSLog("Facebook content shared \(content.video.videoURL)")
You can do this sharing inside the completion block if you so desire, or you can save the newUrl from the completion block and use it somewhere else.

Resources