Sharing multiple images AND text using activityController is not working - swift

I am making a sales app to email charts as images with text for my company, but I am having a problem with my app.
For some reason I can't send multiple images and text together, when the code below is activated, only the text is sent.
I triple checked and the images are NOT nil and I can share text, multiple images alone or text and a single image just fine.
Furthermore I am only sending two images and this is just for the phone version alone.
func EmailMultipleImages(imageArray: [UIImage], emailSubject: String, emailBodyText : String) {
print("Image array \(imageArray.count)")
do {
let shareContent: [Any] = [imageArray, emailBodyText]
//Multiple images alone
//let shareContent: [Any] = [imageArray]
//Text alone
//let shareContent: [Any] = [emailBodyText]
//One image and text
//let shareContent: [Any] = [imageArray[0], emailBodyText]
let activityController = UIActivityViewController(activityItems: shareContent, applicationActivities: nil)
activityController.setValue(emailSubject, forKey: "Subject")
viewController!.present(activityController, animated: true, completion: nil)
}
catch {
print("Error print mulitple images \(error)")
}
}

Make that array a flat object and it should work.
example:
func share() {
let activityItems = [
"Title",
"Body",
UIImage(systemName: "keyboard")!,
UIImage(systemName: "square.and.arrow.up")!
] as [Any]
let vc = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)
vc.setValue("Testing", forKey: "Subject")
self.present(vc, animated: true, completion: nil)
}
Output:

Related

UIActivityViewController not showing all options

In a tableview, I am using a context menu to share a cell's image (via snapshot()) and a small string. However, when I use the UIActivityViewController, not all of the options like Mail and Messages are showing.
What am I doing wrong here? How can I show all of the share options?
if let cell = tableView.cellForRow(at: indexPath) as? ResultsTableViewCell,
let cellSnapshot = cell.snapshot() {
let items: [Any] = ["Check out this speed test.", cellSnapshot]
let activityViewController = UIActivityViewController(activityItems: items, applicationActivities: nil)
self.present(activityViewController, animated: true)
}

UIActivityViewController send UIImage

I have one image generate it in App
the image displayed in uiimageview
here is my image
var img:UIImage!
img = UIImage(ciImage: transformedImage)
here is the value before share it in breakpoint
print(img)
some(UIImage: 12345 , {200, 200})
let myShare = "My beautiful photo! <3 <3"
let shareVC: UIActivityViewController = UIActivityViewController(activityItems: [(img), myShare], applicationActivities: nil)
self.present(shareVC, animated: true, completion: nil)
but the image can not be show but the text it's show in iMessage or email and other apps ... How can I share the image ? in iMessage emails and etc...
Use this method:
func shareImageBtn(img : UIImage, txt : String) {
// if an image and a txt aren't nil
let resourses = [ image!, txt!]
let activityViewController = UIActivityViewController(activityItems: resources, applicationActivities: nil)
activityViewController.popoverPresentationController?.sourceView = self.view // iPads won't crash
// (optional)
activityViewController.excludedActivityTypes = [ .airDrop, .postToFacebook ]
// present the VC
self.present(activityViewController, animated: true, completion: nil)
}

Swift 4 UIActivityViewController send an Image with AirDrop

I have a problem, I would like to sent an Image with E-Mail, Message and also AirDrop. Currently only E-Mail and Message works, when I try to sent it per AirDrop, the Device get an .data File, which I can't open. How I can fix this problem ?
#IBAction func sendItButton(_ sender: UIBarButtonItem) {
let imageShare = [ image! ]
let activityViewController = UIActivityViewController(activityItems: imageShare , applicationActivities: nil)
activityViewController.popoverPresentationController?.barButtonItem = sender
self.present(activityViewController, animated: true, completion: nil)
}
I have faced similar issue today, seems like there's a bug on UIActivityViewController if the UIImage is originated from a .jpeg image from bundle. I used the file URL of the image (instead of UIImage) as the activityItems and it worked fine.
private func urlForBundleFile(filename: String) -> URL? {
let components = filename.components(separatedBy: ".")
return Bundle.main.url(forResource: components[0], withExtension: components[1])
}
let imageURL = urlForBundleFile(filename: "someImage.jpeg")
let activityViewController = UIActivityViewController(activityItems: [imageURL] , applicationActivities: nil)

UIActivityViewController share a video on WhatsApp

