Skip to content

Commit

Permalink
ios: use NetworkPathMonitor
Browse files Browse the repository at this point in the history
SCNetworkReachabilityCreateWithAddress is deprecated for some time.
  • Loading branch information
Chilledheart committed May 9, 2024
1 parent 716f7b8 commit 096fd07
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/ios/YassAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ @implementation YassAppDelegate {
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id>*)launchOptions {
state_ = STOPPED;
initNetworkPathMonitor();
[self didDefaultsChanged:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didDefaultsChanged:)
Expand Down
26 changes: 0 additions & 26 deletions src/ios/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

#include "ios/utils.h"

#include <SystemConfiguration/SCNetworkReachability.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <net/if.h>
Expand All @@ -14,31 +13,6 @@

using json = nlohmann::json;

bool connectedToNetwork() {
// Create zero addy
struct sockaddr_in zeroAddress;
bzero(&zeroAddress, sizeof(zeroAddress));
zeroAddress.sin_len = sizeof(zeroAddress);
zeroAddress.sin_family = AF_INET;

// Recover reachability flags
SCNetworkReachabilityRef defaultRouteReachability =
SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr*)&zeroAddress);
SCNetworkReachabilityFlags flags;

Boolean didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
CFRelease(defaultRouteReachability);

if (!didRetrieveFlags) {
return false;
}

Boolean isReachable = flags & kSCNetworkFlagsReachable;
Boolean needsConnection = flags & kSCNetworkFlagsConnectionRequired;

return (isReachable && !needsConnection) ? true : false;
}

std::string serializeTelemetryJson(uint64_t total_rx_bytes, uint64_t total_tx_bytes) {
json j;
j["total_rx_bytes"] = total_rx_bytes;
Expand Down
4 changes: 4 additions & 0 deletions src/ios/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
#include <string_view>
#include <vector>

void initNetworkPathMonitor();
void deinitNetworkPathMonitor();

bool connectedToNetwork();

std::string serializeTelemetryJson(uint64_t total_rx_bytes, uint64_t total_tx_bytes);
bool parseTelemetryJson(std::string_view resp, uint64_t* total_rx_bytes, uint64_t* total_tx_bytes);

Expand Down
69 changes: 68 additions & 1 deletion src/ios/utils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,71 @@

#include "ios/utils.h"

// PLACE HOLDER FOR Objective-C++ Code
#include <atomic>
#include <thread>

#include <Network/Network.h>

#include "core/logging.hpp"

static std::atomic<bool> connectedNetwork;
static dispatch_queue_t monitorQueue;
static nw_path_monitor_t monitor;
static std::once_flag initFlag;

// https://forums.developer.apple.com/forums/thread/105822
void initNetworkPathMonitor() {
DCHECK(!monitor);

std::call_once(initFlag, []() {
dispatch_queue_attr_t attrs = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY,
DISPATCH_QUEUE_PRIORITY_DEFAULT);
monitorQueue = dispatch_queue_create("it.gui.yass.network-monitor", attrs);
});

// monitor = nw_path_monitor_create_with_type(nw_interface_type_wifi);
monitor = nw_path_monitor_create();
nw_path_monitor_set_queue(monitor, monitorQueue);
if (@available(iOS 14, *)) {
nw_path_monitor_prohibit_interface_type(monitor, nw_interface_type_loopback);
}
nw_path_monitor_set_update_handler(monitor, ^(nw_path_t _Nonnull path) {
nw_path_status_t status = nw_path_get_status(path);
// Determine the active interface, but how?
switch (status) {
case nw_path_status_invalid: {
// Network path is invalid
connectedNetwork = false;
break;
}
case nw_path_status_satisfied: {
// Network is usable
connectedNetwork = true;
break;
}
case nw_path_status_satisfiable: {
// Network may be usable
connectedNetwork = false;
break;
}
case nw_path_status_unsatisfied: {
// Network is not usable
connectedNetwork = false;
break;
}
}
});

nw_path_monitor_start(monitor);
}

void deinitNetworkPathMonitor() {
DCHECK(monitor);

nw_path_monitor_cancel(monitor);
monitor = nw_path_monitor_t();
}

bool connectedToNetwork() {
return connectedNetwork;
}

0 comments on commit 096fd07

Please sign in to comment.