Home/Uncategorized/Checking for an internet connection on mobile devices with Delphi XE5

Checking for an internet connection on mobile devices with Delphi XE5

Views:
478

UPDATE (April 13th, 2015): I’ve added a separate download for a 64 bit version of libReachability.a. This file is untested as I do not have regular access to a 64 bit iOS device.

UPDATE: The project has been updated to include retrieving the current SSID (that the device is connected to). For Android, this means adding the Access Wifi State permission. Refer to the updated text in the article.

It’s a question that has been asked a few times in the Embarcadero forums: how to check if a mobile device (either Android or iOS) has an internet connection.

I already knew of a solution for iOS, and recently I came across one for Android, so I figured I would combine the two and create a platform-independent unit, called NetworkState. In that unit, I created an abstract class that could be derived from in other units that would provide the implementation for each platform, i.e. Android and iOS. The declaration for the abstract class TCustomNetworkState looks like this:

TCustomNetworkState = class(TObject)
  function GetSSID: String; virtual; abstract;
  function IsConnected: Boolean; virtual; abstract;
  function IsWifiConnected: Boolean; virtual; abstract;
  function IsMobileConnected: Boolean; virtual; abstract;
end;

As can be seen, the intention is to simply provide functions for checking if either there is a connection at all, and specifically whether there is either a Wifi or Mobile (Cellular data) connection, and what the SSID is. It was also the intention that the implementation use the supported methods for checking for connections, rather than say, using the Indy components.

The units NetworkState.iOS and NetworkState.Android each declare TPlatformNetworkState that provide the actual implementation, and the implementation uses clause of NetworkState is appropriately IFDEF’d for each platform so that the actual instance that is created is the one for the specific platform being compiled for.

I’ve included a demo project below that includes all the necessary files. If you’re going to use TNetworkState in your own project, make sure the files:

libReachability.a
NetworkState.pas
NetworkState.iOS.pas
NetworkState.Android.pas
SCNetworkReachability.pas
CaptiveNetwork.pas

are either in your project directory or in the compiler search path. Bear in mind that for the Android platform you’ll need to include the Access Network State, and Access Wifi State permissions in the project options:

For iOS on the device, you’ll need to add the SystemConfiguration framework in the SDK manager. Please refer to this article, and instead of CoreBluetooth (as per the 2nd image), use SystemConfiguration.

By | 2017-02-16T18:02:36+00:00 November 9, 2013 10:47 am|Uncategorized|85 Comments

About the Author:

