PKPaymentAuthorizationController delegate does not called - ios

I have NSObject class in that i need to show apple pay. So I am using PKPaymentAuthorizationController instead of PKPaymentAuthorizationViewController.
Apple pay sheet is displayed but delegate method does not called. How should i set delegate to my controller. My iOS version is above 11
Here is my code.
if ([PKPaymentAuthorizationController canMakePaymentsUsingNetworks:#[PKPaymentNetworkVisa, PKPaymentNetworkMasterCard, PKPaymentNetworkAmex]]) {
NSLog(#"Can make apple pay payment");
PKPaymentRequest *paymentRequest = [self paymentRequest:#"10"];
paymentContr = [[PKPaymentAuthorizationController alloc] initWithPaymentRequest:paymentRequest];
paymentContr.delegate = self; // here self is MyClass: NSObject
[paymentContr presentWithCompletion:^(BOOL success) {
NSLog(#"present");
}];
}

Related

Swift 3.0 GameCenter matchmaking keeps cancelling after matching (issue converting objective-c to swift)

I'm following the RayWenderlich GameCenter Tutorial: Raywend GameCenter Tutorial but I'm trying to convert it into Swift 3.0. Basically all it does is authenticate the local player, open the matchmaking interface, and then it should call the matchmakerViewController function once two players find each other. The player is successfully authenticated, and the matchmakerViewController is presented, and the players find each-other. However, after displaying the opponent that it found and putting the blue checkmark next to their name, the app calls matchmakerViewControllerWasCancelled instead of matchmakerViewController(viewController: GKMatchmakerViewController,didFindMatch match: GKMatch) This is weird to me since I'm pretty sure that method is only called based on user interaction (it's not calling the error method). Running the objective-c version of the project works, but my swift conversion has this problem. Here are the two versions of the findMatchWithMinPlayers() method. I'm assuming I converted something wrong here:
Swift
func findMatchWithMinPlayers(minPlayers: Int, maxPlayers: Int, viewController: UIViewController, delegate: GameKitHelperDelegate) {
if !enableGameCenter {
return
}
self.matchStarted = false
self.match = nil
self.delegate = delegate
viewController.dismiss(animated: false, completion: { _ in })
var request = GKMatchRequest()
request.minPlayers = minPlayers
request.maxPlayers = maxPlayers
var mmvc = GKMatchmakerViewController(matchRequest: request)
mmvc?.matchmakerDelegate = self
viewController.present(mmvc!, animated: true, completion: { _ in })
}
Objective-C
- (void)findMatchWithMinPlayers:(int)minPlayers maxPlayers:(int)maxPlayers
viewController:(UIViewController *)viewController
delegate:(id<GameKitHelperDelegate>)delegate {
if (!_enableGameCenter) return;
_matchStarted = NO;
self.match = nil;
_delegate = delegate;
[viewController dismissViewControllerAnimated:NO completion:nil];
GKMatchRequest *request = [[GKMatchRequest alloc] init];
request.minPlayers = minPlayers;
request.maxPlayers = maxPlayers;
GKMatchmakerViewController *mmvc =
[[GKMatchmakerViewController alloc] initWithMatchRequest:request];
mmvc.matchmakerDelegate = self;
[viewController presentViewController:mmvc animated:YES completion:nil];
}
The only other thing I can thing of that may have been different was this:
Objective-C
+ (instancetype)sharedGameKitHelper
{
static GameKitHelper *sharedGameKitHelper;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedGameKitHelper = [[GameKitHelper alloc] init];
});
return sharedGameKitHelper;
}
Swift
And instead I just used a global var called sharedGameKitHelper and anytime in the code where they used [GameKitHelper sharedGameKitHelper] I used sharedGameKitHelper. They described the purpose of that method as creating a "singleton object" of the GameKitHelper class.
If you find nothing wrong with those, here's a full Pastebin of both of my "GameKitHelper" classes, which contain all the GameKit code.
objectice-c swift I've checked every method multiple times and restarted the project from scratch, so I must have some hole in my knowledge of objective-c conversions. Thanks for any help you can give!

CTCallCenter doesn't update the currentCalls property after I set callEventHandler

I'm trying to see if there are any ongoing calls, but I'm having trouble with keeping an instance of CTCallCenter as a property. Here's basically what I'm doing now that I'm debugging (everything is in MyClass):
-(void)checkForCurrentCalls
{
CTCallCenter *newCenter = [[CTCallCenter alloc] init];
if (newCenter.currentCalls != nil)
{
NSLog(#"completely new call center says calls in progress:");
for (CTCall* call in newCenter.currentCalls) {
NSLog(call.callState);
}
}
if (self.callCenter.currentCalls != nil) {
NSLog(#"property-call center says calls in progress:");
for (CTCall* call in self.callCenter.currentCalls) {
NSLog(call.callState);
}
}
}
My self.callCenter is a #property (nonatomic, strong) CTCallCenter *callCenter;. It has synthesized setter and getter. It's initialized in MyClass' init method:
- (id)init
{
self = [super init];
if (self) {
self.callCenter = [[CTCallCenter alloc] init];
}
return self;
}
If I call another of my methods before checkForCurrentCalls, then my self.callCenter.currentCalls stops updating the way it should. More precisely, the phonecalls I make (to myself) just keep piling on, so that if I've dialed and hung up three phonecalls I get printouts of three CTCalls being in the "dialing" state. The newCenter works as expected.
All I have to do to break it is call this:
- (void)trackCallStateChanges
{
self.callCenter.callEventHandler = ^(CTCall *call)
{
};
}
I have come across answers that say that CTCallCenter has to be alloc-init'd on the main queue. I have since then taken care to only call my own init on the main queue, using dispatch_async from my app delegate:
dispatch_async(dispatch_get_main_queue(), ^{
self.myClass = [[MyClass alloc] init];
[self.myClass trackCallStateChanges];
}
My checkForCurrentCalls are later called in applicationWillEnterForeground.
I don't understand why just setting the callEventHandler-block breaks it.
Everything is tested on iphone 5 ios 7.1.2.
This has been reproduced in a new project. Filed a bug report on it.

Admob Interstitial isReady is False

I am trying to implement Admob Interstitial ads on ios.
Here is what I have so far, this is my first time ever touching objective-c so please be kind.
// Simple Admob Interstitial support for Monkey - IOS
// admobInterstitial.ios.h
#import "GADInterstitial.h"
class AdmobInterstitial {
// the kind of "singleton"
static AdmobInterstitial *_admob;
// the ad
GADInterstitial *_interstitialAd;
// ad Unit ID
NSString *adUnitId;
public:
AdmobInterstitial();
// creates an instance of the object and start the thread
static AdmobInterstitial *GetAdmobInterstitial(String adUnitId);
// displays the ad to the user if it is ready
void ShowAd();
};
// admobInterstitial.ios.cpp
AdmobInterstitial *AdmobInterstitial::_admob;
AdmobInterstitial::AdmobInterstitial():_interstitialAd(0) {
}
AdmobInterstitial *AdmobInterstitial::GetAdmobInterstitial(String adUnitId) {
if( !_admob ) _admob=new AdmobInterstitial();
_admob->adUnitId = adUnitId.ToNSString();
return _admob;
}
void AdmobInterstitial::ShowAd() {
// create ad (should this go here or earlier?)
_interstitialAd = [[GADInterstitial alloc] init];
if (_interstitialAd) {
_interstitialAd.adUnitID = adUnitId;
[_interstitialAd loadRequest:[GADRequest request]];
if (_interstitialAd.isReady) {
BBMonkeyAppDelegate *appDelegate=(BBMonkeyAppDelegate*)[[UIApplication sharedApplication] delegate];
UIViewController *rootViewController = appDelegate->viewController;
[_interstitialAd presentFromRootViewController:rootViewController];
}
}
}
I am calling ShowAd() in my game after a player dies and clicks the restart button.
Currently, _interstitialAd.isReady is not coming back as true.
This is the documentation I used to get started
https://developers.google.com/mobile-ads-sdk/docs/admob/advanced#ios
It says that "You may invoke loadRequest: at any time, however, you must wait for GADInterstitialDelegate's interstitialDidReceiveAd: to be called before displaying the creative."
I assume this is the problem I am running into. I think I am calling loadRequest before interstitialDidReceiveAd. However, the document doesn't show an example of how I would wait for this method to be called.
Can anyone help with this?
EDIT: Now works and shows the Ad the 1st time I call ShowAd(), however doesn't show the ad any time after the 1st time this function is called
// Simple Admob Interstitial support for Monkey - IOS
// admobInterstitial.ios.h
#import "GADInterstitial.h"
class AdmobInterstitial {
// the kind of "singleton"
static AdmobInterstitial *_admob;
// the ad
GADInterstitial *_interstitialAd;
// ad Unit ID
NSString *adUnitId;
void loadAd();
public:
AdmobInterstitial();
// creates an instance of the object and start the thread
static AdmobInterstitial *GetAdmobInterstitial(String adUnitId);
// displays the ad to the user if it is ready
void ShowAd();
};
// admobInterstitial.ios.cpp
AdmobInterstitial *AdmobInterstitial::_admob;
AdmobInterstitial::AdmobInterstitial():_interstitialAd(0) {
}
AdmobInterstitial *AdmobInterstitial::GetAdmobInterstitial(String adUnitId) {
if( !_admob ) _admob=new AdmobInterstitial();
_admob->adUnitId = adUnitId.ToNSString();
_admob->loadAd();
return _admob;
}
void AdmobInterstitial::loadAd() {
// testing
_interstitialAd = [[GADInterstitial alloc] init];
if (_interstitialAd) {
_interstitialAd.adUnitID = adUnitId;
[_interstitialAd loadRequest:[GADRequest request]];
}
// end testing
}
void AdmobInterstitial::ShowAd() {
// create ad (should this go here or earlier?)
//_interstitialAd = [[GADInterstitial alloc] init];
if (_interstitialAd) {
//_interstitialAd.adUnitID = adUnitId;
//[_interstitialAd loadRequest:[GADRequest request]];
if (_interstitialAd.isReady) {
BBMonkeyAppDelegate *appDelegate=(BBMonkeyAppDelegate*)[[UIApplication sharedApplication] delegate];
UIViewController *rootViewController = appDelegate->viewController;
[_interstitialAd presentFromRootViewController:rootViewController];
}
}
}
OK. Firstly isAdReady==false will occur when there is no ad available to show. Ie it is a natural condition. You can mitigate it by using mediation.
But in your case it is likely that no ad was available to show because there had no been enough time to send the ad request and receive a response before asking that question.
What you need to do is to call loadAd early. Ie when you game first starts. Then at a natural break point in your game (after the player dies) check is isAdReady is true, and if so show the ad.
When you show the ad or when the game starts up again, call loadAd again so that you will have an ad ready again the next time you want to show it.

Change SKProduct/SKPayment delegate

I implement in-app purchases. I put all methods to separate class IAPHelper and for some reasons I wish to have SKProductsRequestDelegate in other class. Is there any way to change delegate to my other class insted of IAPHelper?
if IAPHelper know the other class, sure :)
//In eg appDelegate
IAPHelper *helper = [[IAPHelper alloc] init];
helper.productsDelegate = self;
...
//in IAPHelper
-(void)setProductsHelper:(id)newHelper {
self.productsRequest = newHelper;
}
for example

How to programmatically send SMS on the iPhone?

Does anybody know if it's possible, and how, to programmatically send a SMS from the iPhone, with the official SDK / Cocoa Touch?
Restrictions
If you could send an SMS within a program on the iPhone, you'll be able to write games that spam people in the background. I'm sure you really want to have spams from your friends, "Try out this new game! It roxxers my boxxers, and yours will be too! roxxersboxxers.com!!!! If you sign up now you'll get 3,200 RB points!!"
Apple has restrictions for automated (or even partially automated) SMS and dialing operations. (Imagine if the game instead dialed 911 at a particular time of day)
Your best bet is to set up an intermediate server on the internet that uses an online SMS sending service and send the SMS via that route if you need complete automation. (ie, your program on the iPhone sends a UDP packet to your server, which sends the real SMS)
iOS 4 Update
iOS 4, however, now provides a viewController you can import into your application. You prepopulate the SMS fields, then the user can initiate the SMS send within the controller. Unlike using the "SMS:..." url format, this allows your application to stay open, and allows you to populate both the to and the body fields. You can even specify multiple recipients.
This prevents applications from sending automated SMS without the user explicitly aware of it. You still cannot send fully automated SMS from the iPhone itself, it requires some user interaction. But this at least allows you to populate everything, and avoids closing the application.
The MFMessageComposeViewController class is well documented, and tutorials show how easy it is to implement.
iOS 5 Update
iOS 5 includes messaging for iPod touch and iPad devices, so while I've not yet tested this myself, it may be that all iOS devices will be able to send SMS via MFMessageComposeViewController. If this is the case, then Apple is running an SMS server that sends messages on behalf of devices that don't have a cellular modem.
iOS 6 Update
No changes to this class.
iOS 7 Update
You can now check to see if the message medium you are using will accept a subject or attachments, and what kind of attachments it will accept. You can edit the subject and add attachments to the message, where the medium allows it.
iOS 8 Update
No changes to this class.
iOS 9 Update
No changes to this class.
iOS 10 Update
No changes to this class.
iOS 11 Update
No significant changes to this class
Limitations to this class
Keep in mind that this won't work on phones without iOS 4, and it won't work on the iPod touch or the iPad, except, perhaps, under iOS 5. You must either detect the device and iOS limitations prior to using this controller, or risk restricting your app to recently upgraded 3G, 3GS, and 4 iPhones.
However, an intermediate server that sends SMS will allow any and all of these iOS devices to send SMS as long as they have internet access, so it may still be a better solution for many applications. Alternately, use both, and only fall back to an online SMS service when the device doesn't support it.
Here is a tutorial which does exactly what you are looking for: the MFMessageComposeViewController.
http://blog.mugunthkumar.com/coding/iphone-tutorial-how-to-send-in-app-sms/
Essentially:
MFMessageComposeViewController *controller = [[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
controller.body = #"SMS message here";
controller.recipients = [NSArray arrayWithObjects:#"1(234)567-8910", nil];
controller.messageComposeDelegate = self;
[self presentModalViewController:controller animated:YES];
}
And a link to the docs.
https://developer.apple.com/documentation/messageui/mfmessagecomposeviewcontroller
You must add the MessageUI.framework to your Xcode project
Include an #import <MessageUI/MessageUI.h> in your header file
Add these delegates to your header file MFMessageComposeViewControllerDelegate & UINavigationControllerDelegate
In your IBAction method declare instance of MFMessageComposeViewController say messageInstance
To check whether your device can send text use [MFMessageComposeViewController canSendText] in an if condition, it'll return Yes/No
In the if condition do these:
First set body for your messageInstance as:
messageInstance.body = #"Hello from Shah";
Then decide the recipients for the message as:
messageInstance.recipients = [NSArray arrayWithObjects:#"12345678", #"87654321", nil];
Set a delegate to your messageInstance as:
messageInstance.messageComposeDelegate = self;
In the last line do this:
[self presentModalViewController:messageInstance animated:YES];
You can use a sms:[target phone number] URL to open the SMS application, but there are no indications on how to prefill a SMS body with text.
One of the systems of inter-process communication in MacOS is XPC. This system layer has been developed for inter-process communication based on the transfer of plist structures using libSystem and launchd. In fact, it is an interface that allows managing processes via the exchange of such structures as dictionaries. Due to heredity, iOS 5 possesses this mechanism as well.
You might already understand what I mean by this introduction. Yep, there are system services in iOS that include tools for XPC communication. And I want to exemplify the work with a daemon for SMS sending. However, it should be mentioned that this ability is fixed in iOS 6, but is relevant for iOS 5.0—5.1.1. Jailbreak, Private Framework, and other illegal tools are not required for its exploitation. Only the set of header files from the directory /usr/include/xpc/* are needed.
One of the elements for SMS sending in iOS is the system service com.apple.chatkit, the tasks of which include generation, management, and sending of short text messages. For the ease of control, it has the publicly available communication port com.apple.chatkit.clientcomposeserver.xpc. Using the XPC subsystem, you can generate and send messages without user's approval. 
Well, let's try to create a connection.
xpc_connection_t myConnection;
dispatch_queue_t queue = dispatch_queue_create("com.apple.chatkit.clientcomposeserver.xpc", DISPATCH_QUEUE_CONCURRENT);
myConnection = xpc_connection_create_mach_service("com.apple.chatkit.clientcomposeserver.xpc", queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
Now we have the XPC connection myConnection set to the service of SMS sending. However, XPC configuration provides for creation of suspended connections —we need to take one more step for the activation.
xpc_connection_set_event_handler(myConnection, ^(xpc_object_t event){
xpc_type_t xtype = xpc_get_type(event);
if(XPC_TYPE_ERROR == xtype)
{
NSLog(#"XPC sandbox connection error: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
}
// Always set an event handler. More on this later.
NSLog(#"Received a message event!");
});
xpc_connection_resume(myConnection);
The connection is activated. Right at this moment iOS 6 will display a message in the telephone log that this type of communication is forbidden. Now we need to generate a dictionary similar to xpc_dictionary with the data required for the message sending.
NSArray *recipient = [NSArray arrayWithObjects:#"+7 (90*) 000-00-00", nil];
NSData *ser_rec = [NSPropertyListSerialization dataWithPropertyList:recipient format:200 options:0 error:NULL];
xpc_object_t mydict = xpc_dictionary_create(0, 0, 0);
xpc_dictionary_set_int64(mydict, "message-type", 0);
xpc_dictionary_set_data(mydict, "recipients", [ser_rec bytes], [ser_rec length]);
xpc_dictionary_set_string(mydict, "text", "hello from your application!");
Little is left: send the message to the XPC port and make sure it is delivered.
xpc_connection_send_message(myConnection, mydict);
xpc_connection_send_barrier(myConnection, ^{
NSLog(#"The message has been successfully delivered");
});
That's all. SMS sent.
Add the MessageUI.Framework and use the following code
#import <MessageUI/MessageUI.h>
And then:
if ([MFMessageComposeViewController canSendText]) {
MFMessageComposeViewController *messageComposer =
[[MFMessageComposeViewController alloc] init];
NSString *message = #"Your Message here";
[messageComposer setBody:message];
messageComposer.messageComposeDelegate = self;
[self presentViewController:messageComposer animated:YES completion:nil];
}
and the delegate method -
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result {
[self dismissViewControllerAnimated:YES completion:nil];
}
You can use this approach:
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:#"sms:MobileNumber"]]
iOS will automatically navigate from your app to the messages app's message composing page. Since the URL's scheme starts with sms:, this is identified as a type that is recognized by the messages app and launches it.
Follow this procedures
1 .Add MessageUI.Framework to project
2 . Import #import <MessageUI/MessageUI.h> in .h file.
3 . Copy this code for sending message
if ([MFMessageComposeViewController canSendText]) {
MFMessageComposeViewController *messageComposer =
[[MFMessageComposeViewController alloc] init];
NSString *message = #"Message!!!";
[messageComposer setBody:message];
messageComposer.messageComposeDelegate = self;
[self presentViewController:messageComposer animated:YES completion:nil];
}
4 . Implement delegate method if you want to.
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{
///your stuff here
[self dismissViewControllerAnimated:YES completion:nil];
}
Run And GO!
//Add the Framework in .h file
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
//Set the delegate methods
UIViewController<UINavigationControllerDelegate,MFMessageComposeViewControllerDelegate>
//add the below code in .m file
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
MFMessageComposeViewController *controller =
[[[MFMessageComposeViewController alloc] init] autorelease];
if([MFMessageComposeViewController canSendText])
{
NSString *str= #"Hello";
controller.body = str;
controller.recipients = [NSArray arrayWithObjects:
#"", nil];
controller.delegate = self;
[self presentModalViewController:controller animated:YES];
}
}
- (void)messageComposeViewController:
(MFMessageComposeViewController *)controller
didFinishWithResult:(MessageComposeResult)result
{
switch (result)
{
case MessageComposeResultCancelled:
NSLog(#"Cancelled");
break;
case MessageComposeResultFailed:
NSLog(#"Failed");
break;
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissModalViewControllerAnimated:YES];
}
Here is the Swift version of code to send SMS in iOS. Please noted that it only works in real devices. Code tested in iOS 7+. You can read more here.
1) Create a new Class which inherits MFMessageComposeViewControllerDelegate and NSObject:
import Foundation
import MessageUI
class MessageComposer: NSObject, MFMessageComposeViewControllerDelegate {
// A wrapper function to indicate whether or not a text message can be sent from the user's device
func canSendText() -> Bool {
return MFMessageComposeViewController.canSendText()
}
// Configures and returns a MFMessageComposeViewController instance
func configuredMessageComposeViewController(textMessageRecipients:[String] ,textBody body:String) -> MFMessageComposeViewController {
let messageComposeVC = MFMessageComposeViewController()
messageComposeVC.messageComposeDelegate = self // Make sure to set this property to self, so that the controller can be dismissed!
messageComposeVC.recipients = textMessageRecipients
messageComposeVC.body = body
return messageComposeVC
}
// MFMessageComposeViewControllerDelegate callback - dismisses the view controller when the user is finished with it
func messageComposeViewController(controller: MFMessageComposeViewController!, didFinishWithResult result: MessageComposeResult) {
controller.dismissViewControllerAnimated(true, completion: nil)
}
}
2) How to use this class:
func openMessageComposerHelper(sender:AnyObject ,withIndexPath indexPath: NSIndexPath) {
var recipients = [String]()
//modify your recipients here
if (messageComposer.canSendText()) {
println("can send text")
// Obtain a configured MFMessageComposeViewController
let body = Utility.createInvitationMessageText()
let messageComposeVC = messageComposer.configuredMessageComposeViewController(recipients, textBody: body)
// Present the configured MFMessageComposeViewController instance
// Note that the dismissal of the VC will be handled by the messageComposer instance,
// since it implements the appropriate delegate call-back
presentViewController(messageComposeVC, animated: true, completion: nil)
} else {
// Let the user know if his/her device isn't able to send text messages
self.displayAlerViewWithTitle("Cannot Send Text Message", andMessage: "Your device is not able to send text messages.")
}
}
There is a class in iOS 4 which supports sending messages with body and recipents from your application. It works the same as sending mail. You can find the documentation here: link text
- (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSArray *)recipients
{
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
UIImage *ui =resultimg.image;
pasteboard.image = ui;
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"sms:"]];
}
//call method with name and number.
-(void)openMessageViewWithName:(NSString*)contactName withPhone:(NSString *)phone{
CTTelephonyNetworkInfo *networkInfo=[[CTTelephonyNetworkInfo alloc]init];
CTCarrier *carrier=networkInfo.subscriberCellularProvider;
NSString *Countrycode = carrier.isoCountryCode;
if ([Countrycode length]>0) //Check If Sim Inserted
{
[self sendSMS:msg recipientList:[NSMutableArray arrayWithObject:phone]];
}
else
{
[AlertHelper showAlert:#"Message" withMessage:#"No sim card inserted"];
}
}
//Method for sending message
- (void)sendSMS:(NSString *)bodyOfMessage recipientList:(NSMutableArray *)recipients{
MFMessageComposeViewController *controller1 = [[MFMessageComposeViewController alloc] init] ;
controller1 = [[MFMessageComposeViewController alloc] init] ;
if([MFMessageComposeViewController canSendText])
{
controller1.body = bodyOfMessage;
controller1.recipients = recipients;
controller1.messageComposeDelegate = self;
[self presentViewController:controller1 animated:YES completion:Nil];
}
}
If you want, you can use the private framework CoreTelephony which called CTMessageCenter class. There are a few methods to send sms.
Use this:
- (void)showSMSPicker
{
Class messageClass = (NSClassFromString(#"MFMessageComposeViewController"));
if (messageClass != nil) {
// Check whether the current device is configured for sending SMS messages
if ([messageClass canSendText]) {
[self displaySMSComposerSheet];
}
}
}
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
//feedbackMsg.hidden = NO;
// Notifies users about errors associated with the interface
switch (result)
{
case MessageComposeResultCancelled:
{
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"Message" message:#"SMS sending canceled!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert1 show];
[alert1 release];
}
// feedbackMsg.text = #"Result: SMS sending canceled";
break;
case MessageComposeResultSent:
{
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:#"Message" message:#"SMS sent!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert2 show];
[alert2 release];
}
// feedbackMsg.text = #"Result: SMS sent";
break;
case MessageComposeResultFailed:
{
UIAlertView *alert3 = [[UIAlertView alloc] initWithTitle:#"Message" message:#"SMS sending failed!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert3 show];
[alert3 release];
}
// feedbackMsg.text = #"Result: SMS sending failed";
break;
default:
{
UIAlertView *alert4 = [[UIAlertView alloc] initWithTitle:#"Message" message:#"SMS not sent!!!" delegate:self cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert4 show];
[alert4 release];
}
// feedbackMsg.text = #"Result: SMS not sent";
break;
}
[self dismissModalViewControllerAnimated: YES];
}
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:#"sms:number"]]
This would be the best and short way to do it.
You can present MFMessageComposeViewController, which can send SMS, but with user prompt(he taps send button). No way to do that without user permission. On iOS 11, you can make extension, that can be like filter for incoming messages , telling iOS either its spam or not. Nothing more with SMS cannot be done
You need to use the MFMessageComposeViewController if you want to show creating and sending the message in your own app.
Otherwise, you can use the sharedApplication method.

Resources