I am using AFNetworking 2.0 to make network calls. I am using the code below for reachability. My problem is that the "Not connected" alert always shows when I open the app. It seems like it takes a while for the app to get connected to the network and that lag is causing the alert to pop up. Is there any way to fix this? I don't want the "Not connected" alert popping up every time and confusing users.
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
NSLog(#"Reachability: %#", AFStringFromNetworkReachabilityStatus(status));
switch (status) {
{case AFNetworkReachabilityStatusNotReachable:
NSLog(#"No Internet Connection");
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Not connected"
message:#"You have no network connection"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
}
break;
{case AFNetworkReachabilityStatusReachableViaWiFi:
NSLog(#"WIFI");
}
break;
{case AFNetworkReachabilityStatusReachableViaWWAN:
NSLog(#"4G");
}
break;
default:
NSLog(#"Unkown network status");
break;
}
}];
[[AFNetworkReachabilityManager sharedManager]startMonitoring];
if ([[AFNetworkReachabilityManager sharedManager] isReachable] == NO) {
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"Not connected"
message:#"You're not connected to the internet. Please connect via WiFi or data plan"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
//this shows all the time - why?
}
put this code in your AppDelegate in this method didFinishLaunchingWithOptions. it will display message only one time.
internetReachableFoo = [Reachability reachabilityWithHostname:#"www.google.com"];
internetReachableFoo.reachableBlock = ^(Reachability*reach)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Yayyy, we have the interwebs!");
});
};
internetReachableFoo.unreachableBlock = ^(Reachability*reach)
{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alrt=[[UIAlertView alloc]initWithTitle:#"Error" message:#"No Internet Connection\nPlease Check The Connection" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alrt show];
});
};
[internetReachableFoo startNotifier];
Because AFNetworkReachabilityManager refreshs its status by notification.
So when you call
[AFNetworkReachabilityManager sharedManager] isReachable]
after the startMonitoring immediately,the status is not get ready.
Related
In my app, it is very important to know whether SMS has been sent or not. For checking, I am using this delegate method:
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result{
switch (result) {
case MessageComposeResultCancelled: {
[NSThread detachNewThreadSelector:#selector(SMScancelled) toTarget:self withObject:nil];
}
break;
case MessageComposeResultSent: {
[NSThread detachNewThreadSelector:#selector(SMSsent) toTarget:self withObject:nil];
}
break;
case MessageComposeResultFailed: {
[NSThread detachNewThreadSelector:#selector(SMSfailed) toTarget:self withObject:nil];
}
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
My problem is, that when testing, I turn on Airplane mode in settings (to test what will happen) and then I am trying to send SMS (using my app). Naturally, iOS fails to send it and system informs me about that. In message app, it is also shown, that I have failed to send it. But delegate method still returns MessageComposeResultSent instead of MessageComposeResultFailed. This situation also happens when I test on another phone that has no SIM card.
I am testing this on iOS 7 and iOS 8.
In documentation, there is written, that MessageComposeResultSent means "The user successfully queued or sent the message". This means, behaviour I am expecting is correct.
So how to know, whether my last SMS has been succesfully sent, or that sending has failed?
You can verify if the device is allowed to send text message by using the canSendText method of the MFMessageComposeViewController.
Add this below code when you care sending the message (This method detects of your device does not support SMS)
if(![MFMessageComposeViewController canSendText]) {
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Your device doesn't support SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
return;
}
You can check Message failed by using delegate method of MFMessageComposeViewController
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
I am new in ios. i have develop a practice app, where i use rechability for network connection. but i have problem in that, when network is weak it shows the 'No network' message.
but i want in weak signal, it should access the internet within a 30sec timeout interval.
How Can i access the internet in weak signal within timeout interval.
I have tried the following:
-(BOOL)getInternetConnectionStatus
{
Reachability *objReachability = [Reachability reachabilityWithHostName:#"www.google.com"];
NetworkStatus internetStatus = [objReachability currentReachabilityStatus];
BOOL boolInternet;
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
boolInternet = NO;
}
else
{
boolInternet = YES;
}
return boolInternet;
}
-(IBAction)buttonClick:(id)sender
{
// call web service
if (![self getInternetConnectionStatus])
{
UIAlertView *alertMessage=[[UIAlertView alloc]initWithTitle:#"Alert" message:#"No Internet Connection" delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertMessage show];
return;
}
else
{
NSData *dataReply;
NSURLResponse *response;
NSError *error;
// create the request
NSString *urlString = [NSString stringWithFormat:#"http://Your link" ];
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:0.3];
// Make the connection
dataReply = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
if (response != nil)
{
NSLog(#"SNNetworkController.isHostAvailable %#", response);
UIAlertView *alertMessage=[[UIAlertView alloc]initWithTitle:#"Alert" message:#"Wel-Come" delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertMessage show];
}
else
{
// inform the user that the download could not be made
NSLog(#"SNNetworkController.isHostAvailable %# %#", response, error);
UIAlertView *alertMessage=[[UIAlertView alloc]initWithTitle:#"Alert" message:#"No Internet Connection" delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alertMessage show];
}
}
}
But it shows the message 'No Internet Connection' when signal is weak.
how can i shows the 'Wel-come' message within timeout when signal is weak.
Please give me the answer....
Thanks in advanced....!!!
Currently I am trying to send sms from a users phone through an app.
The idea is that the user selects the recipients of the message and then one by one the message is sent to each recipient.
Currently this is how I am doing it after a button is clicked this happens
if (self.abNumbersSelected.count > 0){
for(NSString *phoneNumber in self.abNumbersSelected)
{
if(self.currentController)
[self.currentController dismissViewControllerAnimated:YES completion:^{[self sendInviteMessage:phoneNumber];}
];
else
[self sendInviteMessage:phoneNumber];// message that invites selected message
}
}
abNumbersSelected is an array of numbers that the user has picked the sendInviteMessage is here:
- (void)sendInviteMessage:(NSString*)invitingNumber
{
//Invites the numbers using sms
//First checks if it duplicates it
if ([self checkDuplicate:invitingNumber]) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"Invalid Phone Number" message:#"The phone number you entered is not valid." delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[alertView show];
self.phoneField.text = #"";
}
//if not a duplicate then it sends the message
else {
if (SharedSessionManager.authToken) {
NSString* currentUserName = #"";
if (SharedSessionManager.currentUser.firstName && SharedSessionManager.currentUser.lastName) {
currentUserName = [NSString stringWithFormat:#"%# %#", SharedSessionManager.currentUser.firstName, SharedSessionManager.currentUser.lastName];
}
else if (SharedSessionManager.currentUser.firstName) {
currentUserName = SharedSessionManager.currentUser.firstName;
}
if (!customLoadingView.isLoading)
[customLoadingView beginLoading];
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
NSString *message = [NSString stringWithFormat:#"%# invited you to join Friendli - a mobile, location based social network. Join now at friendli.co",currentUserName];
controller.body = message;
controller.recipients = [NSArray arrayWithObjects:invitingNumber, nil];
controller.messageComposeDelegate = self;
controller.disableUserAttachments;
controller.title = #"Invite Friend";
self.currentController = controller;
[self presentModalViewController:self.currentController animated:YES];
}
}
}
}
Currently no message shows up to be sent.
Also here is the messageComposeViewController: method
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:nil];
}
In the log this is what is said when 2 recipients are picked and the button to trigger the MFMessageComposeViewController to be created is clicked by the user
2015-06-05 13:29:10:521 Friendli[241:807] [self.abNumbersSelected count]: 2
2015-06-05 13:29:11:638 Friendli[241:807] Reading auth token from keychain. (friendli.116.authtoken)
2015-06-05 13:29:11:643 Friendli[241:807] Reading auth token from keychain. (friendli.116.authtoken)
2015-06-05 13:29:12.869 Friendli[241:10525] Remote compose controller timed out (NO)!
- (void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult) result
{
switch (result) {
case MessageComposeResultCancelled:
break;
case MessageComposeResultFailed:
{
UIAlertView *warningAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to send SMS!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[warningAlert show];
break;
}
case MessageComposeResultSent:
break;
default:
break;
}
[self dismissViewControllerAnimated:YES completion:^{
if (self.abNumbersSelected.count > 0 && self.multipleRecipients) {
[self sendInviteMessage:[self.abNumbersSelected objectAtIndex:0]];
}
}];
}
In the didFinish method for the MFMessageComposeController in the dismiss statement using the if statement in the block of code the code will continue to create more MFMessageComposeViewControllers till it is done.
I'm using AFNetworking to determine whether the user has an internet connection. It returns false on both wifi and 4G LTE and I have checked to make sure they're operational.
I have the following code:
-(void)viewDidLoad{
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
if ([self connected])
[self doSomething];
else
[self noConnection];
}
- (BOOL)connected {
NSLog(#"This returns 0 %hhd", [AFNetworkReachabilityManager sharedManager].reachable);
return [AFNetworkReachabilityManager sharedManager].reachable;
}
-(void)noConnection{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Internet!"
message:#"Sorry, but you don't have an internet connection at this time. Please try again later."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
This is not a solution using AFNetworking but using sample code from apple
Once you have downloaded and imported Reachbility.m and Reachbility.h files
create a helper function:
-(BOOL)isConnected{
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return !(networkStatus == NotReachable);
}
Then use it
if([self isConnected]){
//connected!
}
else{
//not connected to internet!
}
Very important
If your project is not using arc
go to target >
Build Phase >
double click the Reachability file
add -fno-objc-arc
Hope this helps
I tried several solutions on this board but never successful. What I want is when the user click Buy Button, an UIAlertView with UIActivityIndicatorView appears waiting for the app accessing the app store. But I do not know where to dismiss this UIAlertView once the purchase is done. I know that to dismiss a UIAlertView, we use: [alert dismissWithClickedButtonIndex:-1 animated:YES];
So would you please help me answer two questions:
1) Is my code below OK or any other better to achieve it?
2) Where should I dismiss UIAlertView for all cases:
User accepts to purchase
User cancels to purchase
Purchase is not successful
Following is my code:
-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{
UIAlertView *alert;
for(SKPaymentTransaction *transaction in transactions){
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchasing:
alert = [[UIAlertView alloc]initWithTitle: #"In App Purchase" message: #"Processing your purchase..." delegate: nil cancelButtonTitle: nil otherButtonTitles: nil];
UIActivityIndicatorView *ind = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleWhiteLarge];
[ind startAnimating];
[alert addSubview: ind];
[alert show];
[ind release];
[alert release];
break;
case SKPaymentTransactionStatePurchased:
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:#"Complete"
message:#"You have bought the full version!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[tmp show];
[tmp release];
break;
case SKPaymentTransactionStateRestored:
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
if (transaction.error.code !=SKErrorPaymentCancelled) {
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
UIAlertView *tmp = [[UIAlertView alloc]
initWithTitle:#"Error"
message:#"Purchase not successful!"
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok", nil];
[tmp show];
[tmp release];
}
[[SKPaymentQueue defaultQueue]finishTransaction:transaction];
break;
}
}
}
Try add
case SKPaymentTransactionStatePurchased:
[alert dismissWithClickedButtonIndex:-1 animated:YES];
and
case SKPaymentTransactionStateFailed:
[alert dismissWithClickedButtonIndex:-1 animated:YES];