Share image and/or text through Share Menu on iOS (Swift) - ios

I am looking for a way to share both an image (a screenshot generated by the app) and text, with a preference to the image.
When I try to achieve this, I see it only works for Apple's own Messaging app and maybe a few other apps. But I don't see apps like Snapchat, Tiktok and other famous apps show up in the default share menu that's provided by Apple. For other apps, only the text shows up and the image is ignored.
However, when I leave out the text from the UIActivityViewController so it only contains the image to share, all other apps show up and most of them work perfectly with my image.
How can I make my code so that, if supported, it shares BOTH the image and the text and in other cases gives preference to the image instead of the text. I still want all the apps (like Snapchat, Tiktok and other social media apps) to show up to share to it because this only happens when only the image is in the UIActivityViewController.
This is the code to make sharing work in my app.
func shareMenu() {
if var top = scene?.view?.window?.rootViewController {
while let presentedViewController = top.presentedViewController {
top = presentedViewController
}
let screenshotImage = getScreenshot(scene: scene!)
let activityVC = UIActivityViewController(activityItems: [screenshotImage , "The text that's need to be shared."], applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = view
top.present(activityVC, animated: true, completion: nil)
}
}

Related

Swift 5 - System ShareSheet modals' navbar font color is white, blending in with background. How to access their appearance?

Swift 5, IOS 16, iPad 9.7"
I've got a pretty simple sharesheet implementation to send a pdf file. The share sheet itself looks fine, but "Save to Files" and "Messages" modals all have white font on the nav buttons that make it extremely hard to see. Interestingly, "Email" and "Notes" render fine.
Any ideas? I can't find anything in my app that could affect the system modals' display config.
ShareSheet looks normal
Email looks normal
Notes look normal
Messages white font issue
File Explorer white font issue
Tried to set
UINavigationBar.appearance() = ...
but this has no effect no matter what it's set to. Is there a way to capture/examine/debug the modals properties after the sharesheet? I only have visibility into the ShareSheet itself's view controller, not its children:
let ac = UIActivityViewController(activityItems: items, applicationActivities: nil)
ac.popoverPresentationController?.sourceView = self.view
present(ac, animated: true, completion: nil)
Figured out the solution.
Global Accent Color in project settings was set to a white Asset. Removing this config and the asset fixed my issue.
https://developer.apple.com/documentation/watchos-apps/setting-the-app-s-accent-color?changes=_3

How to hide "Share option" and take user directly to the "Save to Files" Screen in Swift

I have gone through different stackoverflow questions or developer's forums but I am unable to find any answer.
The questions previously asked is about previewing files and then hiding the Share button on the right top of your screen.
Whereas, my question is related to using UIDocumentInteractionControllerDelegate and only allowing user to perform one action i.e. Save to Files
Currently, this popup opens which gives me option to Share and Save to Files
Whereas, I want my controller to directly navigate to this screen:
I have written following code:
func openUrl(url : URL) {
self.documentInteractionController = UIDocumentInteractionController(url: url)
self.documentInteractionController.delegate = self
ProgressIndicator.hideHud()
let isValidAppAvailable = self.documentInteractionController.presentOpenInMenu(from: self.view.frame, in: self.view, animated: true)
if (!isValidAppAvailable){
AlertManager.showAlert(self.getMessage(messageId: Messages.noCompatibleApplicationFound.rawValue))
}
}
Any help on how to directly open Save to Files from code would be appreciated.

Share full-size image from remote URL

I found this tutorial in order to let my users share images from my app:
https://www.hackingwithswift.com/articles/118/uiactivityviewcontroller-by-example
Here is the relevant code:
let items = [yourImage]
let ac = UIActivityViewController(activityItems: items, applicationActivities: nil)
present(ac, animated: true)
It looks like I need to pass a UIImage in the items array.
In my app, I show a feed of images. In the API call for the feed, each image has a thumbnail URL (smaller size) and a full-size URL. My app displays the thumbnail images in the feed in order to keep my app speedy.
This activity view controller is triggered when the user long-presses one of the images in the feed. The problem is that I want the user to be able to share the full-size image (which isn't loaded into any ImageView in the feed), instead of the thumbnail image.
How can I do this?
I've considered fetching the full-size image on long press by following this tutorial, but this causes issues in that the activity view controller doesn't actually show until the image is fully downloaded.
What else can I do??
As an additional question, would the same apply to if I wanted to let the user share a video (mp4)?

How do I preselect the service that will be chosen in a UIActivityViewController?

I am wondering how Dolly (iOS app) does this. If I select the Twitter icon in the first screenshot, the view in the second screen appears immediately.
That second screenshot is what is presented after you typically click the Twitter service from the scrollable list presented in a UIActivityViewController (below), e.g. Facebook, Mail, Messages, Twitter, etc. But, I never had to click Twitter from the below menu.
Again, the share sheet was presented immediately. I did not have to select Twitter from the built in set of options. So, I am wondering what, if anything I can do to duplicate this behavior. Possibly a few lines that I am missing below?
func handleTwitterShareButtonTapped(){
let activityVC = UIActivityViewController.init(activityItems: [ShareActivityItemStringSource(), ShareActivityItemURLSource()], applicationActivities: [])
//preselect twitter from services somehow???
navigationController?.present(activityVC, animated: true, completion: nil)
}
Or, perhaps there is some swizzling magic that I need to do. If this does involve swizzle magic, any resources that might get me going would be extremely helpful.
Thanks!!!

Swift - force square photo from library and camera

I'm building an app and I need to FORCE the user to upload square pictures (just like Instagram does), however I'd like to avoid programming an interface from scratch as we're short in time.
It is important to note that the USER must CHOOSE which part of the image he/she wants to show, so cropping the image programatically without asking the user is out of the question.
I've managed to get this to work via camera, however via library I can't seem to force the user to use a square image. Here's the code I have:
func presentGallery(){
// from library
picker.allowsEditing = true
picker.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
presentViewController(picker, animated: true, completion: nil)
}
Then on my imagepickercontroller:
var chosenImage = info[UIImagePickerControllerEditedImage] as! UIImage
However I don't get the desired result. It would be fine if the "minimum zoom" was to show 100% of the height of the image, or if I could add a white/black background to the top and bottom of the image.
Here's the problem:
Instead of something like this:
My app needs to work starting from iOS7.
You should do some sort of check to make sure that the picture is square if they're picking from their library.
Once you get the image (using imagePickerController didFinishPickingMediaWithInfo), then get the image with [info objectForKey:UIImagePickerControllerOriginalImage];. Once you've done this, perform the check:
if (image.size.height != image.size.width) // Show some alert
What might be an even better solution is creating a view which allows the user to pick any photo, and then choose a square part of the photo to import into your app, like Instagram does.

Resources