Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4b62d73
Migrate Apple reachability from SCNetworkReachability to NWPathMonitor
bmehta001 Apr 29, 2026
3906d9e
Restore ODWReachabilityTests includes to keep #1431 focused
bmehta001 Apr 29, 2026
12d8958
Restore ODWReachability.m header section to match main
bmehta001 Apr 29, 2026
7702508
Use NWPathMonitor in ODWReachability
bmehta001 May 2, 2026
675cad4
Clarify modern WWAN reachability handling
bmehta001 May 2, 2026
366f87a
Avoid blocking Apple reachability construction
bmehta001 May 2, 2026
c13c90c
Gate ODWReachability NWPathMonitor calls by availability
bmehta001 May 5, 2026
09a73ab
Capture ODWReachability semaphore before signal/wait
bmehta001 May 6, 2026
d440d1b
Merge branch 'main' into bhamehta/apple-reachability-longterm
bmehta001 May 9, 2026
a5de13d
Address reachability review comments
bmehta001 May 11, 2026
4711417
Avoid unguarded NWPath status init
bmehta001 May 11, 2026
c9288d1
Limit reachability gates to supported Apple targets
bmehta001 May 11, 2026
511320c
Validate +reachabilityWithAddress: inputs
bmehta001 May 11, 2026
c2587b7
Merge branch 'main' into bhamehta/apple-reachability-longterm
bmehta001 May 22, 2026
f2dab79
Address PR #1431 review comments
bmehta001 May 22, 2026
1ff9981
Remove unused checkNetworkReachability helper
bmehta001 May 24, 2026
0789ca8
Document hostname-constructor semantic change on modern Apple targets
bmehta001 May 24, 2026
46002f4
Simplify ODWReachability ARC-only code
bmehta001 May 25, 2026
7d468b0
Address Apple reachability review comments
bmehta001 May 25, 2026
c7a1864
Fix Apple reachability monitor races
bmehta001 May 25, 2026
566fda2
Fix Reachability hostname parsing
bmehta001 May 25, 2026
791f1dc
Clarify Reachability ARC build behavior
bmehta001 May 25, 2026
9f93d9d
Remove blocking Reachability notifier startup
bmehta001 May 25, 2026
3fed4dc
Match repo style in reachability files
bmehta001 May 25, 2026
eadd84b
Bump default iOS deployment target to 12.0
bmehta001 May 26, 2026
5055cc4
Remove internal ODWReachability helper
bmehta001 May 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build-ios.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ if [ "$IOS_PLAT" == "iphoneos" ] || [ "$IOS_PLAT" == "iphonesimulator" ]; then
SYS_NAME="iOS"
DEPLOYMENT_TARGET="$IOS_DEPLOYMENT_TARGET"
if [ -z "$DEPLOYMENT_TARGET" ]; then
DEPLOYMENT_TARGET="10.0"
DEPLOYMENT_TARGET="12.0"
FORCE_RESET_DEPLOYMENT_TARGET=YES
fi
elif [ "$IOS_PLAT" == "xros" ] || [ "$IOS_PLAT" == "xrsimulator" ]; then
Expand Down
6 changes: 0 additions & 6 deletions docs/List-of-OSS-Components.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,6 @@ Google's C++ test framework. Used only for tests and not included in products.

Google's C++ benchmarking framework. Used only for tests and not included in products.

## [Tony Million Reachability Framework](https://github.com/tonymillion/Reachability)

Reachability is a drop-in replacement for Apple's Reachability class. It is ARC-compatible, and it uses the new GCD methods to notify of network interface changes.
SDK maintains its own snapshot of the mainline `tonymillion/Reachability` [here](../third_party/Reachability). This code is not used nor included in the build of non-Apple OS.
Please note if customer product is adding dependency to this component, they should ensure it meets their product security and licensing requirements.

## SHA-1 by Steve Reid

Classic implementation of SHA-1 (Public Domain).
Expand Down
5 changes: 1 addition & 4 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Honor visibility properties for all target types
cmake_policy(SET CMP0063 NEW)

