iOS Question B4A & B4I detect if the internet is connected and if it is wifi or cellular network

Sergio Haurat

Active Member
Licensed User
Longtime User
SOLUTION HERE


I have seen in the forum some ways to know if you are connected or not to Internet.

Example: https://www.b4x.com/android/forum/threads/b4x-b4xlib-b4xcheckinternetlm.133628/post-848997

The problem is... I don't know if the connection is WiFi or cellular network. If I need to download an update of many records from a database, a video file or whatever but the size is considerably large, I must first ask the user if they want to download it.

This is my code.
CheckInternet:
Sub Process_Globals
  Type tpeCheckInternet(blnIsOnline As Boolean, strType As String)
End Sub

Public Sub CheckInternet() As tpeCheckInternet
    Dim ci As tpeCheckInternet
    ci.Initialize
    ci.strType = "Unknown"
    #if b4a
    Dim jo As JavaObject
    jo.InitializeContext
    Dim cm As JavaObject = jo.RunMethod("getSystemService", Array("connectivity"))
    Dim activeNetwork As JavaObject = cm.RunMethod("getActiveNetworkInfo", Null)
    If activeNetwork.IsInitialized = False Then
      ci.blnIsOnline = False
    Else
      If activeNetwork.RunMethod("isConnected", Null).As (Boolean) = True Then
        If activeNetwork.RunMethod("getType", Null).As (Int) = 1 Then
          ci.blnIsOnline = True
          ci.strType = "WiFi"
        Else
          ci.blnIsOnline = True
          ci.strType = "Cell"
        End If
      Else
        ci.blnIsOnline = False
      End If
    End If
    #Else If b4i
    Dim n As Network
    If n.GetCurrentType = n.TYPE_WIFI Then
        ci.blnIsOnline = True
        ci.strType = "WiFi"
    Else If n.GetCurrentType = n.TYPE_MOBILE Then
        ci.blnIsOnline = True
        ci.strType = "Cell"
    End If
  #End If
  Return ci
End Sub

The B4I code is a suggestion from ChatGPT, but I'm not doing something right or ChatGPT is lying to me :)

1718043713619.png
1718043774165.png


Another suggestion from ChatGPT but it's strange

B4X:
Sub Process_Globals
    ' These global variables will be declared once when the application starts.
    Dim no As NativeObject
End Sub

Sub Globals
    ' These global variables will be redeclared each time the activity is created.
    Dim cm As ConnectivityManager
End Sub

Sub Activity_Create(FirstTime As Boolean)
    ' Do not forget to load the layout file created with the visual designer. For example:
    ' Activity.LoadLayout("Layout1")
    no.InitializeNewInstance("android.content.ContextWrapper", Array As Object(Activity))
    cm = no.RunMethod("getSystemService:", Array("connectivity"))
   
    CheckInternetConnection
End Sub

Sub CheckInternetConnection
    Dim isConnected As Boolean
    isConnected = IsConnectedToInternet
   
    If isConnected Then
        Log("Internet connection is available.")
        Dim connectionType As String = GetConnectionType
        If connectionType = "WIFI" Then
            Log("Connection type: WiFi.")
        Else If connectionType = "MOBILE" Then
            Log("Connection type: Cellular network.")
        Else
            Log("Unknown connection type: " & connectionType)
        End If
    Else
        Log("No internet connection.")
    End If
End Sub

Sub IsConnectedToInternet As Boolean
    Dim ni As NativeObject
    ni.InitializeNewInstance("java.net.NetworkInterface", Null)
    Dim interfaces As List = ni.RunMethod("getNetworkInterfaces", Null)
    For i = 0 To interfaces.Size - 1
        Dim networkInterface As NativeObject = interfaces.Get(i)
        Dim interfaceName As String = networkInterface.GetField("name").AsString
        If interfaceName.StartsWith("pdp_ip") Or interfaceName.StartsWith("rmnet") Then
            Return True ' Cellular network is connected
        End If
    Next
    Return cm.RunMethod("getActiveNetworkInfo", Null).IsInitialized
