General:
Forums subtopic: App & System Services > Networking
TN3151 Choosing the right networking API
Networking Overview document — Despite the fact that this is in the archive, this is still really useful.
TLS for App Developers forums post
Choosing a Network Debugging Tool documentation
WWDC 2019 Session 712 Advances in Networking, Part 1 — This explains the concept of constrained networking, which is Apple’s preferred solution to questions like How do I check whether I’m on Wi-Fi?
TN3135 Low-level networking on watchOS
TN3179 Understanding local network privacy
Adapt to changing network conditions tech talk
Understanding Also-Ran Connections forums post
Extra-ordinary Networking forums post
Foundation networking:
Forums tags: Foundation, CFNetwork
URL Loading System documentation — NSURLSession, or URLSession in Swift, is the recommended API for HTTP[S] on Apple platforms.
Network framework:
Forums tag: Network
Network framework documentation — Network framework is the recommended API for TCP, UDP, and QUIC on Apple platforms.
Building a custom peer-to-peer protocol sample code (aka TicTacToe)
Implementing netcat with Network Framework sample code (aka nwcat)
Configuring a Wi-Fi accessory to join a network sample code
Moving from Multipeer Connectivity to Network Framework forums post
Network Extension (including Wi-Fi on iOS):
See Network Extension Resources
Wi-Fi Fundamentals
TN3111 iOS Wi-Fi API overview
Wi-Fi Aware framework documentation
Wi-Fi on macOS:
Forums tag: Core WLAN
Core WLAN framework documentation
Wi-Fi Fundamentals
Secure networking:
Forums tags: Security
Apple Platform Security support document
Preventing Insecure Network Connections documentation — This is all about App Transport Security (ATS).
Available trusted root certificates for Apple operating systems support article
Requirements for trusted certificates in iOS 13 and macOS 10.15 support article
About upcoming limits on trusted certificates support article
Apple’s Certificate Transparency policy support article
What’s new for enterprise in iOS 18 support article — This discusses new key usage requirements.
Technote 2232 HTTPS Server Trust Evaluation
Technote 2326 Creating Certificates for TLS Testing
QA1948 HTTPS and Test Servers
Miscellaneous:
More network-related forums tags: 5G, QUIC, Bonjour
On FTP forums post
Using the Multicast Networking Additional Capability forums post
Investigating Network Latency Problems forums post
WirelessInsights framework documentation
iOS Network Signal Strength
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Network
RSS for tagNetwork connections send and receive data using transport and security protocols.
Posts under Network tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I am using a custom PAC file in network settings and till now with Sonoma & Sequoia OS, it was working perfectly fine and I was able to redirect traffic to my proxy server.
After upgrading to MacOS Tahoe, this stopped working completely. What is happening now is no url is opening on my machine with Chrome & Firefox browser, but somehoe Safari is working. After checking, I found that my deployed network extension is intercepting traffic and allowing it to pass. But still, the pac file is not working.
Are there any changes done in MacOS Tahoe regarding this PAC file? How can I resolve this issue?
The app “Wi-Fi Aware Sample” on Bojie的iPhone quit unexpectedly.
Domain: IDEDebugSessionErrorDomain
Code: 20
Failure Reason: Message from debugger: The LLDB RPC server has crashed. You may need to manually terminate your process. The crash log is located in ~/Library/Logs/DiagnosticReports and has a prefix 'lldb-rpc-server'. Please file a bug and attach the most recent crash log.
User Info: {
DVTErrorCreationDateKey = "2025-09-17 10:26:56 +0000";
IDEDebugSessionErrorUserInfoUnavailabilityError = "Error Domain=com.apple.dt.deviceprep Code=-10 "Fetching debug symbols for Bojie\U7684iPhone" UserInfo={NSLocalizedRecoverySuggestion=Xcode will continue when the operation completes., NSLocalizedDescription=Fetching debug symbols for Bojie\U7684iPhone}";
IDERunOperationFailingWorker = DBGLLDBLauncher;
}
Event Metadata: com.apple.dt.IDERunOperationWorkerFinished : {
"device_identifier" = "00008101-001E29E01E63003A";
"device_isCoreDevice" = 1;
"device_model" = "iPhone13,3";
"device_osBuild" = "26.0 (23A341)";
"device_osBuild_monotonic" = 2300034100;
"device_os_variant" = 1;
"device_platform" = "com.apple.platform.iphoneos";
"device_platform_family" = 2;
"device_reality" = 1;
"device_thinningType" = "iPhone13,3";
"device_transport" = 1;
"dvt_coredevice_version" = "477.23";
"dvt_coredevice_version_monotonic" = 477023000000000;
"dvt_coresimulator_version" = 1043;
"dvt_coresimulator_version_monotonic" = 1043000000000000;
"dvt_mobiledevice_version" = "1818.0.1";
"dvt_mobiledevice_version_monotonic" = 1818000001000000;
"launchSession_schemeCommand" = Run;
"launchSession_schemeCommand_enum" = 1;
"launchSession_targetArch" = arm64;
"launchSession_targetArch_enum" = 6;
"operation_duration_ms" = 1922640;
"operation_errorCode" = 20;
"operation_errorDomain" = IDEDebugSessionErrorDomain;
"operation_errorWorker" = DBGLLDBLauncher;
"operation_error_reportable" = 1;
"operation_name" = IDERunOperationWorkerGroup;
"operation_unavailabilityErrorCode" = "-10";
"operation_unavailabilityErrorDomain" = "com.apple.dt.deviceprep";
"param_consoleMode" = 1;
"param_debugger_attachToExtensions" = 0;
"param_debugger_attachToXPC" = 1;
"param_debugger_type" = 3;
"param_destination_isProxy" = 0;
"param_destination_platform" = "com.apple.platform.iphoneos";
"param_diag_MainThreadChecker_stopOnIssue" = 0;
"param_diag_MallocStackLogging_enableDuringAttach" = 0;
"param_diag_MallocStackLogging_enableForXPC" = 1;
"param_diag_allowLocationSimulation" = 1;
"param_diag_checker_mtc_enable" = 1;
"param_diag_checker_tpc_enable" = 1;
"param_diag_gpu_frameCapture_enable" = 0;
"param_diag_gpu_shaderValidation_enable" = 0;
"param_diag_gpu_validation_enable" = 0;
"param_diag_guardMalloc_enable" = 0;
"param_diag_memoryGraphOnResourceException" = 0;
"param_diag_queueDebugging_enable" = 1;
"param_diag_runtimeProfile_generate" = 0;
"param_diag_sanitizer_asan_enable" = 0;
"param_diag_sanitizer_tsan_enable" = 0;
"param_diag_sanitizer_tsan_stopOnIssue" = 0;
"param_diag_sanitizer_ubsan_enable" = 0;
"param_diag_sanitizer_ubsan_stopOnIssue" = 0;
"param_diag_showNonLocalizedStrings" = 0;
"param_diag_viewDebugging_enabled" = 1;
"param_diag_viewDebugging_insertDylibOnLaunch" = 1;
"param_install_style" = 2;
"param_launcher_UID" = 2;
"param_launcher_allowDeviceSensorReplayData" = 0;
"param_launcher_kind" = 0;
"param_launcher_style" = 99;
"param_launcher_substyle" = 0;
"param_lldbVersion_component_idx_1" = 0;
"param_lldbVersion_monotonic" = 170300230950;
"param_runnable_appExtensionHostRunMode" = 0;
"param_runnable_productType" = "com.apple.product-type.application";
"param_testing_launchedForTesting" = 0;
"param_testing_suppressSimulatorApp" = 0;
"param_testing_usingCLI" = 0;
"sdk_canonicalName" = "iphoneos26.0";
"sdk_osVersion" = "26.0";
"sdk_platformID" = 2;
"sdk_variant" = iphoneos;
"sdk_version_monotonic" = 2300527605;
}
System Information
macOS Version 15.5 (Build 24F74)
Xcode 26.0 (24141.31) (Build 17A5241o)
Timestamp: 2025-09-17T18:26:56+08:00
Starting with macOS 15 (Sequoia), applications that perform network discovery operations now trigger a permission prompt: "Allow [AppName] to find devices on local networks".
I am using sysctl() with NET_RT_FLAGS and RTF_LLINFO to access the ARP table and retrieve gateway MAC addresses:
int mib[6];
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO; // This flag accesses ARP table entries
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
return nil;
From my testing, the Local Network Access prompt does not always appear.
It looks like if the MAC address is already cached in the ARP table, no prompt is shown, and the prompt only appears when the system needs to resolve a new MAC address.
Is this correct behavior?
Does ARP resolution by itself triggering the prompt?
At WWDC 2015 Apple announced two major enhancements to the Network Extension framework:
Network Extension providers — These are app extensions that let you insert your code at various points within the networking stack, including:
Packet tunnels via NEPacketTunnelProvider
App proxies via NEAppProxyProvider
Content filters via NEFilterDataProvider and NEFilterControlProvider
Hotspot Helper (NEHotspotHelper) — This allows you to create an app that assists the user in navigating a hotspot (a Wi-Fi network where the user must interact with the network in order to get access to the wider Internet).
Originally, using any of these facilities required authorisation from Apple. Specifically, you had to apply for, and be granted access to, a managed capability. In Nov 2016 this policy changed for Network Extension providers. Any developer can now use the Network Extension provider capability like they would any other capability.
There is one exception to this rule: Network Extension app push providers, introduced by iOS 14 in 2020, still requires that Apple authorise the use of a managed capability. To apply for that, follow the link in Local push connectivity.
Also, the situation with Hotspot Helpers remains the same: Using a Hotspot Helper, requires that Apple authorise that use via a managed capability. To apply for that, follow the link in Hotspot helper.
IMPORTANT Pay attention to this quote from the documentation:
NEHotspotHelper is only useful for hotspot integration. There are
both technical and business restrictions that prevent it from being
used for other tasks, such as accessory integration or Wi-Fi based
location.
The rest of this document answers some frequently asked questions about the Nov 2016 change.
#1 — Has there been any change to the OS itself?
No, this change only affects the process by which you get the capabilities you need in order to use existing Network Extension framework facilities. Previously these were managed capabilities, meaning their use was authorised by Apple. Now, except for app push providers and Hotspot Helper, you can enable the necessary capabilities using Xcode’s Signing & Capabilities editor or the Developer website.
IMPORTANT Some Network Extension providers have other restrictions on their use. For example, a content filter can only be used on a supervised device. These restrictions are unchanged. See TN3134 Network Extension provider deployment for the details.
#2 — How exactly do I enable the Network Extension provider capability?
In the Signing & Capabilities editor, add the Network Extensions capability and then check the box that matches the provider you’re creating.
In the Certificates, Identifiers & Profiles section of the Developer website, when you add or edit an App ID, you’ll see a new capability listed, Network Extensions. Enable that capability in your App ID and then regenerate the provisioning profiles based on that App ID.
A newly generated profile will include the com.apple.developer.networking.networkextension entitlement in its allowlist; this is an array with an entry for each of the supported Network Extension providers. To confirm that this is present, dump the profile as shown below.
$ security cms -D -i NETest.mobileprovision
…
<plist version="1.0">
<dict>
…
<key>Entitlements</key>
<dict>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>packet-tunnel-provider</string>
<string>content-filter-provider</string>
<string>app-proxy-provider</string>
… and so on …
</array>
…
</dict>
…
</dict>
</plist>
#3 — I normally use Xcode’s Signing & Capabilities editor to manage my entitlements. Do I have to use the Developer website for this?
No. Xcode 11 and later support this capability in the Signing & Capabilities tab of the target editor (r. 28568128 ).
#4 — Can I still use Xcode’s “Automatically manage signing” option?
Yes. Once you modify your App ID to add the Network Extension provider capability, Xcode’s automatic code signing support will include the entitlement in the allowlist of any profiles that it generates based on that App ID.
#5 — What should I do if I previously applied for the Network Extension provider managed capability and I’m still waiting for a reply?
Consider your current application cancelled, and use the new process described above.
#6 — What should I do if I previously applied for the Hotspot Helper managed capability and I’m still waiting for a reply?
Apple will continue to process Hotspot Helper managed capability requests and respond to you in due course.
#7 — What if I previously applied for both Network Extension provider and Hotspot Helper managed capabilities?
Apple will ignore your request for the Network Extension provider managed capability and process it as if you’d only asked for the Hotspot Helper managed capability.
#8 — On the Mac, can Developer ID apps host Network Extension providers?
Yes, but there are some caveats:
This only works on macOS 10.15 or later.
Your Network Extension provider must be packaged as a system extension, not an app extension.
You must use the *-systemextension values for the Network Extension entitlement (com.apple.developer.networking.networkextension).
For more on this, see Exporting a Developer ID Network Extension.
#9 — After moving to the new process, my app no longer has access to the com.apple.managed.vpn.shared keychain access group. How can I regain that access?
Access to this keychain access group requires another managed capability. If you need that, please open a DTS code-level support request and we’ll take things from there.
IMPORTANT This capability is only necessary if your VPN supports configuration via a configuration profile and needs to access credentials from that profile (as discussed in the Profile Configuration section of the NETunnelProviderManager Reference). Many VPN apps don’t need this facility.
Opening a DTS tech support incident (TSI) will consume a TSI asset. However, as this is not a technical issue but an administrative one, we’ll assign a replacement TSI asset back to your account.
If you were previously granted the Network Extension managed capability (via the process in place before Nov 2016), make sure you mention that; restoring your access to the com.apple.managed.vpn.shared keychain access group should be straightforward in that case.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Revision History
2025-09-12 Adopted the code-level support request terminology. Made other minor editorial changes.
2023-01-11 Added a discussion of Network Extension app push providers. Added a link to Exporting a Developer ID Network Extension. Added a link to TN3134. Made significant editorial changes.
2020-02-27 Fixed the formatting. Updated FAQ#3. Made minor editorial changes.
2020-02-16 Updated FAQ#8 to account for recent changes. Updated FAQ#3 to account for recent Xcode changes. Made other editorial changes.
2016-01-25 Added FAQ#9.
2016-01-6 Added FAQ#8.
2016-11-11 Added FAQ#5, FAQ#6 and FAQ#7.
2016-11-11 First posted.
Hi.
We are writing to report a critical issue we've encountered following the recent release of iOS 26 beta 6.
After updating our test devices, we discovered that our application is no longer able to establish HTTPS connections to several of our managed FQDNs. This issue was not present in beta 5 and appears to be a direct result of changes introduced in beta 6.
The specific FQDNs that are currently unreachable are:
d.socdm.com
i.socdm.com
tg.scodm.com
We have reviewed the official iOS & iPadOS 26 Beta 6 Release Notes, particularly the updates related to TLS. While the notes mention changes, we have confirmed that our servers for all affected FQDNs support TLS 1.2, so we believe they should still be compliant.
We have also investigated several of Apple's support documents regarding TLS connection requirements (e.g., HT214774, HT214041), but the information does not seem to apply to our situation, and we are currently unable to identify the root cause of this connection failure.
https://support.apple.com/en-us/102028
https://support.apple.com/en-us/103214
Although we hope this issue might be resolved in beta 7 or later, the official release is fast approaching, and this has become a critical concern for us.
Could you please provide any advice or insight into what might be causing this issue? Any guidance on potential changes in the networking or security frameworks in beta 6 that could affect TLS connections would be greatly appreciated.
We have attached the relevant code snippet that triggers the error, along with the corresponding Xcode logs, for your review.
Thank you for your time and assistance.
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"https://i.socdm.com/sdk/js/adg-script-loader-b-stg.js"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:30.0];
[self sendWithRequest:req completionHandler:^(NSData *_Nullable data,
NSHTTPURLResponse *_Nonnull response,
NSError *_Nullable error) {
if (error){
NSLog(@"Error occurred: %@", error.localizedDescription);
return;
}else{
NSLog(@"Success! Status Code: %ld", (long)response.statusCode);
}
}];
}
- (void) sendWithRequest:(NSMutableURLRequest *)request
completionHandler:(void (^ _Nullable)(NSData *_Nullable data,
NSHTTPURLResponse *response,
NSError *_Nullable error))completionHandler {
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = nil;
session = [NSURLSession sessionWithConfiguration:configuration
delegate:self
delegateQueue:nil];
NSURLSessionTask *task = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
[session finishTasksAndInvalidate];
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
if (error) {
if (completionHandler) {
completionHandler(nil, httpResponse, error);
}
}
else {
if (completionHandler) {
completionHandler(data, httpResponse, nil);
}
}
}];
[task resume];
}
@end
error
Connection 1: default TLS Trust evaluation failed(-9807)
Connection 1: TLS Trust encountered error 3:-9807
Connection 1: encountered error(3:-9807)
Task <C50BB081-E1DA-40FF-A1E5-A03A2C4CB733>.<1> HTTP load failed, 0/0 bytes (error code: -1202 [3:-9807])
Task <C50BB081-E1DA-40FF-A1E5-A03A2C4CB733>.<1> finished with error [-1202] Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “i.socdm.com” which could put your confidential information at risk." UserInfo={NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, NSErrorPeerCertificateChainKey=(
"<cert(0x10621ca00) s: *.socdm.com i: GlobalSign RSA OV SSL CA 2018>",
"<cert(0x106324e00) s: GlobalSign RSA OV SSL CA 2018 i: GlobalSign>"
), NSErrorClientCertificateStateKey=0, NSErrorFailingURLKey=https://i.socdm.com/sdk/js/adg-script-loader-b-stg.js, NSErrorFailingURLStringKey=https://i.socdm.com/sdk/js/adg-script-loader-b-stg.js, NSUnderlyingError=0x1062bf960 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x10609d140>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9807, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9807, kCFStreamPropertySSLPeerCertificates=(
"<cert(0x10621ca00) s: *.socdm.com i: GlobalSign RSA OV SSL CA 2018>",
"<cert(0x106324e00) s: GlobalSign RSA OV SSL CA 2018 i: GlobalSign>"
)}}, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <C50BB081-E1DA-40FF-A1E5-A03A2C4CB733>.<1>"
), _kCFStreamErrorCodeKey=-9807, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <C50BB081-E1DA-40FF-A1E5-A03A2C4CB733>.<1>, NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x10609d140>, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “i.socdm.com” which could put your confidential information at risk.}
Error occurred: The certificate for this server is invalid. You might be connecting to a server that is pretending to be “i.socdm.com” which could put your confidential information at risk.
折りたたむ
Please ask Apple to provide an interface for sending follow-ups like Samsung's WiFi Aware.
Around 8/23/25, I installed macOS 15.6.1 on my work Mac. After this I can no longer log the application I am working on into our backend servers. My work Mac is running Palo Alto Global Protect VPN software along with a bunch of associated security software to lock down my computer. I had no issues with connecting to our backend servers behind the firewall before the macOS update and nothing has changed in the source code related to this. When I send the username the network call just hangs and never times out.
On the other hand, if I turn off the VPN and point to the production environment the call succeeds with no problems.
Any Ideas?
Hello,
I’m building an iOS application that supports peer-to-peer file transfer. My goal is to use the WebRTC data channel only (no audio or video) to send files between users.
I understand from Apple’s documentation that:
• Apps are generally suspended in the background, and arbitrary sockets (like WebRTC) do not continue running.
• Background file transfer is officially supported via URLSessionConfiguration.background, which the system manages reliably even if the app is suspended or terminated.
• VoIP use cases require CallKit + audio/VoIP background modes, and CallKit must be used for legitimate calls (audio/video).
What I want to confirm is:
Is it supported for a WebRTC peer connection using only the data channel (no audio/video track, no CallKit call) to continue sending data when the app is in the background or locked?
I considered using BGProcessingTask and BGAppRefreshTask, but as far as I can tell, those don’t allow maintaining long-lived sockets for active data transfer. Real-world developer discussions suggest that WebRTC connections are dropped when the app is backgrounded on iOS unless there’s at least one active audio track to keep the session alive.
Can someone from Apple confirm if my understanding is correct—that data-only WebRTC connections will be killed in background unless they’re part of an active audio/video call with the appropriate entitlements?
Thanks in advance!
iOS Development environment
Xcode 16.4, macOS 15.6.1 (24G90)
Run-time configuration: iOS 17.2+
Short Description
After having successfully established an NWConnection (either as UDP or TCP), and subsequently receiving the error code:
UDP Connection failed: 57 The operation couldn't be completed. (Network.NWError error 57 - Socket is not connected), available Interfaces: [enO]
via
NWConnection.stateUpdateHandler = { (newState) in ... } while newState == .failed
the data connection does not restart by itself once cellular (RF) telephony coverage is established again.
Detailed Description
Context: my app has a continuous cellular data connection while in use. Either a UDP or a TCP connection is established depending on the user settings.
The setup data connection works fine until the data connection gets disconnected by loss of connection to a available cellular phone base station. This disconnection simply occurs in very poor UMTS or GSM cellular phone coverage. This is totally normal behavior in bad reception areas like in mountains with signal loss.
STEPS TO REPRODUCE
Pre-condition
App is running with active data connection.
Action
iPhone does loss the cellular data connection previously setup. Typically reported as network error code 57.
Observed
The programmed connection.stateUpdateHandler() is called in network connection state '.failed' (OK).
The self-programmed data re-connection includes:
a call to self.connection.cancel()
a call to self.setupUDPConnection() or self.setupConnection() depending on the user settings to re-establish an operative data connection.
However, the iPhone's UMTS/GSM network data (re-)connection state is not properly identified/notified via NWConnection API. There's no further network state notification by means of NWConnection even though the iPhone has recovered a cellular data network.
Expected
The iPhone or any other means automatically reconnects the interrupted data connection on its own. The connection.stateUpdateHandler() is called at time of the device's networking data connection (RF) recovering, subsequently to a connection state failed with error code 57, as the RF module is continuously (independently from the app) for available telephony networks.
QUESTION
How to systematically/properly detect a cellular phone data network reconnection readiness in order to causally reinitialize the NWConnection data connection available used in app.
Relevant code extract
Setup UDP connection (or similarly setup a TCP connection)
func setupUDPConnection() {
let udp = NWProtocolUDP.Options.init()
udp.preferNoChecksum = false
let params = NWParameters.init(dtls: nil, udp: udp)
params.serviceClass = .responsiveData // service type for medium-delay tolerant, elastic and inelastic flow, bursty, and long-lived connections
connection = NWConnection(host: NWEndpoint.Host.name(AppConstant.Web.urlWebSafeSky, nil), port: NWEndpoint.Port(rawValue: AppConstant.Web.urlWebSafeSkyPort)!, using: params)
connection.stateUpdateHandler = { (newState) in
switch (newState) {
case .ready:
//print("UDP Socket State: Ready")
self.receiveUDPConnection(). // data reception works fine until network loss
break
case .setup:
//print("UDP Socket State: Setup")
break
case .cancelled:
//print("UDP Socket State: Cancelled")
break
case .preparing:
//print("UDP Socket State: Preparing")
break
case .waiting(let error):
Logger.logMessage(message: "UDP Connection waiting: "+error.errorCode.description+" \(error.localizedDescription), available Interfaces: \(self.connection.currentPath!.availableInterfaces.description)", LoggerLevels.Error)
break
case .failed(let error):
Logger.logMessage(message: "UDP Connection failed: "+error.errorCode.description+" \(error.localizedDescription), available Interfaces: \(self.connection.currentPath!.availableInterfaces.description)", LoggerLevels.Error)
// data connection retry (expecting network transport layer to be available)
self.reConnectionServer()
break
default:
//print("UDP Socket State: Waiting or Failed")
break
}
self.handleStateChange()
}
connection.start(queue: queue)
}
Handling of network data connection loss
private func reConnectionServer() {
self.connection.cancel()
// Re Init Connection - Give a little time to network recovery
let delayInSec = 30.0. // expecting actually a notification for network data connection availability, instead of a time-triggered retry
self.queue.asyncAfter(deadline: .now() + delayInSec) {
switch NetworkConnectionType {
case 1:
self.setupUDPConnection() // UDP
break
case 2:
self.setupConnection() // TCP
break
default:
break
}
}
}
Does it necessarily require the use of CoreTelephony class CTTelephonyNetworkInfo or class CTCellularData to get notifications of changes to the user’s cellular service provider?
In iOS 26, should we have bootloader that runs the repo on startup - or should we have that inside tasks in root view?
we have repos that runs as a «closed» functions, we dont throw but updates swiftdata and we use @query in the views. So what is best?
and for the repo we should have a repo that runs the upserts manage relations eg? Should that run on a modelactor?
Hi Apple Development forums,
I am having trouble getting a Wireguard VPN config setup to automatically disconnect on all domain requests other than one specific domain.
I have my .mobileconfig designed as so:
<dict>
<key>Action</key>
<string>EvaluateConnection</string>
<key>ActionParameters</key>
<array>
<dict>
<key>Domains</key>
<array>
<string>service.domainname.com</string>
</array>
<key>DomainAction</key>
<string>ConnectIfNeeded</string>
<key>ProbeURL</key>
<string>https://service.domainname.com/</string>
</dict>
</array>
</dict>
<dict>
<key>Action</key>
<string>Disconnect</string>
<key>DNSDomainMatch</key>
<array>
<string>*.com</string>
<string>*.org</string>
<string>*.net</string>
</array>
</dict>
<dict>
<key>Action</key>
<string>Disconnect</string>
</dict>
</array>
The issue I'm having is regardless of whether I note a *.com or simply have the action Disconnect noted - the VPN stays connected after navigating to https://service.domainname.com.
would anyone have any thoughts on this? Or am I missing something here?
I have an app with lots of networking calls that are currently done through URLSession. We would like to implement the new carried constrained entitlements and begin moving data through the ultra constrained network path for core features of our application. I have successfully implemented the NWPathMonitor to identify when the current network path is ultra constrained and I have been consistently on a physical device in a real world environment.
I'm aware that we will not be able to use URLSession to do this from other posts in this forum like this one. Because of this problem with URLSession I am attempting to fallback to using NWConnection when the current path is ultra constrained. I have setup a NWConnection with the NWParameters.allowUltraConstrainedPaths set to true. The request works perfectly when connected to wifi or cellular. However, it does not work at all when the current path is ultra constrained. When attempting this request through my NWConnection I receive an error that says:
The operation couldn’t be completed. (Network.NWError error 50 - Network is down)
Is this expected? I have confirmed my physical device is connecting to carrier provided satellite and I have been able to load data in other ios apps from Apple like the music app while on this carrier constrained connection. If this is not the correct way to move data when the path is ultra constrained what is the correct way?
Furuno AP(EW750) is sending EAPOL M1 message, but Iphone16 is not responding with EAPOL M2 message, Hence Iphone16 is unable to connect to Qualcomm based AP with MLO suiteb encryption.
Issue impact: All the Iphone16 users cannot connect to WiFi7 AP with MLO suiteb encryption globally. Predominantly, Iphone users tend to connect to more secured wifi networks using WPA3 suiteb encryption, hence many of the iphone users will experience the connectivity issue significantly.
Topology:
AP Hardware: Furuno WiFi7 AP(EW770) The Furuno WiFi7 AP uses Miami IPQ5332 with waikiki radio QCN9274 (Qualcomm based chipset)
AP software: SPF12.2 CSU3
IPhone16 software: (18.3.1 or 18.5 ) I
phone16 wifi capabilities: 802.11 b/a/g/n/ac/ax/be
Radius server details: Radius server:
Laptop running with Ubuntu Radius package: 3.0.26dfsggit20220223.1.00ed0241fa-0ubuntu3.4 Version: 3.0.26
Steps:
Power on the Wi-Fi 7 Access Point with the Miami chipset, and flash it with the SPF 12.2 CSU3 image.
Enable both 5 GHz and 6 GHz radios on the AP.
Enable MLO (Multi-Link Operation) in 6Ghz & 5Ghz, set MLD address different from radio address and configure Suite-B (192-bit) encryption
On the Linux laptop, set up the RADIUS server with EAP-TLS authentication method.
Once the above steps are completed, take the iPhone 16 and follow the steps below to install the RADIUS client certificates on the device.
On the sniffer laptop, switch the Wi-Fi adapter to monitor mode, configure the required channel, and begin packet capture.
Check SSID is broadcasting, then connect the iPhone 16 to .
Verify if the client (iPhone 16) connects to the SSID using WPA3-Enterprise, MLO, and Suite-B encryption by checking the wireless capture on both the AP and iPhone sides.
Support needed from Apple team: We would request Apple team to analyse and enable the IPhone16 users to connect to advanced security WPA3 Suiteb by resolving the issue.
Below is our analysis and observation for your reference.
As per IEEE, MLD mac address can be set to the same or different from radio address, Iphone16 is not accepting EAPOL M1 message if source address(MLD) is different from radio address.
IPhone16 is accepting EAPOL M1 if the source address(MLD) is set to the same as the radio address and responds with M2 message
IPhone16 is not accepting EAPOL M1 if source address(MLD) set to different from radio address and fails to respond with M2 message.
sysdiagnose.log
log-file
log-file
Please let us know additional logs are required.
For important background information, read Extra-ordinary Networking before reading this.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Broadcasts and Multicasts, Hints and Tips
I regularly see folks struggle with broadcasts and multicasts on Apple platforms. This post is my attempt to clear up some of the confusion.
This post covers both IPv4 and IPv6. There is, however, a key difference. In IPv4, broadcasts and multicasts are distinct concepts. In contrast, IPv6 doesn’t support broadcast as such; rather, it treats broadcasts as a special case of multicasts. IPv6 does have an all nodes multicast address, but it’s rarely used.
Before reading this post, I suggest you familiarise yourself with IP addresses in general. A good place to start is The Fount of All Knowledge™.
Service Discovery
A lot of broadcast and multicast questions come from folks implementing their own service discovery protocol. I generally recommend against doing that, for the reasons outlined in the Service Discovery section of Don’t Try to Get the Device’s IP Address.
There are, however, some good reasons to implement a custom service discovery protocol. For example, you might be working with an accessory that only supports this custom protocol [1]. If you must implement your own service discovery protocol, read this post and also read the advice in Don’t Try to Get the Device’s IP Address.
IMPORTANT Sometimes I see folks implementing their own version of mDNS. This is almost always a mistake:
If you’re using third-party tooling that includes its own mDNS implementation, it’s likely that this tooling allows you to disable that implementation and instead rely on the Bonjour support that’s built-in to all Apple platforms.
If you’re doing some weird low-level thing with mDNS or DNS-SD, it’s likely that you can do that with the low-level DNS-SD API.
[1] And whose firmware you can’t change! I talk more about this in Working with a Wi-Fi Accessory.
API Choice
Broadcasts and multicasts typically use UDP [1]. TN3151 Choosing the right networking API describes two recommended UDP APIs:
Network framework
BSD Sockets
Our general advice is to prefer Network framework over BSD Sockets, but UDP broadcasts and multicasts are an exception to that rule. Network framework has very limited UDP broadcast support. And while it’s support for UDP multicasts is less limited, it’s still not sufficient for all UDP applications. In cases where Network framework is not sufficient, BSD Sockets is your only option.
[1] It is possible to broadcast and multicast at the Ethernet level, but I almost never see questions about that.
UDP Broadcasts in Network Framework
Historically I’ve claimed that Network framework was useful for UDP broadcasts is very limited circumstances (for example, in the footnote on this post). I’ve since learnt that this isn’t the case. Or, more accurately, this support is so limited (r. 122924701) as to be useless in practice.
For the moment, if you want to work with UDP broadcasts, your only option is BSD Sockets.
UDP Multicasts in Network Framework
Network framework supports UDP multicast using the NWConnectionGroup class with the NWMulticastGroup group descriptor. This support has limits. The most significant limit is that it doesn’t support broadcasts; it’s for multicasts only.
Note This only relevant to IPv4. Remember that IPv6 doesn’t support broadcasts as a separate concept.
There are other limitations, but I don’t have a good feel for them. I’ll update this post as I encounter issues.
Local Network Privacy
Some Apple platforms support local network privacy. This impacts broadcasts and multicasts in two ways:
Broadcasts and multicasts require local network access, something that’s typically granted by the user.
Broadcasts and multicasts are limited by a managed entitlement (except on macOS).
TN3179 Understanding local network privacy has lots of additional info on this topic, including the list of platforms to which it applies.
Send, Receive, and Interfaces
When you broadcast or multicast, there’s a fundamental asymmetry between send and receive:
You can reasonable receive datagrams on all broadcast-capable interfaces.
But when you send a datagram, it has to target a specific interface.
The sending behaviour is the source of many weird problems. Consider the IPv4 case. If you send a directed broadcast, you can reasonably assume it’ll be routed to the correct interface based on the network prefix. But folks commonly send an all-hosts broadcast (255.255.255.255), and it’s not obvious what happens in that case.
Note If you’re unfamiliar with the terms directed broadcast and all-hosts broadcast, see IP address.
The exact rules for this are complex, vary by platform, and can change over time. For that reason, it’s best to write your broadcast code to be interface specific. That is:
Identify the interfaces on which you want to work.
Create a socket per interface.
Bind that socket to that interface.
Note Use the IP_BOUND_IF (IPv4) or IPV6_BOUND_IF (IPv6) socket options rather than binding to the interface address, because the interface address can change over time.
Extra-ordinary Networking has links to other posts which discuss these concepts and the specific APIs in more detail.
Miscellaneous Gotchas
A common cause of mysterious broadcast and multicast problems is folks who hard code BSD interface names, like en0. Doing that might work for the vast majority of users but then fail in some obscure scenarios.
BSD interface names are not considered API and you must not hard code them. Extra-ordinary Networking has links to posts that describe how to enumerate the interface list and identify interfaces of a specific type.
Don’t assume that there’ll be only one interface of a given type. This might seem obviously true, but it’s not. For example, our platforms support peer-to-peer Wi-Fi, so each device has multiple Wi-Fi interfaces.
When sending a broadcast, don’t forget to enable the SO_BROADCAST socket option.
If you’re building a sandboxed app on the Mac, working with UDP requires both the com.apple.security.network.client and com.apple.security.network.server entitlements.
Some folks reach for broadcasts or multicasts because they’re sending the same content to multiple devices and they believe that it’ll be faster than unicasts. That’s not true in many cases, especially on Wi-Fi. For more on this, see the Broadcasts section of Wi-Fi Fundamentals.
Snippets
To send a UDP broadcast:
func broadcast(message: Data, to interfaceName: String) throws {
let fd = try FileDescriptor.socket(AF_INET, SOCK_DGRAM, 0)
defer { try! fd.close() }
try fd.setSocketOption(SOL_SOCKET, SO_BROADCAST, 1 as CInt)
let interfaceIndex = if_nametoindex(interfaceName)
guard interfaceIndex > 0 else { throw … }
try fd.setSocketOption(IPPROTO_IP, IP_BOUND_IF, interfaceIndex)
try fd.send(data: message, to: ("255.255.255.255", 2222))
}
Note These snippet uses the helpers from Calling BSD Sockets from Swift.
To receive UDP broadcasts:
func receiveBroadcasts(from interfaceName: String) throws {
let fd = try FileDescriptor.socket(AF_INET, SOCK_DGRAM, 0)
defer { try! fd.close() }
let interfaceIndex = if_nametoindex(interfaceName)
guard interfaceIndex > 0 else { fatalError() }
try fd.setSocketOption(IPPROTO_IP, IP_BOUND_IF, interfaceIndex)
try fd.setSocketOption(SOL_SOCKET, SO_REUSEADDR, 1 as CInt)
try fd.setSocketOption(SOL_SOCKET, SO_REUSEPORT, 1 as CInt)
try fd.bind("0.0.0.0", 2222)
while true {
let (data, (sender, port)) = try fd.receiveFrom()
…
}
}
IMPORTANT This code runs synchronously, which is less than ideal. In a real app you’d run the receive asynchronously, for example, using a Dispatch read source. For an example of how to do that, see this post.
If you need similar snippets for multicast, lemme know. I’ve got them lurking on my hard disk somewhere (-:
Other Resources
Apple’s official documentation for BSD Sockets is in the man pages. See Reading UNIX Manual Pages. Of particular interest are:
setsockopt man page
ip man page
ip6 man page
If you’re not familiar with BSD Sockets, I strongly recommend that you consult third-party documentation for it. BSD Sockets is one of those APIs that looks simple but, in reality, is ridiculously complicated. That’s especially true if you’re trying to write code that works on BSD-based platforms, like all of Apple’s platforms, and non-BSD-based platforms, like Linux.
I specifically recommend UNIX Network Programming, by Stevens et al, but there are lots of good alternatives.
https://unpbook.com
Revision History
2025-09-01 Fixed a broken link.
2025-01-16 First posted.
Hello,
I have a Cocoa application from which I fork a new process (helper sort of) and it crashes on fork due to some cleanup code probably registered with pthreads_atfork() in Network framework.
This is crash from the child process:
Application Specific Information:
*** multi-threaded process forked ***
BUG IN CLIENT OF LIBPLATFORM: os_unfair_lock is corrupt
Abort Cause 258
crashed on child side of fork pre-exec
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_platform.dylib 0x194551238 _os_unfair_lock_corruption_abort + 88
1 libsystem_platform.dylib 0x19454c788 _os_unfair_lock_lock_slow + 332
2 Network 0x19b1b4af0 nw_path_shared_necp_fd + 124
3 Network 0x19b1b4698 -[NWConcrete_nw_path_evaluator dealloc] + 72
4 Network 0x19af9d970 __nw_dictionary_dispose_block_invoke + 32
5 libxpc.dylib 0x194260210 _xpc_dictionary_apply_apply + 68
6 libxpc.dylib 0x19425c9a0 _xpc_dictionary_apply_node_f + 156
7 libxpc.dylib 0x1942600e8 xpc_dictionary_apply + 136
8 Network 0x19acd5210 -[OS_nw_dictionary dealloc] + 112
9 Network 0x19b1beb08 nw_path_release_globals + 120
10 Network 0x19b3d4fa0 nw_settings_child_has_forked() + 312
11 libsystem_pthread.dylib 0x100c8f7c8 _pthread_atfork_child_handlers + 76
12 libsystem_c.dylib 0x1943d9944 fork + 112
(...)
I'm trying to create a child process with boost::process::child which does basically just a fork() followed by execv() and I do it before the - [NSApplication run] is called.
Is it know bug or behavior which I've run into? Also what is a correct way to spawn child processes in Cocoa applications? As far as my understanding goes the basically all the available APIs (e.g. posix, NSTask) should be more or less the same thing calling the same syscalls. So forking the process early before main run loop starts and not starting another NSApplication in forked child should be ok ...or not?
Development environment
Xcode 26.0 Beta 6
iOS 26 Simulator
macOS 15.6.1
To verify TLS 1.3 session resumption behavior in URLSession, I configured URLSessionConfiguration as follows and sent an HTTP GET request:
let config = URLSessionConfiguration.ephemeral
config.tlsMinimumSupportedProtocolVersion = .TLSv13
config.tlsMaximumSupportedProtocolVersion = .TLSv13
config.httpMaximumConnectionsPerHost = 1
config.httpAdditionalHeaders = ["Connection": "close"]
config.enablesEarlyData = true
let session = URLSession(configuration: config, delegate: nil, delegateQueue: nil)
let url = URL(string: "https://www.google.com")!
var request = URLRequest(url: url)
request.assumesHTTP3Capable = true
request.httpMethod = "GET"
let task = session.dataTask(with: request) { data, response, error in
if let error = error {
print("Error during URLSession data task: \(error)")
return
}
if let data = data, let responseString = String(data: data, encoding: .utf8) {
print("Received data via URLSession: \(responseString)")
} else {
print("No data received or data is not UTF-8 encoded")
}
}
task.resume()
However, after capturing the packets, I found that the ClientHello packet did not include the early_data extension.
It seems that enablesEarlyData on URLSessionConfiguration is not being applied.
How can I make this work properly?
I'm currently exploring Instruments for profiling and tracing on macOS 15.6.1. I know there is the "network connections" instrument which records TCP/UDP information, however it seems to not include the "lo0" (loopback) interface.
Is there a way to configure it so that localhost traffic is included in the recording? as the application I'm tracing uses that and I want that information to be included in traces.
The documentation for network-interface-detection schema makes no mention of how it detects interfaces.
Thanks in advance.
I investigated what network interface names are assigned to carrier networks on a dual SIM iPhone by examining the output of getifaddrs(). (An part of the program used for this is provided below.)
//////////////
struct ifaddrs *interfaces = NULL;
struct ifaddrs *an_interface = NULL;
if (0 == getifaddrs(&interfaces)) {
an_interface = interfaces;
while (an_interface != NULL) {
if( an_interface->ifa_addr->sa_family == AF_INET) {
NSString* name = [NSString stringWithUTF8String:an_interface->ifa_name];
NSLog(@"Interface name is: %@", name);
}
an_interface = an_interface->ifa_next;
}
}
freeifaddrs(interfaces);
In this investigation, it appeared that the interface name for the sXGP SIM selected under "iPhone > Settings > Cellular > Cellular Data" was always "pdp_ip0".
(A screenshot of "Cellular Data" is provided below. this is sample of sXGP selected )"
[QUESTION]
Is the SIM selected in Settings of iPhone always assigned to "pdp_ip0"?
[BACKGROUND]
I am developing a VoIP application and opening sockets by specifying IP addresses for communication.
On a dual SIM iPhone, multiple networks (IP addresses) are visible. Therefore, I need to determine which network to use. My question is whether I can reliably make this decision based on the network interface name.
If the SIM selected in Settings is always assigned to "pdp_ip0", I intend to open the socket using the IP address of "pdp_ip0".
Alternatively, should I use a different method to select the appropriate network interface?
It's not yet fully clear why and when does this crash occur, but I'm creating this post so there's a centralized thread for this.
Some hints collected so far:
The crash is occurring for existing Xcode projects opened with new Xcode 26.0 beta (17A5241e); no one's been able to reproduce on a project created in Xcode 26. I even tried creating a project with Xcode 16.2 and open it in Xcode 26, but it's all working fine there (don't have older Xcode at the moment, to try with many versions)
It crashes right at the line of code that initializes URLSessionConfiguration. If you call URLSession() without parameters (which is deprecated as of iOS 13), the session initializes without the crash.
It's NOT occurring only for libraries installed through package manages. In a project where it crashes, one should be able to reproduce by adding URLSessionConfiguration.default as the first line in didFinishLaunchingWithOptions
It crashes when running an app on an iOS 26 simulator. (I don't have a device running beta iOS 26 to test on it!) It's working fine when running the app on a simulator or a device running iOS 18 or older.
Related issue on Firebase GitHub repo: https://github.com/firebase/firebase-ios-sdk/issues/14948
Sorry to not be able to provide more info at the moment. I wanted to report this so in case someone from Apple knows about it, we could at least get some feedback or workarounds, until fix is released -- and, to prevent us all from duplicating this report in repositories of each library, as this isn't related to libraries.