include_directories( . ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include/public ${CMAKE_CURRENT_SOURCE_DIR}/include/public ${CMAKE_CURRENT_SOURCE_DIR}/include/mat ${CMAKE_CURRENT_SOURCE_DIR}/pal ${CMAKE_CURRENT_SOURCE_DIR}/utils ${CMAKE_CURRENT_SOURCE_DIR}/modules/exp ${CMAKE_CURRENT_SOURCE_DIR}/modules/dataviewer ${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard ${CMAKE_CURRENT_SOURCE_DIR}/modules/liveeventinspector ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/Reachability ${CMAKE_CURRENT_SOURCE_DIR}/modules/cds ${CMAKE_CURRENT_SOURCE_DIR}/modules/signals ${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer /usr/local/include )
include_directories( . ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include/public ${CMAKE_CURRENT_SOURCE_DIR}/include/public ${CMAKE_CURRENT_SOURCE_DIR}/include/mat ${CMAKE_CURRENT_SOURCE_DIR}/pal ${CMAKE_CURRENT_SOURCE_DIR}/utils ${CMAKE_CURRENT_SOURCE_DIR}/modules/exp ${CMAKE_CURRENT_SOURCE_DIR}/modules/dataviewer ${CMAKE_CURRENT_SOURCE_DIR}/modules/privacyguard ${CMAKE_CURRENT_SOURCE_DIR}/modules/liveeventinspector ${CMAKE_CURRENT_SOURCE_DIR}/modules/cds ${CMAKE_CURRENT_SOURCE_DIR}/modules/signals ${CMAKE_CURRENT_SOURCE_DIR}/modules/sanitizer /usr/local/include )

set(SRCS decorators/BaseDecorator.cpp
packager/BondSplicer.cpp
Expand Down Expand Up @@ -170,8 +170,6 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11")

list(APPEND SRCS
pal/posix/NetworkInformationImpl.mm
# TODO: this unit below needs to be deprecated and removed
../third_party/Reachability/ODWReachability.m
)
else()
list(APPEND SRCS
Expand Down Expand Up @@ -342,4 +340,3 @@ message("-- Library will be installed to ${INSTALL_LIB_DIR}")
# #target_link_libraries(mat PUBLIC libcurl.a libz.a libssl.a libcrypto.a "${SQLITE_LIBRARY}" "${CMAKE_THREAD_LIBS_INIT}" "${CMAKE_DL_LIBS}" )
# #target_link_libraries(mat PUBLIC libsqlite3.a libz.a ${LIBS} "${CMAKE_THREAD_LIBS_INIT}" "${CMAKE_DL_LIBS}" )
#endif()

164 changes: 63 additions & 101 deletions lib/pal/posix/NetworkInformationImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include "pal/PAL.hpp"
#include "pal/NetworkInformationImpl.hpp"

#import <Foundation/Foundation.h>
#import <Network/Network.h>
#import "ODWReachability.h"

namespace PAL_NS_BEGIN {

Expand Down Expand Up @@ -63,16 +63,13 @@ virtual NetworkCost GetNetworkCost()
void SetupNetDetect();

private:
void SetupModernNetDetect() API_AVAILABLE(macos(10.14), ios(12.0));
void UpdateType(NetworkType type) noexcept;
void UpdateCost(NetworkCost cost) noexcept;
std::string m_network_provider {};

// iOS 12 and newer
// iOS 12+ / macOS 10.14+
nw_path_monitor_t m_monitor = nil;

// iOS 11 and older
ODWReachability* m_reach = nil;
id m_notificationId = nil;
};

NetworkInformation::NetworkInformation(IRuntimeConfig& configuration) :
Expand All @@ -88,118 +85,84 @@ virtual NetworkCost GetNetworkCost()
{
if (m_isNetDetectEnabled)
{
nw_path_monitor_cancel(m_monitor);
}
}
else
{
if (m_isNetDetectEnabled)
{
[[NSNotificationCenter defaultCenter] removeObserver:m_notificationId];
[m_reach stopNotifier];
if (m_monitor != nil)
{
nw_path_monitor_cancel(m_monitor);
}
}
}
}

void NetworkInformation::SetupNetDetect()
void NetworkInformation::SetupModernNetDetect()
{
if (@available(macOS 10.14, iOS 12.0, *))
auto weak_this = std::weak_ptr<NetworkInformation>(shared_from_this());

m_monitor = nw_path_monitor_create();
if (m_monitor == nil)
{
auto weak_this = std::weak_ptr<NetworkInformation>(shared_from_this());
LOG_WARN("Unable to create NWPathMonitor.");
return;
}

m_monitor = nw_path_monitor_create();
nw_path_monitor_set_queue(m_monitor, dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0));
nw_path_monitor_set_update_handler(m_monitor, ^(nw_path_t path)
nw_path_monitor_set_queue(m_monitor, dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0));
nw_path_monitor_set_update_handler(m_monitor, ^(nw_path_t path)
Comment thread
bmehta001 marked this conversation as resolved.
{
auto strong_this = weak_this.lock();
if (!strong_this)
{
return;
}

NetworkType type = NetworkType_Unknown;
NetworkCost cost = NetworkCost_Unknown;
nw_path_status_t status = nw_path_get_status(path);
bool connected = status == nw_path_status_satisfied || status == nw_path_status_satisfiable;
if (connected)
{
auto strong_this = weak_this.lock();
if (!strong_this)
if (nw_path_uses_interface_type(path, nw_interface_type_wifi))
{
return;
type = NetworkType_Wifi;
}

NetworkType type = NetworkType_Unknown;
NetworkCost cost = NetworkCost_Unknown;
nw_path_status_t status = nw_path_get_status(path);
bool connected = status == nw_path_status_satisfied || status == nw_path_status_satisfiable;
if (connected)
else if (nw_path_uses_interface_type(path, nw_interface_type_cellular))
{
if (nw_path_uses_interface_type(path, nw_interface_type_wifi))
{
type = NetworkType_Wifi;
}
else if (nw_path_uses_interface_type(path, nw_interface_type_cellular))
{
type = NetworkType_WWAN;
}
else if (nw_path_uses_interface_type(path, nw_interface_type_wired))
{
type = NetworkType_Wired;
}
cost = nw_path_is_expensive(path) ? NetworkCost_Metered : NetworkCost_Unmetered;
if (@available(macOS 10.15, iOS 13.0, *))
type = NetworkType_WWAN;
}
else if (nw_path_uses_interface_type(path, nw_interface_type_wired))
{
type = NetworkType_Wired;
}
cost = nw_path_is_expensive(path) ? NetworkCost_Metered : NetworkCost_Unmetered;
if (@available(macOS 10.15, iOS 13.0, *))
{
if (nw_path_is_constrained(path))
{
if (nw_path_is_constrained(path))
{
cost = NetworkCost_Roaming;
}
cost = NetworkCost_Roaming;
}
}
strong_this->UpdateType(type);
strong_this->UpdateCost(cost);
});
nw_path_monitor_start(m_monitor);

// nw_path_monitor_start will invoke the callback for once. So if
// we don't want to listen for changes, we can just start the
// monitor and stop it right away.
if (!m_isNetDetectEnabled)
{
nw_path_monitor_cancel(m_monitor);
}
strong_this->UpdateType(type);
strong_this->UpdateCost(cost);
});
nw_path_monitor_start(m_monitor);

// nw_path_monitor_start will invoke the callback for once. So if
// we don't want to listen for changes, we can just start the
// monitor and stop it right away.
if (!m_isNetDetectEnabled)
{
nw_path_monitor_cancel(m_monitor);
}
}

void NetworkInformation::SetupNetDetect()
{
if (@available(macOS 10.14, iOS 12.0, *))
{
SetupModernNetDetect();
}
else
{
auto weak_this = std::weak_ptr<NetworkInformation>(shared_from_this());

m_reach = [ODWReachability reachabilityForInternetConnection];
void (^block)(NSNotification*) = ^(NSNotification*)
{
auto strong_this = weak_this.lock();
if (!strong_this)
{
return;
}

// NetworkCost information is not available until iOS 12.
// Just make the best guess here.
switch (m_reach.currentReachabilityStatus)
{
case NotReachable:
strong_this->UpdateType(NetworkType_Unknown);
strong_this->UpdateCost(NetworkCost_Unknown);
break;
case ReachableViaWiFi:
strong_this->UpdateType(NetworkType_Wifi);
strong_this->UpdateCost(NetworkCost_Unmetered);
break;
case ReachableViaWWAN:
strong_this->UpdateType(NetworkType_WWAN);
strong_this->UpdateCost(NetworkCost_Metered);
break;
}
};
block(nil); // Update the initial status.

if (m_isNetDetectEnabled)
{
m_notificationId =
[[NSNotificationCenter defaultCenter]
addObserverForName: kNetworkReachabilityChangedNotification
object: nil
queue: nil
usingBlock: block];
[m_reach startNotifier];
}
LOG_WARN("Network detection requires iOS 12.0 or macOS 10.14 or newer.");
}
}

Expand Down Expand Up @@ -229,4 +192,3 @@ virtual NetworkCost GetNetworkCost()
}

} PAL_NS_END