End Sub

Sub GetConnectionType As String
    Dim activeNetwork As NativeObject = cm.RunMethod("getActiveNetworkInfo", Null)
    If activeNetwork.IsInitialized Then
        If activeNetwork.GetField("getType") = 1 Then
            Return "WIFI"
        Else
            Return "MOBILE"
        End If
    Else
        Return ""
    End If
End Sub

At the end of the code leave the following comment:

This code utilizes NativeObject to interact with Android's ConnectivityManager to check for internet connectivity and determine the type of connection.

  • IsConnectedToInternet method checks if there is any active network interface, which indicates internet connectivity.
  • GetConnectionType method determines whether the active network is WiFi or mobile data.
Make sure to handle permissions in your Info.plist file to allow network access.
 
Last edited:
Solution
Now, there was my confusion. I imagined that the library was developed in XCode on a Mac.

I'm going to try using #if objc with Objective-C code.

To make it clear, the .a file and the .h file are produced by B4I, and Erel's tool creates the XML.

——————————————————————

Ahora si, ahí estaba mi confusión. Yo imaginé que la librería estaba desarrollada en XCode en una Mac. Voy a Intentar usar #if objc con el código Objective-C. Para dejar en claro el archivo .a y el archivo .h son producidos por B4I y la herramienta de Erel crea el XML

Sergio Haurat

Active Member
Licensed User
Longtime User
Some Mac user can compile the code seen below into the necessary files (.h, .xml and .a) like @Star-Dust does in [B4X] [XUI] SD FlexGrid (Table)

B4i Library:
#import <Foundation/Foundation.h>

@interface NetworkStatus : NSObject

@property (nonatomic, assign) BOOL isConnected;
@property (nonatomic, strong) NSString *networkType;

@end

@implementation NetworkStatus

@end

@implementation NetworkReachability

+ (NetworkStatus *)getNetworkStatus {
    NetworkStatus *networkStatus = [[NetworkStatus alloc] init];

    SCNetworkReachabilityRef reach = SCNetworkReachabilityCreateWithName(NULL, [@"google.com" UTF8String]);
    SCNetworkReachabilityFlags flags;
    SCNetworkReachabilityGetFlags(reach, &flags);
    CFRelease(reach);

    if ((flags & kSCNetworkReachabilityFlagsReachable) == 0) {
        networkStatus.isConnected = NO;
        networkStatus.networkType = @"NONE";
        return networkStatus;
    }

    if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) {
        networkStatus.isConnected = YES;
        networkStatus.networkType = @"LOCAL"; // Local network (uncertain if internet)
        return networkStatus;
    }

    if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == 0) {
        networkStatus.isConnected = YES;
        networkStatus.networkType = @"WIFI";
        return networkStatus;
    }

    networkStatus.isConnected = YES;
    networkStatus.networkType = @"CELL";
    return networkStatus;
}

@end
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
There is an easier way to know if you are connected with WIFI - See here

You can also use sources that check if Wifi is on and if you are connected to a Wifi and all the features of the SSDI ...

You don't need to think of new methods.


PS. Don't trust ChatGPT too much. It is very effective for some languages (those for which it is very on the right track) and not very reliable for others
 
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
There is an easier way to know if you are connected with WIFI - See here

You can also use sources that check if Wifi is on and if you are connected to a Wifi and all the features of the SSDI ...

You don't need to think of new methods.


PS. Don't trust ChatGPT too much. It is very effective for some languages (those for which it is very on the right track) and not very reliable for others
Hello, thanks for your response. I'm going to try this method to see if I can get the same result.

On first post, I can't find iSocket or similar in B4I
You can use Socket.GetMyWifiIp to get the local network ip. It will return 127.0.0.1 if there is no network.

Now just to know.
- I have created a static library project.
- I have compiled and created the .a file
- Obviously the .h file generated by the XCode compiler is useless, it has to be done manually and this is the difficult part
- The .xml file is with the Erel tool that reads the .h file
 