I have look around a lot but didn't find a solution to my problem.
I am displaying videos in a tableviewcell like this
if let videoUrlString = post?.videoUrl, let videoUrl = URL(string: videoUrlString) {
self.volumenView.isHidden = false
player = AVPlayer(url: videoUrl)
playerLayer = AVPlayerLayer(player: player)
playerLayer?.frame = postImageView.frame
playerLayer?.frame.size.width = UIScreen.main.bounds.width
playerLayer?.frame.size.height = UIScreen.main.bounds.width / post!.ratio!
self.contentView.layer.addSublayer(playerLayer!)
self.volumenView.layer.zPosition = 1
player?.play()
player?.isMuted = isMuted
NotificationCenter.default.addObserver(self, selector:#selector(self.playerDidFinishPlaying(note:)),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player?.currentItem)
}
this works perfectly fine.
Now I want the user to be able to share the video on WhatsApp.
I ve made it work text post and image post which work fine but wasn't able to make it run with videos.
this is how I currently send the notification
let videoURL = NSURL(fileURLWithPath: (post?.videoUrl)!)
let data:[String: NSURL] = ["video": videoURL]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "shareCalled"), object: nil, userInfo: data)
this works so far that the chat partner receives a link to where the video is stored in firebase and by clicking that link he can see the video.
This works but its not elegant, I would like to send the video as one and not as a link where the user has to suspiciously click on.
Any idea?
Edit: code where I share the post (notice: text and image work fine, video just sends the url but not a video as one
#objc func shareCalled(_ notification: NSNotification) {
if let data = notification.userInfo?["image"] as? UIImage {
let activityVC = UIActivityViewController(activityItems: [data], applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = self.view
activityVC.excludedActivityTypes = [UIActivityType.airDrop, UIActivityType.addToReadingList,UIActivityType.openInIBooks, UIActivityType.openInIBooks]
self.present(activityVC, animated: true, completion: nil)
}
if let data = notification.userInfo?["caption"] as? String {
let activityVC = UIActivityViewController(activityItems: [data], applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = self.view
activityVC.excludedActivityTypes = [UIActivityType.airDrop, UIActivityType.addToReadingList,UIActivityType.openInIBooks, UIActivityType.openInIBooks]
self.present(activityVC, animated: true, completion: nil)
}
if let data = notification.userInfo?["video"] as? URL {
let activityVC = UIActivityViewController(activityItems: [data], applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = self.view
activityVC.excludedActivityTypes = [UIActivityType.airDrop, UIActivityType.addToReadingList,UIActivityType.openInIBooks, UIActivityType.openInIBooks]
self.present(activityVC, animated: true, completion: nil)
}
}

Add Instagram to UIActivityViewController

I'm trying to share an image using standard UIActivityViewController, it's fine to share on Facebook, Twitter and Save Image using this code:
let firstActivityItem = "foo text"
let secondActivityItem : UIImage = image!
let activityViewController : UIActivityViewController = UIActivityViewController(
activityItems: [firstActivityItem, secondActivityItem], applicationActivities: nil)
activityViewController.excludedActivityTypes = [
UIActivityTypePostToWeibo,
UIActivityTypePrint,
UIActivityTypeAssignToContact,
UIActivityTypeAddToReadingList,
UIActivityTypePostToVimeo,
UIActivityTypePostToTencentWeibo
]
self.presentViewController(activityViewController, animated: true, completion: nil)
I need one more thing, Instagram:
If UIApplication.sharedApplication().canOpenURL(instagramURL!) {
// Success
var img = image!
var savePath: String = NSHomeDirectory().stringByAppendingPathComponent("Documents/Test.igo")
UIImageJPEGRepresentation(img, 1).writeToFile(savePath, atomically: true)
var imgURL = NSURL(string: NSString(format: "file://%#", savePath) as! String)
docController = UIDocumentInteractionController(URL: imgURL!) // 1
docController.UTI = "com.instagram.exclusivegram" // 2
docController.delegate = self
docController.annotation = ["InstagramCaption":"testsss"] // 3
docController.presentOpenInMenuFromRect(self.view.frame, inView: self.view, animated: true) // 4
} else {
// Error
}
Both these codes work fine separately, how can I add Instagram to the UIActivityViewController? Is it possible at all?
I think it would be very easier to add other social shares to the code you wrote for Instagram. The ".igo" extension is exclusive for Instagram so other apps will not support it. Just change this extension from ".igo" to ".ig" and other apps will read it:
var savePath: String = NSHomeDirectory().stringByAppendingPathComponent("Documents/Test.ig")
But Instagram also have an exclusive UTI to avoiding other apps to appear in the same Document Interaction View. So you will also need to change it from "exclusivegram" to "photo":
docController.UTI = "com.instagram.photo"
I have an app with a similar functionality and this is my original code:
#IBAction func shareOnIntagram(sender: UIButton) {
let finalImage: UIImage = UIImage.imageWithView(photoView)
let instagramURL = NSURL(string: "instagram://app")
if (UIApplication.sharedApplication().canOpenURL(instagramURL!)) {
let imageData = UIImageJPEGRepresentation(finalImage, 1)
let captionString = "caption"
let writePath = (NSTemporaryDirectory() as NSString).stringByAppendingPathComponent("instagram.ig")
if imageData?.writeToFile(writePath, atomically: true) == false {
return
} else {
let fileURL = NSURL(fileURLWithPath: writePath)
self.documentController = UIDocumentInteractionController(URL: fileURL)
self.documentController.delegate = self
self.documentController.UTI = "com.instagram.photo"
self.documentController.annotation = NSDictionary(object: captionString, forKey: "InstagramCaption")
self.documentController.presentOpenInMenuFromRect(self.view.frame, inView: self.view, animated: true)
}
} else {
print(" Instagram is not installed ")
}
}
To make this code work, don't forget to add UIDocumentInteractionControllerDelegate in the UIViewController class.
It seems it's not possible, because of .igo extension which is needed by Instagram.