I want to show the Alert message When no mail is configured on the device.But when i click Mail from document interaction it just simply dismiss the controller none of the two following Delegate method will call.Please refer Image for better understanding.
Please help. Thanks in Advance
- (void)openAppList:(FileInfo *)fileinfo {
NSURL *fileURL = [NSURL fileURLWithPath:fileinfo.fullName];
UIDocumentInteractionController *interactionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
[interactionController retain];
interactionController.delegate = self;
BOOL present = [interactionController presentOptionsMenuFromRect:CGRectZero inView:self.tabBarController.view animated:YES];
if (!present) {
[MainteOrErrorDialog initWithErrorCode:kAlertNotOpenInFileId filename:fileInfo.filename target:nil action:nil];
} else {
[interactionController retain];
}
}
#pragma UIDocumentInteractionDelegate
- (void)documentInteractionController:(UIDocumentInteractionController *)controller
willBeginSendingToApplication:(NSString *)application
{
}
- (void)documentInteractionController:(UIDocumentInteractionController *)controller
didEndSendingToApplication:(NSString *)application
{
}
Unfortunately, you can't really interact with the Mail delegates through UIDocumentInteractionController. UIDocumentInteractionController is extremely limited to what you can do with properties and attributes of all apps it supports, you can't even set a mails message body to a custom message. In fact, documentInteractionController:canPerformAction: is deprecated in iOS 6.0 because Apple was moving towards UIActivityViewController. They're own deprecated statement is :
Apps should use UIActivityViewController for actions
So alternatively, with UIActivityViewController you can.
A work around for this, implement UIActivityViewController, they both support the same apps and check if a user can send emails, if not, exclude Mail from the menu :
if ([MFMailComposeViewController canSendMail]) {
NSArray *shareItems;
shareItems = #[[Config emailMessage], snapshot]; //emailMessage is an NSString containing the body of the mail or mms message located in a different VC
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:shareItems applicationActivities:nil];
[activityController setCompletionWithItemsHandler:(UIActivityViewControllerCompletionWithItemsHandler)^(NSString *string, BOOL completed) {
}
[self presentViewController:activityController animated:YES completion:nil];
} else {
NSArray *shareItems;
shareItems = #[[Config emailMessage], snapshot]; //emailMessage is an NSString containing the body of the mail or mms message located in a different VC
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:shareItems applicationActivities:nil];
activityController.excludedActivityTypes = #[UIActivityTypeMail];
[activityController setCompletionWithItemsHandler:(UIActivityViewControllerCompletionWithItemsHandler)^(NSString *string, BOOL completed) {
}
[self presentViewController:activityController animated:YES completion:nil];
}
Related
Please Help us..
We want to share projects (i.e. Its Images, text and also my app url).
But i can't get SDK to share all on whatsApp, facebook, twitter, mails and messages. same as android developer using Intent called ACTION_SEND
Try this -
- (void)shareText:(NSString *)text andImage:(UIImage *)image andUrl:(NSURL *)url
{
NSMutableArray *sharingItems = [NSMutableArray new];
if (text) {
[sharingItems addObject:text];
}
if (image) {
[sharingItems addObject:image];
}
if (url) {
[sharingItems addObject:url];
}
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
[self presentViewController:activityController animated:YES completion:nil];
}
Call shareText like this -
[self shareText:#"Your text" andImage:nil andUrl:nil];
I am trying to send user location to facebook and whatsapp from my app by UIActivityViewController.
- (IBAction)shareUserLocation:(id)sender {
shareArray = [[NSArray alloc]initWithObjects:[NSURL URLWithString:[NSString stringWithFormat:#"http://maps.apple.com/maps?q=%f,%f",location.coordinate.latitude,location.coordinate.longitude]],nil];
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:shareArray applicationActivities:nil];
controller.excludedActivityTypes = #[];
[self presentViewController:controller animated:YES completion:nil];
}
Its working but opening the location in apple maps.
Is there a way I can open the location in Google maps.
P.S- I have not tried whatsApp i have only tested for facebook.
If you want to open a Google Maps URL in your Google Maps iOS app, you can use comgooglemapsurl://maps.google.com/?q=%f,%f. If you want to show it in browser, you can do https://maps.google.com/?q=%f,%f.
Sample code:
-(void)testURL:(CLLocation*)location {
NSArray *shareArray;
if ([[UIApplication sharedApplication] canOpenURL:[[NSURL alloc] initWithString:#"comgooglemaps://"]]) {
shareArray = [[NSArray alloc]initWithObjects:[NSURL URLWithString:[NSString stringWithFormat:#"comgooglemapsurl://maps.google.com/?q=%f,%f",location.coordinate.latitude,location.coordinate.longitude]],nil];
} else {
shareArray = [[NSArray alloc]initWithObjects:[NSURL URLWithString:[NSString stringWithFormat:#"https://maps.google.com/?q=%f,%f",location.coordinate.latitude,location.coordinate.longitude]],nil];
}
UIActivityViewController *controller = [[UIActivityViewController alloc] initWithActivityItems:shareArray applicationActivities:nil];
controller.excludedActivityTypes = #[];
[self presentViewController:controller animated:YES completion:nil];
}
I have seen a nice feature in the iOS App Scanner Pro. This app allows to send scanned documents as email attachments via the original mail app from Apple but without leaving the Scanner Pro app. I ask me how did they do it? Is there a special API call?
implement MFMailComposeViewControllerDelegate like this:
#interface YourViewController<MFMailComposeViewControllerDelegate >
Then where you want to instantiate this email viewcontroller just do the following:
if([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailController = [[MFMailComposeViewController alloc] init];
[mailController setMailComposeDelegate:self];
[mailController setSubject:#"Mail Subject!"];
[mailController setMessageBody:#"Here is your message body" isHTML:NO];
[mailController setToRecipients:[NSArray arrayWithObject:#"yourrecipent#domain.com"]];
NSData *imageData = UIImageJPEGRepresentation(imageToUpload, 1.0f);
if(imageData.length)
{
[mailController addAttachmentData:imageData mimeType:#"image/jpeg" fileName:#"Your_Photo.jpg"];
[self presentModalViewController:mailController animated:YES];
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Invalid Image" message:#"The image couldn't be converted." delegate:nil cancelButtonTitle:nil otherButtonTitles:#"Okay", nil];
[alert show];
}
}
Last implement mailComposerViewController delegate method
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
// or you can check for the status first and implement different task if you wish
}
You can use UIActivityViewController, for example:
UIImage *image = [UIImage imageNamed:#"image_file_name"];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:#[image] applicationActivities:nil];
[self presentViewController:activityViewController animated:YES completion:nil];
it gives user even more options, than just send email.
Yes, the so called UIActivityViewController. You use it like this:
NSArray *itemsToShare = #[[NSString stringWithFormat:#"This is a string that is sent via mail as well."], NSURLtoTheFileToSend];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:itemsToShare applicationActivities:nil];
activityVC.excludedActivityTypes = #[UIActivityTypeAssignToContact]; // Here you can say what you dont want to give the opportunity to share.
activityVC.completionHandler = ^(NSString *activityType, BOOL completed) {
if (completed) {
UIAlertView *alert = [[UIAlertView alloc] init];
alert.title = #"Export successfull";
[alert show];
[alert performSelector:#selector(dismissWithClickedButtonIndex:animated:) withObject:nil afterDelay:1];
}
};
[self presentViewController:activityVC animated:YES completion:^{}];
I have seen this format (Image shown below) of share option in most of the iOS applications that support iOS 7.
Is there a default code/framework available to implement this share option as it is shown in the image below?
What you are looking for is the UIActivityViewController.
Since you asked a general question I can't do more than give you a link to the documentation
In addition to the accepted answer, a small piece of example code
- (void)shareText:(NSString *)text andImage:(UIImage *)image andUrl:(NSURL *)url
{
NSMutableArray *sharingItems = [NSMutableArray new];
if (text) {
[sharingItems addObject:text];
}
if (image) {
[sharingItems addObject:image];
}
if (url) {
[sharingItems addObject:url];
}
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
[self presentViewController:activityController animated:YES completion:nil];
}
Call shareText, leave the things that you don't want to share at nil.
[self shareText:#"Hello world" andImage:nil andUrl:nil];
The Controller in the image you posted is the UIActivitiyViewController this is a link to the class documentation
some good example code:
How to display the default iOS 6 share action sheet with available share options?
I know this question is particular to iOS 7, and the code example specifies iOS 6, but AFAICT they are very similar one might find the example code as helpful as I did.
UIActivityViewController is what you are looking for.
You can specify either the items or the applications
UIActivityViewController *actCont = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
Just use following code for Default Sharing. You can able to add more items into shareItems array as per your requirement.
NSMutableArray *shareItems = [[NSMutableArray alloc] initWithObjects:
#"Hello",
[UIImage imageNamed:#"your_image.png"],
#"http://google.com/", nil];
[self shareItemToOtherApp:shareItems];
Following method is for default sharing Text or Image into other Apps:-
-(void)shareItemToOtherApp:(NSMutableArray *)shareItems{
UIActivityViewController *shareController = [[UIActivityViewController alloc]
initWithActivityItems: shareItems applicationActivities :nil];
[shareController setValue:#"Sharing" forKey:#"subject"];
shareController.excludedActivityTypes = #[UIActivityTypePostToWeibo, UIActivityTypeAssignToContact, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeSaveToCameraRoll];
shareController.completionHandler = ^(NSString *activityType, BOOL completed)
{
//NSLog(#" activityType: %#", activityType);
//NSLog(#" completed: %i", completed);
};
[self presentViewController: shareController animated: YES completion: nil];
}
If you want to make Custom Sharing sheet then use following code. For this, you have to import <Social/Social.h> framework.
-(void)shareOnFacebook:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook])
{
SLComposeViewController *faceSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
// NSLog(#"%#", messageField.text);//This returns the appropriate string
[faceSheet setInitialText:#"Hellooooooo"];
//The facebook VC appears, but initial text is not set to messageField.text
[self presentViewController:faceSheet animated:YES completion:nil];
}
else
{
NSLog(#"Please first install Application and login in Facebook");
}
}
-(void)shareOnTwitter:(id)sender {
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter])
{
SLComposeViewController *tweetSheet = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
[tweetSheet setInitialText:#"Hello"];
[self presentViewController:tweetSheet animated:YES completion:nil];
}
else{
NSLog(#"Please first install Application and login in Twitter");
}
}
Hope, this is what you're looking for. Any concern get back to me. :)
I finally find someone who was facing the same problem than me.
UIActivityViewController customize text based on selected activity
I want to customize the content share with the activities of the UIActivityViewController. The good answer is the following:
"Instead of passing the text strings into the initWithActivityItems
call, pass in your own sub-class of the UIActivityItemProvider class
and when you implement the itemForActivityType method it will provide
the sharing service as the 'activityType' parameter.
You can then return the customized content from this method."
I understand tricks, but I'm not getting the way to do it...
I did this as a subclass:
#interface SharingItems : UIActivityItemProvider
#implementation SharingItems
-(id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
// Here depending on the activityType i want to share NSString or UIImage
}
#end
But I don't know what to do now in my original viewController:
-(void)actionSheet
{
if ([[UIActivityViewController class] respondsToSelector:#selector(alloc)])
{
__block NSString *imgName = [[NSString alloc] initWithFormat:#"%#", _sharingUrl];
NSArray *activityItems = [NSArray arrayWithObjects:imgName, nil];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
[self presentViewController:activityController animated:YES completion:nil];
__block NSString *chan = [[NSString alloc] initWithFormat:#"%#", _channel];
[activityController setCompletionHandler:^(NSString* activityType, BOOL completed)
{
if (completed)
{
}
}];
}
else
[self displayActionSheet];
}
Here's an example UIActivityItemProvider (not tested but adapted from working code):
#implementation StringProvider
- (id)initWithPlaceholderString:(NSString*)placeholder facebookString:(NSString*)facebookString
{
self = [super initWithPlaceholderItem:placeholder];
if (self) {
_facebookString = facebookString;
}
return self;
}
- (id)item
{
if ([self.activityType isEqualToString:UIActivityTypePostToFacebook]) {
return _facebookString;
} else {
return self.placeholderItem;
}
}
#end
Then when you set up the activity view controller:
StringProvider *stringProvider = [[StringProvider alloc] initWithPlaceholderString:#"Default string" facebookString:#"Hello, Facebook."];
UIActivityViewController *shareController = [[UIActivityViewController alloc] initWithActivityItems:#[stringProvider] applicationActivities:nil];
Basically you create UIActivityItemProviders that provide the right data when the -(id)item method is called and pass in those activity item providers when you create the activity view controller. You need to initialize with a placeholder item so the OS knows what class the final item will be (most likely NSString, NSURL, UIImage). Hope that helps!