Last edited:
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
Socket -> iNetwork library
 
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
Dear @Star-Dust,

If I turn off the Wi-Fi network and cell phone data (I am not activating airplane mode) the application does absolutely nothing, no errors, nothing.

You could try to create a library with “Reachability”, just like you did with SD Flex Grid, do you think it's possible? I would pay for it since it would solve this double but simple question (Is there Internet? Cellular or WiFi) for the current project and any other in the future.

If you don't have time, tell me how to create the .h file, which is what I didn't see any tool do, like with the .xml file.

I have searched the forum and I see that this is not a new question, I am looking for a definitive solution. The best option would be to have it within iNetwork, for example

Thank you for your patience and your time.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
If I turn off the Wi-Fi network and cell phone data (I am not activating airplane mode) the application does absolutely nothing, no errors, nothing.
As you will certainly have read in the posts I indicated to you, Erel suggested logging in with HttpJob to check if there is a connection. If it does not generate an error, check if it is wifi with the method already indicated. (Besides the fact that you can also know all the details of the SSID in the code indicated in the second link)
So you can get the same result without having to rewrite any more code.

You could try to create a library with “Reachability”, just like you did with SD Flex Grid, do you think it's possible? I would pay for it since it would solve this double but simple question (Is there Internet? Cellular or WiFi) for the current project and any other in the future.
My FlexGrid library is entirely written in B4X and with small native code insertions. You find many libraries written in Objective-C on the forum and several developers. But since there is a valid solution I doubt anyone is willing to compile your code. Since you have the tools, I suggest you try it yourself if you think it's essential for you
 
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
small native code insertions
Well, I think the simpler, better for everyone. I don't see using a lot of libraries or doing multiple things for people like me as being the most convenient. Please, just tell me how you generated the .h file. I'm going to get involved with Objective-C to help the B4I community integrate more iOS with Android using B4X.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
Compile As Library
".a and .h files will be created in the Mac Libs folder."

I am very sorry for not being exact in my posts, my language is Spanish. I will try again:

If I have a static library code on Mac that generates the .a file (in machine code), how do I get the .h file that is not the standard one generated by XCode. The XML is a tool from @Erel that reads the .h file.

The .h file generated in XCode is not compatible with the example I see in SD Flex Grid.

