iOS Question #IF OBJC / NativeObject

Sergio Haurat

Active Member
Licensed User
Longtime User
Hi @Erel, I am trying to use native code to detect if there is an internet connection and the type of connection. Of course, the use of ChatGPT does not guarantee operation, but it is the way I have to do "translations" when I do not know Swift or Objective-C

I have searched the forum and saw several examples that the quick method is to try, connect to a site using a try/catch, for example google.com. and then with socketServer this example if it is WiFi or not.

In this answer you just talk about #IF OBJC, I found a piece of code in Swift that I converted into Objective-C using ChatGPT

Original post in stackoverflow.com

Swift code:
import Network // Put this on top of your class

let monitor = NWPathMonitor()

monitor.pathUpdateHandler = { path in
    if path.status != .satisfied {
        // Not connected
    }
    else if path.usesInterfaceType(.cellular) {
        // Cellular 3/4/5g connection
    }
    else if path.usesInterfaceType(.wifi) {
        // Wi-Fi connection
    }
    else if path.usesInterfaceType(.wiredEthernet) {
        // Ethernet connection
    }
}

monitor.start(queue: DispatchQueue.global(qos: .background))

Objective-C code:
#import <Foundation/Foundation.h>
#import <Network/Network.h>

@interface NetworkMonitor : NSObject
@property (nonatomic, strong) NWPathMonitor *monitor;
@end

@implementation NetworkMonitor

- (instancetype)init {
    self = [super init];
    if (self) {
        self.monitor = [[NWPathMonitor alloc] init];
        __weak typeof(self) weakSelf = self;
        
        self.monitor.pathUpdateHandler = ^(NWPath * _Nonnull path) {
            if (path.status != NWPathStatusSatisfied) {
                // Not connected
                NSLog(@"Not connected");
            } else if ([path usesInterfaceType:NWInterfaceTypeCellular]) {
                // Cellular 3/4/5g connection
                NSLog(@"Cellular connection");
            } else if ([path usesInterfaceType:NWInterfaceTypeWiFi]) {
                // Wi-Fi connection
                NSLog(@"Wi-Fi connection");
            } else if ([path usesInterfaceType:NWInterfaceTypeWiredEthernet]) {
                // Ethernet connection
                NSLog(@"Ethernet connection");
            }
        };

        [self.monitor startWithQueue:dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)];
    }
    return self;
}

@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NetworkMonitor *networkMonitor = [[NetworkMonitor alloc] init];
        [[NSRunLoop currentRunLoop] run];
    }
    return 0;
}

According to ChatGPT this should be the code, but it doesn't work

B4X code:
#Region  Project Attributes
    #ApplicationLabel: B4i Network Monitor
    #Version: 1.0.0
    #iOSKeychainAccessGroups:
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
    Private monitor As NativeObject
End Sub

Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Network Monitor"
    Page1.RootPanel.LoadLayout("MainLayout")
    NavControl.ShowPage(Page1)
    
    monitor = CreateNWPathMonitor
    StartMonitoring
End Sub

Private Sub CreateNWPathMonitor As NativeObject
    Dim no As NativeObject
    no = no.Initialize("NWPathMonitor").RunMethod("new", Null)
    Return no
End Sub

Private Sub StartMonitoring
    monitor.RunMethod("setPathUpdateHandler:", Array(CreateWrapper("pathUpdateHandler:")))
    monitor.RunMethod("startWithQueue:", Array(CreateWrapper("globalQueue")))
End Sub

Private Sub pathUpdateHandler(path As NativeObject)
    Dim status As Int = path.GetField("status").AsNumber
    If status <> 1 Then ' NWPathStatusSatisfied == 1
        Log("Not connected")
    Else
        Dim usesCellular As Boolean = path.RunMethod("usesInterfaceType:", Array(4)).AsBoolean ' NWInterfaceTypeCellular == 4
        Dim usesWiFi As Boolean = path.RunMethod("usesInterfaceType:", Array(1)).AsBoolean ' NWInterfaceTypeWiFi == 1
        Dim usesEthernet As Boolean = path.RunMethod("usesInterfaceType:", Array(2)).AsBoolean ' NWInterfaceTypeWiredEthernet == 2

        If usesCellular Then
            Log("Cellular connection")
        ElseIf usesWiFi Then
            Log("Wi-Fi connection")
        ElseIf usesEthernet Then
            Log("Ethernet connection")
        End If
    End If
End Sub

Private Sub CreateWrapper(MethodName As String) As NativeObject
    Dim no As NativeObject
    no.Initialize("B4I" & MethodName)
    Return no
End Sub

Private Sub globalQueue As NativeObject
    Return NativeObject.Initialize("dispatch_get_global_queue", Array(4, 0)) ' QOS_CLASS_BACKGROUND == 4
End Sub
 

Sergio Haurat

Active Member
Licensed User
Longtime User
Post the error message.


Show error and project example. I want to thank you very much for your time

warning: unexpected C compiler invocation with specified outputs: '/Users/administrator/Documents/UploadedProjects/<user id>/Payload/CheckInternet.app/reachability.m' (for input: '/Users/administrator/Documents/UploadedProjects/<user id>/reachability.m') (in target 'B4iProject' from project 'B4iProject')

Error: ** BUILD FAILED **
 

Attachments

  • CheckInternet.zip
    4.6 KB · Views: 79
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
It will not work. It is a Swift class and it will be more complicated to integrate it.

You can use ServerSocket to find out whether the device is connected to wifi (GetMyWifiIp) and whether it is connected to a network at all (GetMyIp).
I do not know either language to be able to see the error, additionally, the conversion from Swift to Objective-C is done with ChatGPT

I tried to compile a library in XCode and then include it with the .h and .xml file, all without success o_O

I've seen in other posts that you invite you to first connect to google.com and then use SocketServer. I have already tried it and if WiFi or cellular data is not enabled it does not generate any errors and I cannot do anything.

My hope is to have code similar to this, but with NativeObject

Actually you should update it according to this document
 
Upvote 0

Sergio Haurat

Active Member
Licensed User
Longtime User
1. Use GetMyWifiIp <> "127.0.0.1" to check whether the device is connected to wifi.
2. If not then check GetMyIp <> "127.0.0.1". If true then the device is connected to cellular network (assuming that wifi is false).
Well, I'll try to do it with pure b4x
 
Upvote 0
Solution
Top