Rechability connection to internet - ios

I want to execute some code only, and only if I am connected to the internet:
//Reachability
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reachabilityChanged:)
name:kReachabilityChangedNotification
object:nil];
Reachability * reach = [Reachability reachabilityWithHostname:#"www.dropbox.com"];
reach.reachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"Block Says Reachable");
connect = #"yes";
});
};
reach.unreachableBlock = ^(Reachability * reachability)
{
dispatch_async(dispatch_get_main_queue(), ^{
connect = #"no";
});
};
[reach startNotifier];
//Reachability
if (connect == #"no") {
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"There is no internet connection. Please connect to the internet. If you are already connected, there might be a problem with our server. Try again in a moment." delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
} else if (titleSet == NULL){
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"Please select a group or create a new one" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
}else if (NavBar.topItem.title.length < 1){
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"Please select a group or create a new one" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
} else if (newmessagename.text.length < 4){
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:#"" message:#"Please give a name to your event that is at least 4 characters long" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles: nil];
[alert1 show];
}
It seems that the code is not executed in order. I think it is taking more time to check the Internet connection than it takes to execute the code. How can I fix this?
Please do not tell me to place the code directly in the parenthesis where connect = #"no"; is located.

The blocks aren't executed sequentially, they are executed asynchronously.
This means that you can't tell when the code inside the blocks is going to be called. The code using the block may finish and execute before the rest of your method (however this is unlikely, especially with Internet connections).
You should place your ifs in a method that is called at a valid time. This time is probably when you receive a response from your blocks, or, if my memory serves true, [reach startNotifier]; can notify you when there is a change in reachability status, this appears to be your reachabilityChanged: method:
-(void) reachabilityChanged:(id) parameter
{
//Query reachability and notify / cache as required.
}

Of course its not executed in order, the whole point of those methods is to stop the ui to freeze while you get your reachability response. Basically you set up the reachability responses and immediately ask for the result when nothing has been checked yet. What you have to really is to move it inside the brackets.
Something else that you can do is make a function with those results, and call this function in both of the blocks.
If you want to have this on the load of the viewcontroller or before you display anything else, then you either have to check for reachability before you show this controller, or add a "loading" screen.
EDIT: Something else that i dont understand is, those reachability methods seem to fire a block when they get the results, but you are registering for a notification as well. And i dont see you posting a notification for this. You are using 2 asynchronous approches here (blocks and notifications)

Related

Obtain an array with notifications

