I have created an application that uses the SMS and after the user clicks the sms button it opens up with my number already in and no message (thats their job). But when it loads up the sms message page it set the curser thing is up where the recipients are not where the message is. To explain that better, after the sms loads if they were to just start typing they would be adding another person to send the message to, not typing the message. For example if I would like to load up to a specific row on my UIPicker on startup I would:
[picker selectRow:3 inComponent:0 animated:NO];
sms load up:
- (IBAction)sms {
MFMessageComposeViewController *textComposer = [[MFMessageComposeViewController alloc] init];
[textComposer setMessageComposeDelegate:self];
if ([MFMessageComposeViewController canSendText]) {
[textComposer setRecipients:[NSArray arrayWithObjects: #"support#nicmacengineering.com", nil]];
[textComposer setBody:#""];
[self presentViewController:textComposer animated:YES completion:NULL];
} else {
NSLog(#"Can't Open Text");
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
switch (result) {
case MessageComposeResultCancelled:
NSLog(#"Cancelled");
break;
case MessageComposeResultFailed:
break;
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
First, your question is fairly hard to understand. Here's my impression of it:
Can I set the cursor to the message field by default in an SMS controller?
And the answer is:
No.
Since it is an Apple framework, with no public method to switch fields (here's the class reference).
Because of this, you won't be able to automatically set the position of the cursor.
Related
I used SLComposerController, but it is not disabling the post button when the character count exceeds 140 character . I want to post an URL ,image and initial text on Twitter via my iOS application. How to do this?
It is up to the user to set the correct length to send, but I think it won't send if it is too long, or give you a callback if it didn't work.
Here is what I did:
-(void) postOnTwitterInsideView:(UIViewController *)viewController
message:(NSString *)postMessage{
if( [SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter] ){
SLComposeViewController *twitterPost = [SLComposeViewController
composeViewControllerForServiceType:SLServiceTypeTwitter];
[twitterPost setCompletionHandler:^(SLComposeViewControllerResult result){
switch (result) {
case SLComposeViewControllerResultDone:
// tell user message was sent
break;
case SLComposeViewControllerResultCancelled:
// tell user message was not sent
break;
default:
break;
}
}];
[twitterPost addImage:self.imagePost];
[twitterPost setInitialText:postMessage];
[viewController presentViewController:twitterPost
animated:YES
completion:nil];
} else {
// tell user he has to activate this service in his settings of iOS
}
}
I have a few questions regarding MFMessageComposeViewController:
Is there a way to know to whom the user actually sent the SMS to?
Or, at least be able to know to how many numbers the SMS was sent to?
What was the message that was actually sent?
Here is what I have so far, and it works OK. But It seems there is only one delegate, but it's so simple that it's pretty much useless.
- (void)showSMS:(NSArray *)numbers message:(NSString *)message {
MFMessageComposeViewController *messageController = [[MFMessageComposeViewController alloc] init];
messageController.messageComposeDelegate = self;
[messageController setRecipients:numbers];
[messageController setBody:message];
[self presentViewController:messageController animated:YES completion:nil];
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result {
if (result == MessageComposeResultCancelled) {
NSLog(#"SMS cancelled");
}
else if (result == MessageComposeResultFailed) {
NSLog(#"SMS failed");
}
else if (result == MessageComposeResultSent) {
NSLog(#"SMS sent");
}
[self dismissViewControllerAnimated:YES completion:nil];
}
Thanks.
This isn't possible. The iOS SDK doesn't expose a way to access this.
From Apple's documentation of MFMessageComposeViewController:
Important: The message composition interface itself is not
customizable and must not be modified by your app. In addition, after
presenting the interface, your app is unable to make further changes
to the message content. The user can edit the content using the
interface, but programmatic changes are ignored. Thus, you must set
the values of content fields, if desired, before presenting the
interface.
I am trying to allow the player to share their score by SMS when the game is over.
I have imported the framework in to my project. Imported in the my viewController.h file.
here is my viewController.h file
#import <UIKit/UIKit.h>
#import <SpriteKit/SpriteKit.h>
#import <MessageUI/MessageUI.h>
#interface myViewController : UIViewController <MFMessageComposeViewControllerDelegate> {
}
#end
I also tried to import into MyScene.h like so:
#import <MessageUI/MessageUI.h>
#interface MyScene : SKScene <MFMessageComposeViewControllerDelegate> {
}
When I want to show the SMS share, I use this code in my MyScene.m file
MFMessageComposeViewController *textComposer = [[MFMessageComposeViewController alloc] init];
[textComposer setMessageComposeDelegate:self];
if ([MFMessageComposeViewController canSendText]) {
[textComposer setRecipients:[NSArray arrayWithObject:nil]];
[textComposer setBody:#"Happy Happy Joy Joy!"];
[self presentViewController:textComposer animated:YES completion:NULL];
} else {
NSLog(#"Cant send text!");
}
But on this line
[self presentViewController:textComposer animated:YES completion:NULL];
I get an "No visible #interface for 'MyScene' declares the selector 'presentViewController:animated:completion:'" error.
I have tried to search for the last couple hours. Try god knows how many variations and examples from other posts/tutorials(which was good to learn a few things unrelated to this). Nothing seems the work. I starting to run out of hair to pull out. So any help would be great. I am sure for some of you Gurus here this should be a walk in the park. Thanks.
EDIT: I am not using storyboard, or the view controller for buttons/menu/game play etc...hence why I am not able to call the function from within the viewController itself.
EDIT:
So I tried what Paulw11 suggested in his link. Now I have the following errors.
in myViewController
MyScene.MyViewController = self;
I get a "Property 'MyViewController' not found on object of type 'MyScene'" error
also in MyScene.m
- (void)sendToController
{
NSLog(#"ok");
// use the already-created spriteViewController
[_MyViewController sendSMS];
}
[_MyViewController sendSMS]; line I get an "No visible #interface for 'MyViewController' declares the selector 'SendSMS'"
EDIT 2: *EDIT 2:* EDIT 2: *EDIT 2:*
I got it to open up the SMS. Small problem, it does not allow me to dismiss it /cancel.
Here is my sendSMS code:
-(void) sendSMS {
MFMessageComposeViewController *textComposer = [[MFMessageComposeViewController alloc] init];
[textComposer setMessageComposeDelegate:self];
if ([MFMessageComposeViewController canSendText]) {
[textComposer setRecipients:[NSArray arrayWithObject:#" "]];
NSString *body = [NSString stringWithFormat:#"Happy Day!: %i. ", _score];
[textComposer setBody:body];
UIViewController *vc = self.view.window.rootViewController;
[vc presentViewController: textComposer animated: YES completion:nil];
} else {
NSLog(#"Cant send text!");
}
}
Here is my dismiss code:
-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result {
UIViewController *vc = self.view.window.rootViewController;
[vc dismissViewControllerAnimated:YES completion:NULL];
}
EDIT 3
The following code gives me the NSLog at the correct times, but does not dismiss the window.
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result
{
UIViewController *vc = self.view.window.rootViewController;
// Notifies users about errors associated with the interface
switch (result)
{
case MessageComposeResultCancelled:
NSLog(#"Result: SMS sending canceled");
break;
case MessageComposeResultSent:
NSLog(#"Result: SMS sent");
break;
case MessageComposeResultFailed:
NSLog(#"Result: SMS sending failed");
break;
default:
NSLog(#"Result: SMS not sent");
break;
}
[vc dismissViewControllerAnimated:YES completion:NULL];
}
If you refer to the MFMessageComposeViewController Class Reference you will see that you need to present it modally using presentModalViewController:animated:. You are also responsible for dismissing it via your delegate object once you are done.
I suggest you have a look at the Message Composer sample code for an example of using the MFMessageComposeViewController class.
UPDATE
You can just dismiss the view controller that was passed to your delegate method -
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result
{
// Notifies users about errors associated with the interface
switch (result)
{
case MessageComposeResultCancelled:
NSLog(#"Result: SMS sending canceled");
break;
case MessageComposeResultSent:
NSLog(#"Result: SMS sent");
break;
case MessageComposeResultFailed:
NSLog(#"Result: SMS sending failed");
break;
default:
NSLog(#"Result: SMS not sent");
break;
}
[controller dismissViewControllerAnimated:YES completion:NULL];
}
I have an app that allows the user to send a test email from their iPhone. My app calls a method to activate the compose mail function like this:
-(void)displayComposerSheet
{
//set up a way to cancel the email here
//picker is an instance of MSMailComposeViewController already declared in the .h file
[picker setSubject:#"Test Mail"];
// Set up recipients
// Attach an image to the email
NSString *path = [[NSBundle mainBundle] pathForResource:#"Icon" ofType:#"png"];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:#"image/png" fileName:#"Icon"];
// Fill out the email body text
NSString *emailBody = #"This is a test mail.";
[picker setMessageBody:emailBody isHTML:NO];
[self presentModalViewController:picker animated:YES];
NSLog(#"mail is working");
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error
{
emailLabel.hidden = NO;
// Notifies users about errors associated with the interface
switch (result)
{
case MFMailComposeResultCancelled:
emailLabel.text = #"Mail sending canceled.";
break;
case MFMailComposeResultSaved:
emailLabel.text = #"Mail saved.";
break;
case MFMailComposeResultSent:
{
emailLabel.text = #"Mail sent.";
NSLog(#"It's away!");
UIAlertView *emailAlertView = [[UIAlertView alloc] initWithTitle:#"Sent!" message:#"Mail sent successfully." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[emailAlertView show];
[self dismissModalViewControllerAnimated:YES];
[self.navigationController popViewControllerAnimated:YES];
}
break;
case MFMailComposeResultFailed:
{
emailLabel.text = #"Mail sending failed.";
}
break;
default:
{
emailLabel.text = #"Mail not sent.";
}
break;
}
}
My problem is that when the compose email function is active, I am unable to come out of this function and return to my app. The only way out of this is by actually going ahead and sending a message. There is a default "cancel" bar button that appears on the top left hand corner of the navigation bar, which when clicked, gives me three options: "delete draft", "save draft", and "cancel". If I select "delete draft", it does nothing except to return me to the compose message screen. Is there a way for me to allow the user to return to the app after starting the compose mail function, but prior to sending it? Is there a way to add extra functionality to the "cancel" bar button to accomplish this?
Thanks in advance to all who reply.
You have to implement MFMessageComposeViewControllerDelegate with the - (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result method.
You will dismiss your message view in this method.
EDIT : i confused with MFMailComposeViewControllerDelegate but the purpose is the same as with MFMessageComposeViewControllerDelegate
Take a look at your own code in your ...didFinishWithResult: method:
case MFMailComposeResultCancelled:
emailLabel.text = #"Mail sending canceled.";
break;
case MFMailComposeResultSaved:
emailLabel.text = #"Mail saved.";
break;
case MFMailComposeResultSent:
{
emailLabel.text = #"Mail sent.";
NSLog(#"It's away!");
UIAlertView *emailAlertView = [[UIAlertView alloc] initWithTitle:#"Sent!" message:#"Mail sent successfully." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[emailAlertView show];
[self dismissModalViewControllerAnimated:YES];
[self.navigationController popViewControllerAnimated:YES];
}
When the result is MFMailComposeResultSent you're dismissing the modal view controller and popping the nav stack, which causes the mail compose view controller to go away, and also pops the stack to remove the view controller that presented the compose view controller. When the result is MFMailComposeResultCancelled, however, you just set some label's text. Same for MFMailComposeResultSaved. You need to dismiss the message compose view controller for these cases too if you want the compose view controller to go away when the user cancels or saves.
You should add this method in your view controller
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self becomeFirstResponder];
[self dismissViewControllerAnimated:YES completion:nil];
}
hope this one helps some one.
Set Delegate of MFMailComposeViewController
MFMailComposeViewController *mailcomposer = [[MFMailComposeViewController alloc]init];
mailcomposer.mailComposeDelegate = self;
And Use this Delegate Method
-(void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
My App got rejected and reason is below:-
Did not integrate with iOS features. For example, the email button should enable users to compose emails in the app rather than launching the Mail app.
I did not get that what they want. I have used MFMailComposer class so what's wrong with it?Any Suggestion.
Did you do it like this:
- (IBAction)pushMail:(id)sender { //A button that initiates composition
MFMailComposeViewController* controller = [[MFMailComposeViewController alloc] init];
controller.mailComposeDelegate = self;
[controller setSubject:#"My Mail Subject"];
if (controller) [self presentModalViewController:controller animated:YES];
[controller release];
}
- (void)mailComposeController:(MFMailComposeViewController*)controller
didFinishWithResult:(MFMailComposeResult)result
error:(NSError*)error;
{
if (result == MFMailComposeResultSent) {
NSLog(#"It's away!");
}
[self dismissModalViewControllerAnimated:YES];
}
I think you have to use an MSMailComposeViewController (as I have in the above example) to do what you want.
... the email button should enable users to compose emails in the app ...
They mean that your program should allow people to compose emails, instead of opening Mail.app.