108 changes: 0 additions & 108 deletions tests/unittests/obj-c/ODWReachabilityTests.mm

This file was deleted.

4 changes: 0 additions & 4 deletions tests/unittests/unittests-ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
objects = {

/* Begin PBXBuildFile section */
16CC10702D4D58DA00C03295 /* ODWReachabilityTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 16CC106F2D4D58DA00C03295 /* ODWReachabilityTests.mm */; };
430102E5235E660F00836D50 /* iOSWrapper.mm in Sources */ = {isa = PBXBuildFile; fileRef = 430102E4235E660F00836D50 /* iOSWrapper.mm */; };
431EFE50233EBE54002FCC18 /* HttpClientTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 431EFE2A233EBE53002FCC18 /* HttpClientTests.cpp */; };
431EFE51233EBE54002FCC18 /* LoggerTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 431EFE2B233EBE53002FCC18 /* LoggerTests.cpp */; };
Expand Down Expand Up @@ -117,7 +116,6 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
16CC106F2D4D58DA00C03295 /* ODWReachabilityTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = ODWReachabilityTests.mm; path = "obj-c/ODWReachabilityTests.mm"; sourceTree = "<group>"; };
430102E4235E660F00836D50 /* iOSWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = iOSWrapper.mm; path = ../../common/iOSWrapper.mm; sourceTree = "<group>"; };
431EFE1E233EBDF2002FCC18 /* libunittests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libunittests.a; sourceTree = BUILT_PRODUCTS_DIR; };
431EFE2A233EBE53002FCC18 /* HttpClientTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HttpClientTests.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -203,7 +201,6 @@
431EFE15233EBDF2002FCC18 = {
isa = PBXGroup;
children = (
16CC106F2D4D58DA00C03295 /* ODWReachabilityTests.mm */,
43BD496F26B8B0C300EC3C0C /* EventPropertiesDecoratorTests.cpp */,
437C72F024D2286F0046F545 /* ODWLogConfigurationTests.mm */,
437C72EE24D21ACE0046F545 /* ODWSemanticContextTests.mm */,
Expand Down Expand Up @@ -436,7 +433,6 @@
431EFEA7233EC590002FCC18 /* HttpDeflateCompressionTests.cpp in Sources */,
431EFEB3233EC590002FCC18 /* OfflineStorageTests.cpp in Sources */,
431EFEB8233EC590002FCC18 /* TaskDispatcherCAPITests.cpp in Sources */,
16CC10712D4D58DA00C03295 /* ODWReachabilityTests.mm in Sources */,
437C72ED24D0C5D70046F545 /* ODWEventPropertiesTests.mm in Sources */,
431EFEB6233EC590002FCC18 /* RouteTests.cpp in Sources */,
431EFEA8233EC590002FCC18 /* HttpRequestEncoderTests.cpp in Sources */,
Expand Down
Loading
Loading