I am trying to put notifications in an array as they become available, but the count of the array is reset to 1 when I push a new notification.
This is the code:
int r = 0;
listMsgReceived = [[NSMutableArray alloc] init];
if (notification)
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Notification received" message:[NSString stringWithFormat:#"%#", message] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertView show];
[listMsgReceived insertObject:message atIndex:r];
r++;
NSLog(#"apres: %d \n", [listMsgReceived count]);
}
It looks like you are initializing the variables r and listMsgReceived each time your notification is received (though it's hard to tell from the context you provided).
You should not do that, because that gets you a new array each time, where you insert one object - hence the count will be one after each notification.
You could try moving your array initialization outside of your method; declare it as a property on your class and initialize it in the initializer.

Placeholders for variables in UIAlertView?

I want a UIAlertView to warn the user if there are no items matching his/her chosen search criteria. My initial idea was to use this code:
if (aOiCount == 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No instances of %#",self.thisSpec.activityOfInterest message:#"Please select an activity or Cancel" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
The idea being to slip an actual activity name into the title, like in an NSLog string.
Unfortunately, this doesn't work. Compiler tells me Expected ":"
Is it possible to use a variable like this, and if so, how?
Thanks!
call this line
#"No instances of %#",self.thisSpec.activityOfInterest
in one NSString
NSString *alertstr=[NSString stringWithFormat:#"No instances of %#",self.thisSpec.activityOfInterest];
after that call your UIAlertView and then rearrange the word delegate:nil into delegate:self
if (aOiCount == 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:alertStr message:#"Please select an activity or Cancel" delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
I don't think this is valid Objective C syntax:
initWithTitle:#"No instances of %#",self.thisSpec.activityOfInterest
You need to wrap it in an NSString, or a self-contained form.
Consider one of the many NSString methods, such as stringWithFormat or construct one in a different way. Either way, you should pass a complete string here.

iOS 7 UIWebView intercept alerts

In my app there's a UIWebView showing a web page. It sometimes displays errors in a UIAlertView that are really annoying. I would like to intercept this and show the errors in a more sophisticated way.
Is there a way where i can intercept the error message in a function and decide for myself what i want to do with it?
Thanks in advance!
This seems to do it:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
JSContext *ctx = [webView valueForKeyPath:#"documentView.webView.mainFrame.javaScriptContext"];
ctx[#"window"][#"alert"] = ^(JSValue *message) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"JavaScript Alert" message:[message toString] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
};
}
Note: only tested on iOS 8.

Test Connection over Wifi only iOS

I have a method implemented thats tests the internet connection in my iOS app. The problem is, I only want the method to test the internet connection over wifi, not cellular. How do I do that? :-) PS I'm using the latest version of Xcode & iOS 6.
NSURL *scriptUrl = [NSURL URLWithString:#"http://10.247.245.87/stores/test.html"];
NSData *data = [NSData dataWithContentsOfURL:scriptUrl];
if (data != nil){
UIAlertView *alert = [[UIAlertView alloc]initWithTitle: #"Success"
message: #"You're connected to the server"
delegate: self
cancelButtonTitle: #"Close"
otherButtonTitles:nil];
//Show Alert On The View
[alert show];
}
else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle: #"Connection Failed"
message: #"Please connect to network and try again"
delegate: self
cancelButtonTitle: #"Close"
otherButtonTitles:nil];
//Show Alert On The View
[alert show];
}
Have you looked into the Reachability class?
http://developer.apple.com/library/ios/#samplecode/Reachability/Introduction/Intro.html
It will probably provide you with a lot more flexibility and why roll your own if Apple has already done the work :) Hope this helps!
Check Tony Million Reachability class
There must be a isReachableViaWiFi method you can check wifi only
// allocate a reachability object
Reachability* reach = [Reachability reachabilityWithHostname:#"www.google.com"];
// tell the reachability that we DONT want to be reachable on 3G/EDGE/CDMA
reach.reachableOnWWAN = NO;
Have you looked at this similar question:
How to check for an active Internet connection on iOS or OSX?
The highest up voted question on that gives a github link to a neat workaround and shows you if the internet connection is active via wifi or WWAN (cellular)
AFNetworking providing facility to check network connectivity -
AFNetworkReachabilityManager.sharedManager().setReachabilityStatusChangeBlock { (status: AFNetworkReachabilityStatus) -> Void in
// check your connectivity...
}

Twitter.framework - twitterd session interrupted, restarting

Got a problem with the new Twitter.framework that I haven't been able to find a solution for yet.
Here is my code:
if ([TWTweetComposeViewController canSendTweet]){
TWTweetComposeViewController *twitter = [[TWTweetComposeViewController alloc] init];
[twitter addImage:tweetImage];
[twitter setInitialText:initalString];
[twitter addURL:url];
twitter.completionHandler = ^(TWTweetComposeViewControllerResult result) {
if (result == TWTweetComposeViewControllerResultDone) {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"Tweeted"
message:#"You successfully tweeted"
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
});
} else if (result == TWTweetComposeViewControllerResultCancelled) {
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:#"Twitter"
message:#"Tweet has been canceled"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
[alertView release];
});
}
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissModalViewControllerAnimated:YES];
});
};
[self presentViewController:twitter animated:YES completion:nil];
[twitter release];
}
Seems to be the standard way of implementing this although I made the addition of queuing the UI stuff on the main thread. The addImage, setInitialText and addURL parameters are all good. In, fact this works most of the time. The problem I am having is that occasionally when the TWTweetComposeViewController is alloc'd init the app freezes and I can see "twitterd session interrupted, restarting... " in the console. The app will hang sometimes for only a few seconds but more often it will hang for unreasonable amount of time (20 - 30 secs or more), I will get numerous of these messages and then the twitter controller will finally slide up. Occasionally, as well, it will just hang and never come back.
Was wondering it anybody has see this problem before or has any ideas on a solution to this problem?
Thanks in advance.
I never add these problems with the twitter view controller. I used my code pasted in this post: https://stackoverflow.com/questions/9314308/can-twtweetcomposeviewcontroller-tweet-sheet-rotate-to-landscape
You can try it, just change it to "self" when you dismiss or present in modal view, as I'm using a different view controller.

Resources