0

I'm having some issues determining what the proper application design pattern is for initially alerting users that they need to enable an internet connection.

I have an iOS app that requires an internet connection due to the wide range of data that a user could request. The app has a couple tab bar controllers within which there are navigation controllers that take users through a variety of views based on hierarchy and returned data. All requests are made asynchronously using ASIHTTPRequest using NSNotificationCenter observers that wait for a central api request class to either complete the request or report an error. In most cases a user will have downloaded at least the first requests, but I can always ask them to enable their connection in a UIAlertView and then return them to that lower level by popping other nav controller levels off of the stack if they aren't connected. Overall the application works great.

However, if a user was to first open the application with their connection disabled I am running into issues. Often my initial subviews (which are IBoutlets for ease of creating the tab-bar/navigation hierarchy) will have attempted to load before I could possibly test for the existence of a connection. I'm not sure if maybe the correct way to do this is to create a timeout in my app delegate before other things load somehow, or make an initial test request that doesn't actually retrieve any crucial data (since it seems it's nearly impossible, or at least impractical to completely re-initialize a view from scratch without being its delegate).

Does anybody have any simple method that they use to accomplish this at the application initialization stage? I feel like I must be missing something obvious since the rest of this has been so straightforward.

If someone wants me to post code I could, however I'm pretty sure this is primarily an architecture question. Also please keep in mind I would rather use observers that delegates in most cases due to the intentionally loosely coupled nature of my app.

I greatly appreciate any input on this.

Project707
  • 482
  • 6
  • 13

3 Answers3

1

As you suggest, it sounds like an architecture problem.

I think the timeout solution is iffy at best because the whole loading process is nondeterministic. I don't know what views you are populating with the data you are loading asynchronously; but let's say it's a UITableView for the sake of discussion. When the view first loads, there will be no data; but if a connection is available, you will asynchronously populate the table via ASIHTTPRequest callbacks.

An example:

[[CCFConnectionManager sharedManager] countScenariosForScenarioID:lwScenario.uniqueID
                                                                groupCode:groupCode
                                                        completionHandler:^(NSInteger count) {
                                                            lwScenario.completionCount = count;
                                                            dispatch_async(dispatch_get_main_queue(), ^{
                                                                [[self tableView] reloadData];
                                                            });

So in the completion handler, I update the model and send [[self tableView] reloadData]. The latter on the main thread. HTH.

FluffulousChimp
  • 9,129
  • 3
  • 32
  • 41
  • Sorry if I'm just being obtuse but I'm not clear on how this solves the question. This seems to solve the problem of asynchronous loading but it sounds like that part of the implementation is already working. What the questioner needs to know is how to determine the presence of a network connection. To clarify is your suggestion to try to load what you need a startup and if it fails then tell the user to check their connection? – Mattia Oct 11 '11 at 11:14
  • 1
    I re-read the OP, and agree with you. Perhaps checking `Reachability`, then – FluffulousChimp Oct 11 '11 at 11:42
  • I guess one issue is that I normally have some timed animations and things on initial load that actually use the initially requested data. I dont mind skipping them or waiting until the user has enabled their network connection to do them, but the thing is it's not as simple as just reloading table data ( which I do in other cases as I use a single dynamically populated tableview). I think it's ideally more about stopping the app from continuing to execute until the app is reachable rather than how to detect reachability which I can do with an initial request that I already have in place. – Project707 Oct 11 '11 at 16:24
  • Initially I was catching the lack of connection in the app delegate, and then trying to remove and re-create my tableview in my first tab, but I didn't seem to be able to access it reliably, but maybe I just need to continue with that method. – Project707 Oct 11 '11 at 16:34
0

I ended up using more notifications to do this:

I call my api request class from my app delegate with a "test request" and then listen for it in the app delegate as well. If the app delegate observes a successful response, it starts another request for which my active view controller is the observer. The object passed along contains the data the receiving controller needs to reload its view.

I think next time I need to plan my delegation a little bit better to do away with some of the notifications. However, with an application like this where the same class is used dynamically and can receive multiple sets of data or where the data can be intended for a different context, notifications do make some sense I suppose.

Project707
  • 482
  • 6
  • 13
0
-(BOOL)isConnected{
BOOL connected;
const char *host = "www.google.com";
SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(NULL, host);
SCNetworkReachabilityFlags flags;
connected = SCNetworkReachabilityGetFlags(reachability, &flags);
BOOL isConnected = connected && (flags & kSCNetworkFlagsReachable) && !(flags & kSCNetworkFlagsConnectionRequired);
CFRelease(reachability);
return isConnected;}

this method add in app delegate.

Gaurav Patel
  • 967
  • 1
  • 6
  • 16
  • As far as I know all that does is test whether or not the device has an active internet connection. The question was really about the proper way to handle the loading of the application and views in the event that there is no connection. – Project707 Jan 08 '12 at 01:17