0

I'm currently developing an app in iOS which it is fully dependent on web service to get data from server through HTTP and display on the app. Therefore, the internet access for the app is the main concern to keep the app running smoothly. Also, if there is no internet access and when the app re-gain internet accessed, some of the content need to refresh by calling the web service.

Also, my company uses normal server which it is not as powerful as Google one, so sometimes it might have no responds or connection error returned to the app. My supervisor suggested right before calling every web service, the app should ping our server in order to check if our server is good to call for web services.

As my researched, iOS doesn't have any build-in method to ensure the device is gaining internet accessed, so that I used Reachability library by Tony Million to check if google.com is reachable in order to make sure there are internet connection, then I create a NSMutableURLRequest with 5 seconds time-out to try to connect to our server, if there are responds then only start the web service request.

Here is the pseudocode of my logic:

IF google.com is reachable
   IF ourserver.com is reachable
       Call the web service
   ELSE
       Prompt to user 'Server is busy, please try again later'
ELSE
   Prompt to user 'No internet accessed, please try again.'

this approach uses right before every web service called in the app, however, it makes action seem delayed or slow response, I guess it is cause by our server slow response.

To tackle the issue of refresh the content while the app re-gain internet access, I've found another library called AFNetworking which provides rich networking related functions to the app. I can use [[AFNetworkReachabilityManager sharedManager] startMonitoring]; and [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receiveNetworkChangeNotification:) name:AFNetworkingReachabilityDidChangeNotification object:nil]; to know the device has change of network state. However, this method is only know if the device is connected to a network or not, but it doesn't detect if the network has internet accessed. So I plan to put an internet accessed check by using Reachability I mention earlier to re-call the web service. And below is the pseudocode

Network Changed Called
    IF [AFNetworkReachabilityManager sharedManager].reachable]
        IF google.com is reachable
           IF ourserver.com is reachable
               Call the web service
           ELSE
               Prompt to user 'Server is busy, please try again later'
        ELSE
           Prompt to user 'No internet accessed, please try again.'
    ELSE
        Prompt to user 'No internet accessed, please turn on Wifi or 3G.'

However, this approach seem impractical due to it has to many checking and it seem affected the performance of the app. Also I was thinking is that a good way that we put a time-out checking to our server, because some users use 3G connection which it might takes time for the user to connect to our server, so it seem not a good approach. Some people suggested that AFNetworking reachability is good enough to check for the internet accessed, they are assuming that the device connected to network == internet accessed. So if the user really doesn't have internet accessed but they are connected to the network, the app should still proceed to call the web service and let it falls on the exception and prompt message accordingly.

Can anyone here give me some suggestion or direction of the best practice to called web service from mobile to deal with the problem I had? Thanks in advanced and appreciate it.

Wai Hong
  • 175
  • 2
  • 11

2 Answers2

1

You ask a lot of good questions, but not simple to answer here without writing a full article. There's a great video here: https://realm.io/news/tmi-active-internet-connection-ios/ and a few good StackOverflow articles here you should check out: Easiest way to detect Internet connection on iOS?, How to check for an active Internet connection on iOS or OSX?.

Community
  • 1
  • 1
xdeleon
  • 769
  • 8
  • 20
  • The first link you given is informative and pointed out that `Reachability` shouldn't be used to check the internet connection at all, and the app should try to execute the NSURLRequest and let it catch the exception, this solution is more clean and makes more sense as well as improve the performance of the app. I've try to use google chrome to open a website under the environment that network is connected, but without internet connection, chrome did took like 10 seconds+ to show the error page, so I guess same concept applies the app should be acceptable to the user – Wai Hong Dec 10 '15 at 03:58
  • and more importantly, I showed your link to my supervisor and am able to convinced him that this approach is more practical. Thanks for the answer. – Wai Hong Dec 10 '15 at 04:01
0

Keep in mind, pinging google while in mainland china will just timeout. Perhaps ping a server from Apple etc which is available more widely. Also, while you are waiting for the google/baidu packet to come back, you might as well already try sending something to your server too. While processing, as soon as the one comes from your server, you can discard the one from google etc.

Finally, you can set up a service on a free high availability cloud system like google or amazon AWS that regularly monitors if your site is up and just ping that. Then you wouldnt have to bother with those extra steps while using only tiny amount of data on the free cloud service. You could even have the cloud based system cache a little bit of data

  • the app is only running in my country locally, which I can surf google anywhere from my country, but thanks for the tips, will keep in mind for my upcoming project which running globally. Also, thanks for the advise of cloud system, will check it out while I'm available to do R&D on that – Wai Hong Dec 30 '15 at 02:35