Example .h file header Flex Grid
B4X:
#import "iCore.h"
#import "iXUI.h"
@class _head_type;
@class _cell_type;
@class _flexorder_type;
@class b4i_flexgrid;
@class _parsednode;
@class _orderdata;
@interface b4i_eval : B4IClass
{
@public int __number_type;
@public int __operator_type;
@public _parsednode* __root;
@public int __parseindex;
@public B4IList* __nodes;
@public B4IMap* __operatorlevel;
@public BOOL __error;
@public b4i_flexgrid* __flexg;
... continue

Example XCode .h file
B4X:
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>

//! Project version number for MacOSReachability.
FOUNDATION_EXPORT double ReachabilityVersionNumber;

//! Project version string for MacOSReachability.
FOUNDATION_EXPORT const unsigned char ReachabilityVersionString[];

/**
 * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X.
 *
 * @see http://nshipster.com/ns_enum-ns_options/
 **/
#ifndef NS_ENUM
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#endif

extern NSString *const kReachabilityChangedNotification;

... continue

The #include syntax is different to the content of your .h file (among other lines) compared to what XCode does when compiling, I understand that my problem in getting it to work is having the .h file with the correct syntax. It's just an opinion, I'm not sure either.

Thank you for your patience.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
there are two alternatives: (1) I don't understand what you mean (2) You're confusing.

You asked me how I compiled the FlexGrid library and I gave you the link, all the other xml file considerations seem to me to be just irrelevant considerations
 
Last edited:
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
@Star-Dust, thank you for your patience and your responses. It is likely a combination of points 1 and 2. Additionally, my native language is Spanish, and I use Google Translate for my writing.

To make it as straightforward as possible:

- An additional library in B4X is stored in a folder and configured in the IDE.
- B4I libraries can be ".b4xlib" files or, as in the case of your SD_FlexGrid library, a combination of three types of files. The .a file, which is a binary file compiled in XCode, the .h file, which is human-readable, and the .xml file generated by Erel's tool B4Ih2xml.jar.

The .h file created by XCode does not have the same internal structure as the one found within the version of your library. Here, I repeat the examples from the previous post to visualize what I want to express regarding structure:

Start of FlexGrid .h file:
#import "iCore.h"
#import "iXUI.h"
@class _head_type;
@class _cell_type;
@class _flexorder_type;
@class b4i_flexgrid;
@class _parsednode;
@class _orderdata;
@interface b4i_eval : B4IClass
{
@public int __number_type;
@public int __operator_type;
@public _parsednode* __root;
@public int __parseindex;
@public B4IList* __nodes;
@public B4IMap* __operatorlevel;
@public BOOL __error;
@public b4i_flexgrid* __flexg;
... continue

Start of the .h file, from the library that I have compiled in XCode:
#import <Foundation/Foundation.h>
#import <SystemConfiguration/SystemConfiguration.h>
FOUNDATION_EXPORT double ReachabilityVersionNumber;
FOUNDATION_EXPORT const unsigned char ReachabilityVersionString[];
#ifndef NS_ENUM
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#endif
extern NSString *const kReachabilityChangedNotification;

... continue

As I wrote earlier, the tool developed by @Erel reads the .h file and creates the .xml file. As far as I imagine, the XML file is read by the IDE to display it in the list of available libraries.

The problem I have is that I can select my library compiled in XCode from the list of available libraries in B4I, but it does not allow me to instantiate it by its name or any of its functions. Here is an example of what happens with iNetwork:

This does not work:
Dim n as Network
This works:
Dim ss As ServerSocket

The .h file of your library, #import refers to "iCore.h" within double quotes, just to give an example. The .h file created by XCode in my case refers in #import to other libraries, but it does so using < and >.

I think that when trying to compile the file to test it, my .h file is the problem, but I'm not sure. This is the error that B4I shows when trying to compile the test application.

b4i_main.h:2:9: fatal error: 'Reachability.h' file not found
#import "Reachability.h"
^~~~~~~~~~~~~~~~
1 error generated.

Now, beyond this particular case, I would like to know how to compile and obtain the correct files to contribute other solutions in the future.
 
Upvote 0

Star-Dust

Expert
Licensed User
Longtime User
The libraries are different because I created my library with the B4i IDE. I suggest you create the library directly from the B4i IDE using the tools for using native code within B4i. This would solve many problems.

If you have to import a library that you created with swift or objective-C and compiled with xcode and then import it to b4i I think it is more complex. I've never tried to do something like this and I don't know how to help you.

____________________________________________________________________________________________________________
Las bibliotecas son diferentes porque creé mi biblioteca con B4i IDE. Le sugiero que cree la biblioteca directamente desde B4i IDE utilizando las herramientas para usar código nativo dentro de B4i. Esto solucionaría muchos problemas.

Si tienes que importar una biblioteca que creaste con swift u Objective-C y compilaste con xcode y luego importarla a b4i, creo que es más complejo. Nunca he intentado hacer algo como esto y no sé cómo ayudarte.
 
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
Now, there was my confusion. I imagined that the library was developed in XCode on a Mac.

I'm going to try using #if objc with Objective-C code.

To make it clear, the .a file and the .h file are produced by B4I, and Erel's tool creates the XML.

——————————————————————

Ahora si, ahí estaba mi confusión. Yo imaginé que la librería estaba desarrollada en XCode en una Mac. Voy a Intentar usar #if objc con el código Objective-C. Para dejar en claro el archivo .a y el archivo .h son producidos por B4I y la herramienta de Erel crea el XML
 
Upvote 0
Solution
Top