85 Comments

  1. Rene November 11, 2013 at 12:18 am - Reply

    Excellent, I was looking for it.

    Thank you.

  2. Misha Oumantsev November 15, 2013 at 4:29 am - Reply

    I have downloaded your example. When I try to compile it for IOS Device, I get this error
    [DCC Error] E2597 ld: file not found: /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration

    Thank you.

    • admin November 15, 2013 at 5:25 am - Reply

      My apologies; I had meant to include the instructions for adding SystemConfiguration to the SDK manager. I’ve updated the article with additional instructions at the end.

      • Misha Oumantsev November 15, 2013 at 7:23 am - Reply

        Did exactly what is in that article, but still have the same error. I can see the SystemConfiguration framework in the list along with other frameworks. I was also trying to play with libSystemConfiguration path in SCNetworkReachability.pas, but it did not help.
        Your help is very appreciated. You contact me by email, I can provide a screenshot.

        • Misha Oumantsev November 15, 2013 at 8:02 am - Reply

          I realized, that I missed the last step in adding the framework. I forgot to click Update Local File Cache button. It works now. Thank you for your help.

  3. Willem November 16, 2013 at 12:06 am - Reply

    LINK ERROR when compiling for iOS
    ======================
    I also already has a solution for iOS in XCode (reachability) but I just bought XE5 and thought let’s try it cross-platform 🙂

    I dowloaded your code and ran it on an android device – works like a charm!
    I selected my iPhone and ran again – link error
    [DCC Error] E2597 ld: file not found: /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration

    Maybe there is something I’m not quite getting, but this file does exist on my iMac and is an alias for:
    /System/Library/Frameworks/SystemConfiguration.framework/Versions/A/SystemConfiguration

    Delphi is running on another iMac running Windows 7 which connects to the other iMac running paserver
    (I am able to compile and run other programs on the iPhone with this setup)

    Any idea how to fix this?

    • Willem November 16, 2013 at 12:17 am - Reply

      Never mind, I just refreshed the page I left open last night 🙂 and found the answer!

      It works now, thank you very much for such a fast response!

  4. Robin November 20, 2013 at 6:46 pm - Reply

    Hi, thanks you very much !
    But I have a problem to compil it 🙁

    [DCC Fatal Error] CaptiveNetwork.pas(6): F1026 Fichier introuvable : ‘C:\Users\Retwas\Documents\RAD Studio\Projets\whisky\Macapi.CoreFoundation.dcu’ (la portée d’unité “Macapi” indique seulement OSX32)

    What’s the problem ? Thanks

  5. Daniel Magin November 28, 2013 at 11:09 pm - Reply

    Nice code nut it helps only to know you are connected to a net. it can be also a intranet without internet connection or what ever. so i prefer this simple code.

    function TdmMain.CheckInternet: boolean;
    begin
    result:=false;
    try
    IdTCPClient1.ReadTimeout:=2000;
    IdTCPClient1.ConnectTimeout:=2000;
    IdTCPClient1.Port:=80;
    IdTCPClient1.Host:=’google.de’;
    IdTCPClient1.Connect;
    IdTCPClient1.Disconnect;
    result:=true;
    except
    result:=false;
    end;
    end;

    • Francisco May 26, 2015 at 9:59 am - Reply

      here you will see a comment why you don’t want use that code:
      http://www.fmxexpress.com/must-have-check-network-connectivity-state-library-for-delphi-xe8-firemonkey-on-android-and-ios/

      so be aware and use asych connection in separate thread. An example of would be great! any?

      • admin May 26, 2015 at 10:13 am - Reply

        Daniel is referring to his example; not mine. Calling the network state check in iOS returns immediately, so shouldn’t cause any issues.

        Daniel’s method actually attempts to make a network connection, so it should be contained in a thread to prevent the iOS app from closing if the call takes too long. I’ll write an article on how to achieve this and post it soon.

  6. jordan December 11, 2013 at 2:45 am - Reply

    Does this code not work for the iOS simulator ? Error reads : ‘ Objective C class Reachability can not be found’ . This is straight from the demo project

    • bytearts February 23, 2014 at 6:38 am - Reply

      I have the exact same issue (“Objective C class Reachability can not be found”) when running on iOS simulator AND on iPhone . Could it be a problem with the iOS version? I am using iOS7, XE5 Update 2.

  7. Thierry December 11, 2013 at 11:44 am - Reply

    Thanks so much that was really usefull for us. I would love to discuss with you some business opportunity.

    • admin December 16, 2013 at 11:46 am - Reply

      I’ve sent you an email.

  8. Eli December 17, 2013 at 6:42 am - Reply

    With XE5 Update 2 and iPhoneOS 7.0.3 SDK I get this error (worked fine with XE5 Update 1):

    [DCC Hint] H2596 ld: warning: unknown dwarf DW_FORM_strp (offset=0xFFFFCF2C) is too big in libReachability.a(Reachability.o)

    Any ideas? I might need to update my local file cache for the iOS SDK.

    • admin December 17, 2013 at 7:39 am - Reply

      That’s a hint; not an error. Have you tried running it? It works fine for me.

      If you’re unable to run it due to a compiler error, try right-clicking the project in the project manager, click “Clean”, then right-click and “Build”. You may still receive the hint, but it should run OK.

  9. Eli December 31, 2013 at 3:33 pm - Reply

    I did get it running thanks. It was some other linker problem with the project file after installing Update 2 that was keeping it from running. A new project file took care of the issue.

  10. […] Head over and download the class and demo for NetworkState. […]

  11. Davor January 25, 2014 at 9:05 am - Reply

    Is there any way to implement NFC?

  12. Delphi April 22, 2014 at 6:54 am - Reply

    I’m using Delphi XE5 and the network API works fine when running on android, but just crashes on iOS 5.1.1. The application just shuts down when trying to retrieve info. Any idea why or how to troubleshoot?
    Thanks!

    • admin April 22, 2014 at 8:50 am - Reply

      Have you run it via the debugger to see where the crash occurs?

      I’m yet to test it with iOS 5.1.1. I may have time to do so sometime this week.

  13. Cleber June 4, 2014 at 2:27 am - Reply

    I wonder if it is to enable or disable WIFI and not only check the status.
    Thank you.

    • admin June 4, 2014 at 7:52 am - Reply

      As it stands, just to check the status. I can look into enabling/disabling the wi-fi

  14. sensor October 3, 2014 at 1:24 pm - Reply

    I test your demo, andriod is OK, but ios is not OK. the errmessage is [DCC Error] E2597 ld: file not found: /System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration
    I have do step by step as http://delphi.radsoft.com.au/2013/10/adding-other-ios-frameworks-to-the-sdk-manager/

    when i update local file Cache, the error message is Directory does not exist: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/usr/include/

    I use delphi XE7 and Xcode 6 for IOS 7.1

    I do’t know how to do now ? thank you ! I am from china,
    I am poor in english. I hope your Email reply.

    • admin October 14, 2014 at 6:28 pm - Reply

      I’m about to start checking out XE7, so I’ll revisit this article, thanks!

  15. […] Heute, 17:18 Sowas wie das hier? http://delphi.radsoft.com.au/2013/11…th-delphi-xe5/ Kaum macht man's richtig – schon funktioniert's Nachdenkliche Menschen denken oft warum sie […]

  16. Veeresh October 17, 2014 at 12:05 am - Reply

    While running this code in XE7 it is giving access violation error. Can you please look into this ?

    • admin October 17, 2014 at 8:07 am - Reply

      It would help to have more information, such as which platform you are targeting (i.e. iOS or Android), and exactly where the error occurs.

      • djnacho February 16, 2015 at 8:21 am - Reply

        Some devices (as LG G Pad 7, for example) show the Access Viotation Exception.
        I don’t know why, but if you use IsWifiConnected or IsMobileConnected in those devices, the exception is raised (IsConnected don’t raise the exception).
        If you could explain why is happing this, and the solution, i would thank you very much.
        Cheers 🙂

        • admin February 17, 2015 at 10:25 am - Reply

          I don’t have an LG G Pad 7, so I’m unable to check; sorry.

  17. Brian October 19, 2014 at 6:57 am - Reply

    Hi
    I have XE7 and also have the same issue as noted about the missing directory when trying to get the bluetooth api
    I seem to recall something along the lines that bluetooth support is better in xe7 anyway though so maybe does not sepecificly need the api?
    (but I may be talking through a hole in my head too here)
    Thanks!

    • admin October 19, 2014 at 2:18 pm - Reply

      If you’re referring to the reference to adding a new framework in the SDK manager, note that I specifically mention to replace “CoreBluetooth” with “SystemFramework”

      • Brian October 20, 2014 at 4:14 am - Reply

        Hi
        I still get error about missing folder with updating local file cache in SDK manager if I set to use SystemFramework instead of CoreBluetooth
        (and so means get compile error with XE7 with the networkstate.pas about file not found systemconfiguration etc
        You have XE7 now, have got it to work?
        thanks!

        • admin October 20, 2014 at 6:39 am - Reply

          What’s the missing folder error message? Please provide the *exact* message.

          Yes, I have it compiling in XE7, however my iPhone isn’t working so I’m unable to test it. As far as I can recall, it doesn’t work in the simulator because the Reachability class is not included in the framework in the simulator (though as I mentioned, it will still compile)

          • Brian October 20, 2014 at 7:21 am

            copy /paste does not seem to work
            but its the same missing folder (on the Mac side) error for when doing the local file update
            that others have already mentioned
            what xcode version and iOS version have got it to work with?

          • admin October 20, 2014 at 9:28 am

            I have Xcode 6.0.1. This release has iOS 7.1 SDK for the simulator only, which is what I was targetting when I compiled. It has iOS 8.0 SDK for the simulator and device, however there’s changes that need to be made in order for it to compile. I’m starting a new article to cover this, so keep any eye out for it.

          • Brian October 20, 2014 at 10:34 am

            Hi
            Ok.thanks for help so far 🙂
            Just to note, I am targetting Apple store (i.e device), as using Macincloud

  18. Adriano Santos January 23, 2015 at 9:58 pm - Reply

    Hello, I can compile in Delphi XE7, but when the app runs on iOS Simulator with 8.1 I get an error ObjectiveC reachability class could not be found

    • admin January 23, 2015 at 10:27 pm - Reply

      It doesn’t work with the simulator; only with the device

  19. Warquia Pereira January 29, 2015 at 11:18 pm - Reply

    Bom dia, onde posso fazer o download do exemplo?
    thank you!

    • Warquia Pereira January 30, 2015 at 5:28 am - Reply

      Hello, where can I download the example?
      thank you!

      • admin February 12, 2015 at 7:12 am - Reply

        My download manager was broken. It’s back again now 🙂

    • admin February 12, 2015 at 7:12 am - Reply

      Mi gestor de descargas se rompió. Es volver de nuevo ahora 🙂

  20. Daniel January 31, 2015 at 2:53 am - Reply

    I’d like to see your demo. Where is its link to download?

    • admin February 12, 2015 at 7:11 am - Reply

      My download manager was broken. It’s back again now 🙂

  21. Naoki February 3, 2015 at 10:27 am - Reply

    Where can I get the demo program(source code)? I can’t find the link to it.

    • admin February 12, 2015 at 7:11 am - Reply

      My download manager was broken. It’s back again now 🙂

  22. Alex Egorov February 11, 2015 at 11:59 pm - Reply

    How I can download this sample? Can’t found any download link 🙁

    • admin February 12, 2015 at 7:10 am - Reply

      My download manager was broken. It’s back again now 🙂

      • Alex Egorov February 12, 2015 at 6:14 pm - Reply

        Thanks for the link,
        About Delphi XE7 support: should be added to the uses list this unit – Androidapi.Helpers, SharedActivityContext is moved from FMX.Helpers.Android to this unit for XE7

  23. tefsoft February 13, 2015 at 6:53 pm - Reply

    getIpAddress Why Int?

    cast 127.0.0.1 string?

  24. Ratan February 16, 2015 at 5:42 pm - Reply

    hey I am using XE7.
    and I use your code to check network state,WiFi state in android.
    It work Nice.
    But How I check Whether Internet is available or Not while connected to WiFi in Android.

  25. Mauricio April 11, 2015 at 7:19 am - Reply

    Hi, i tested the code XE8 IOS32 bit and is working, but on IOS64 bit i get an error on libReachability.a, i guess that we need the 64 bit version of this library, do you have any idea of how to get it?
    Thank you

    • admin April 11, 2015 at 11:49 am - Reply

      You’ll need to build a new libReachability.a in Xcode. I’m yet to do this myself, however this page may help for now:

      http://code.tutsplus.com/tutorials/ios-sdk-detecting-network-changes-with-reachability–mobile-18299

      I may be able to work it out over the next couple of days or so.

    • admin April 13, 2015 at 9:35 am - Reply

      I’ve now added a link to download a 64 bit version of libReachability.a (see the article contents). I’m yet to be able to test it though, as I don’t have regular access to a 64 bit iOS device.

      • Pieter Bas April 13, 2015 at 7:21 pm - Reply

        You’re great! Was just looking for a 64-bit solution for iOS 32/64bit deployment

        • admin April 13, 2015 at 7:38 pm - Reply

          Thanks, Peter. I assume it works, then? I’m yet to test it myself.

  26. Freddie Bell April 29, 2015 at 8:29 pm - Reply

    I tested this on an Android – compiled with XE7 once Androidapi.Helpers had been added to the Networkstate.Android.pas to obviate the SharedActivityContext error), and it works beautifully!

  27. […] Head over and download the network state component library for checking the internet connection in D… […]

  28. Brian May 12, 2015 at 1:51 pm - Reply

    Hi
    I was able to add the framework using the new way in XE8 now
    great
    and it compiled OK
    re the 64 bit libReachability.a file
    one problem is, there is no option to add 64bit iOS in the compiler for some reason with the demo test project?

    • admin May 12, 2015 at 2:53 pm - Reply

      Make sure you add the iOS Device – 64 bit SDK in the SDK Manager (Tools|Options|Environment Options\SDK Manager)

      • Brian May 12, 2015 at 4:59 pm - Reply

        Hi
        thats already there
        you have to create a new project (then copy across the source code/objects) in XE8 so as to be able to have 64 bit iOS as a target listed
        (unless there is some other work around)

        • admin May 12, 2015 at 7:50 pm - Reply

          Weird thing is: I didn’t have to create a new project. I just re-opened in XE8. Mind you, I may have opened it in XE6 and XE7 previously 🙂

  29. Brian May 12, 2015 at 1:55 pm - Reply

    I am thinking that I would need to start a new project so as XE8 can then add in 64 bit option , come to think of it

  30. […] NetworkState(一个检查网络连接状态的组件) […]

  31. Rock July 20, 2015 at 9:36 pm - Reply

    Hello,
    How I know wheather connection is intranet or internet in wifi state..?
    Please Help..

  32. John July 21, 2015 at 1:39 am - Reply

    Works like a charm. The tip on adding SystemConfiguration Framework was great too! Thanks.

    64 bit version of libReachability is causing a compile time error on XE8 Update 1. The 32 bit version works OK. The error message is:
    [DCC Error] E2597 NYI lto::isObjectFile
    NYI lto::archName
    ld: file was built for archive which is not the architecture being linked (arm64): libReachability.a for architecture arm64

    It did a lipo -info on the 64 bit libReachability.a, and the result (“Architectures in the fat file: libReachability.a are: armv7 arm64”) doesn’t indicate anything abnormal.

    It should be noted that it works OK for another team member who is using XE8 without the Update 1. I wonder if the error I am getting is somehow related to the Update 1. Any thoughts on how to fix it?

  33. john July 21, 2015 at 3:30 am - Reply

    Please disregard my last comment which was about getting a compile time error E2597 in XE8 update 1 when choosing iOS 64 as target. It was traced back to having a 32 bit file lying around in the project directory. Thx.

  34. […] Checking for an internet connection on mobile devices with Delphi XE5 […]

  35. Jan Blomqvist August 22, 2015 at 6:40 pm - Reply

    On Delphi XE8 upd1, I get this error when compiling for Android:
    [DCC Error] NetworkState.Android.pas(115): E2003 Undeclared identifier: ‘SharedActivityContext’
    and then:
    [DCC Error] NetworkState.Android.pas(148): E2003 Undeclared identifier: ‘JStringToString’

    Using: Android SDK 24.0.2 32-bit

    Is there something that has changed in the Android SDK and must be changed in this source code?

  36. Jan Blomqvist August 22, 2015 at 6:49 pm - Reply

    Sorry, should have searched around first. With XE7 and later change FMX.Helpers.Android to Androidapi.Helpers;

    See: http://stackoverflow.com/questions/25981458/in-which-uses-can-i-find-sharedactivitycontext

    Now it run successfully on my Android.

  37. Kelver Merlotti November 13, 2015 at 9:55 pm - Reply

    Do you already implemented or know who did the MacOS Reachability wrapper to test Internet Connection on Mac OS-X?

    Cheers,
    KM

  38. Rock November 25, 2015 at 2:47 pm - Reply

    Is it possible to get event when wifi interface is enabled or disabled.

  39. Guilherme Augusto December 15, 2016 at 2:25 pm - Reply

    Good night, Dave.
    These classes work for detection but have a fault.
    It happened here with me now that I have the local network running but my internet is not reaching the router.
    It detects that I am connected to the Router but can not see that I am out of the internet.
    Take a test there to stay without IP WAN (no internet coming but normal working network) and see what I’m saying …
    Good job in the classes.
    Best regards,
    Guilherme Augusto

    • admin December 15, 2016 at 3:02 pm - Reply

      I suspected that might be an issue, given what else I have read, and from other comments.

      I’m planning to revisit this issue, and others, very soon.

  40. Guilherme Augusto December 16, 2016 at 6:08 am - Reply

    It’s all right.
    The intention is precisely to try to improve the great solution that has created.
    Thank you for your attention and response.
    Have great parties and the end of the year.
    Best Regards,
    Guilherme Augusto

  41. mmparodyMartin Parody May 6, 2017 at 1:36 pm - Reply

    How can I enable javascript in TWebView (WebView) for Delphi Berlin?

Leave a Reply

Show Buttons
Hide Buttons