iOS native way to share files to any possible apps - ios

I'm currently implementing an iOS app using objective-C, which has a function that users may share a file with other friend or other app (like upload the file to Dropbox, Google Drive, attach the file to Mail, share the file to Facebook Messenger, Whatsapp, via Bluetooth, etc).
Is there a native way to implement this share function that can detect all apps which allows sharing a file, while I don't need to do it one by one?

You want to use UIActivityViewController. Below is an example from NSHipster, which is probably the most comprehensive article I've seen on the subject. And Apple has some good documentation here.
NSString *string = ...;
NSURL *URL = ...;
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[string, URL]
applicationActivities:nil];
[navigationController presentViewController:activityViewController
animated:YES
completion:^{
// ...
}];

This provide full answer for iPhone and iPad devices
ViewController *contentViewController = [[ViewController alloc] init];
// Present the view controller using the popover style.
contentViewController.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:contentViewController
animated:YES
completion:nil];
// Get the popover presentation controller and configure it.
UIPopoverPresentationController *presentationController =[contentViewController popoverPresentationController];
presentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
presentationController.sourceView = self.view;
presentationController.sourceRect = self.view.frame;
UIPopoverPresentationController should have a non-nil sourceView or barButtonItem set before the presentation occurs on iOS 9

Related

Popover crashing on iPad (SpriteKit game)

Recently I discovered that it’s necessary to use Popover to display the ActivityViewController on iPad. I found this website as a main reference:
http://pinkstone.co.uk/how-to-share-things-with-a-uiactivityviewcontroller/
It’s perfectly explained, but I can’t make it work from my SpriteKit game. I double-checked with other examples and all seems to be in its place... but this crash on iPad anyways, without any meaningful message (on iPhone it works). I have no idea on what’s wrong. If somebody experienced the same, any clue will be very welcome!
UIActivityViewController *activityController = [[UIActivityViewController alloc]initWithActivityItems:#[twitterText] applicationActivities:nil];
UIViewController* viewController = self.view.window.rootViewController;
activityController.modalPresentationStyle = UIModalPresentationPopover;
[viewController presentViewController:activityController animated:YES completion:nil];
UIPopoverPresentationController *popController = [activityController popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionDown;
popController.sourceRect = CGRectMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame),200,200);
The solution was adding
popController.sourceView = self.view;
before the sourceRect. Thanks and kudos to Warren Burton.

UIActivityViewController view frame is cut in ios 9.0

I encounter this bug when using UIActivityViewController in order to create a simple UI for sharing assets in my app. This works well on ios 10 and above, but in ios 9 this annoy issue appears. I've already researched for solutions but didn't find any help. Could you guys please take a look?
My code is just simple as below:
NSString *url=#"http://itunes.apple.com/us/app/APPNAME/idXXXXXXXXX";
NSString * title =[NSString stringWithFormat:#"Download ECG app %# and get free reward points!",url];
NSArray* dataToShare = #[title];
UIActivityViewController* activityViewController =[[UIActivityViewController alloc] initWithActivityItems:dataToShare applicationActivities:nil];
activityViewController.excludedActivityTypes = #[UIActivityTypeAirDrop];
[self presentViewController:activityViewController animated:YES completion:^{}];
In ios 9, it looks like THIS
Please try to update animated:NO when you present the Activity View, if the view displayed correctly with animated:NO then self.view.translatesAutoresizingMaskIntoConstraints = NO; should be the cause of this problem.

iOS 8.3 Facebook error Not logged In

I'am sharing a NSString and NSURL, using the native UIActivityViewController
The user is logged in into Facebook both in Settings and also in the Facebook App
but after iOS 8.3 i'am getting this error... moreover, on older devices, the dialog confirmation is obscured by the keyboard, making it impossible to confirm or decline
UIActivityViewController *vc = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:applicationActivities];
NSArray *excludeActivities = #[UIActivityTypeAssignToContact];
vc.excludedActivityTypes = excludeActivities;
if (IsUserInterfaceIdiomPad) {
vc.popoverPresentationController.sourceView = self.navigationController.view;
}
[self.navigationController presentViewController:vc animated:YES completion:^{
}];
Yes, this is a bug that went out in Version 29 of the Facebook application. We (Facebook) are working on a fix and hope that it will ship soon.

UIActivityController Cancel button doesn't work on iPad

I've a problem with the UIActivityController on iOS 8 iPad: the activity view works correctly I can select a share service (i.e. Twitter) but when the "publish" view appear I can only click on the Post button,the Cancel button doesn't work. I've the same problem on real devices and on the simulator.
If you have an idea about how to fix this problem,...
Thanks
Here's my code:
- (IBAction)activityController:(id)sender {
// items to share
NSURL *url = [NSURL URLWithString:_articleUrl];
NSArray *items=#[url];
// create the controller
UIActivityViewController *controller = [[UIActivityViewController alloc]initWithActivityItems:items applicationActivities:nil];
[self presentViewController:controller animated:YES completion:nil];
UIPopoverPresentationController *popPC = controller.popoverPresentationController;
popPC.barButtonItem = _buttn;
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny;

Why UIActivityViewController doesn't dismiss MFMailComposeViewController when the presenter is a UITabbarController child?

I have a very simple case where a button shows an UIActivityViewController to share some content. The problem is that the mail composer is not dismissed when the user cancel or sends email.
NSArray *items = [NSArray arrayWithObjects:#"share",nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
I tried to dismiss the modal view in the activityViewController.completionHandler but then the console says that another animation is in process and sometimes crash the app, so this isn't the solution. Besides other social networks work well (facebook, twitter) without doing anything.
After some tests I detected that this only occurs if the UIViewController that presents the UIActivityViewController is a child of a UITabBarController.
If in my AppDelegate I create the app like this it doesn't work:
UIViewController > UINavigationController > UITabbarController > Window
but if I remove the tabbar all works fine!:
UIViewController > UINavigationController > Window
A workaround that solves the problem is presenting from the rootviewcontroller.
[self.view.window.rootViewController presentViewController:activityViewController animated:YES completion:NULL];
but I want to know what's happening here.
Thanks! ;)
I had the same issue and after figuring out I get to know that when we don't present mail composer from the class which is currently active on window , it will fail to take responses some time like it will not get even present on every call, same is the problem with dismisal.
It is not that it is only the case with UITabbarController. It can happen to any architecture when you are presenting it from different controller which is not currently on window. That is why your workaround is working and its not wrong though.
I was presenting mail composer from a button tapped inside uipopover. Mail composer was being presented in that popover controller class. And I was facing the same issue you are facing. Then I changed my code to :
MFMailComposeViewController *mailComposer = [MFMailComposeViewController new];
[mailComposer addAttachmentData:data mimeType:#"application/pdf" fileName:model.documentTitle];
[mailComposer setSubject:model.documentTitle]; // Use the document file name for the subject
if(kBccEmailID)
[mailComposer setBccRecipients:[[NSArray alloc]initWithObjects:kBccEmailID, nil ]];
mailComposer.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
mailComposer.modalPresentationStyle = UIModalPresentationFormSheet;
AppDelegate *delagate =(AppDelegate *) [[UIApplication sharedApplication]delegate];
mailComposer.mailComposeDelegate = [[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject]; // Set the delegate
[(UIViewController *)[[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject] presentViewController:mailComposer animated:YES completion:nil];
[(UIViewController *)[[(UINavigationController *)delagate.window.rootViewController viewControllers] lastObject] is an alternative for your 'self.view.window.rootViewController'.

Resources