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.
Moving to Fewer, Larger Transfers forums post
Testing Background Session Code forums post
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
NWEndpoint History and Advice 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).
WWDC 2017 Session 701 Your Apps and Evolving Network Security Standards [1] — This is generally interesting, but the section starting at 17:40 is, AFAIK, the best information from Apple about how certificate revocation works on modern systems.
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 forums post
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] This video is no longer available from Apple, but the URL should help you locate other sources of this info.
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
Hi,
After the release of macOS Tahoe 26.2. We are seeing memory leaks if our Network Protection Extension is used alongside the Apple Built In Firewall, a second Security Solution that does Network Protection and a VPN. Our NEXT, socketfilterfw and the other security solution consume instead of a few MB of Memory now multiple Gigabytes of Memory. This issue started with the public release of macOS Tahoe 26.2, this issue was not present in earlier versions of macOS and the same set of Software. Just testing our solution by itself will not show this behavior. I unfortunately can't try to reproduce the issue on my test device that runs the latest 26.3 beta as I do not have the third party software installed there and I can't get it.
Our Network extension implements depending on the license and enabled features:
NEFilterDataProvider
NEDNSProxyProvider
NETransparentProxyProvider
For all man in the middle Use Cases we are using Network Framework, to communicate with the peers. And leaks suggest that the there is a memory leak within internals of the Network Framework.
Here is a shortened sample of the leaks output of our Network extension. However, the third party NEXT does show the same leaks.
More details can be found on the Feedback with the ID FB21649104
snippet is blocking post? sensitive language
Does anyone see similar issues or has an idea what could cause this issue, except a regression of the Network.framework introduced with macOS Tahoe 26.2?
Best Regards,
Timo
We are developing a macOS VPN application using NEPacketTunnelProvider with a custom encryption protocol.
We are using standard On-Demand VPN rules with Wi-Fi SSID matching but we want to add some additional feature to the native behaviour.
We want to control the 'conenect/disconnect' button status and allow the user to interact with the tunnel even when the on demand rule conditions are satisfied, is there a native way to do it?
In case we need to implement our custom on-demand behaviour we need to access to this information:
connected interface type
ssid name
and being informed when it changes so to trigger our logic, how to do it from the app side?
we try to use CWWiFiClient along with ssidDidChangeForWiFiInterface monitoring, it returns just the interface name en0 and not the wifi ssid name.
Is location access mandatory to access wifi SSID on macOS even if we have a NEPacketTunnelProvider?
Please note that we bundle our Network Extension as an App Extension (not SystemExtension).
Hello,
I have a .app NSApplication which is ran as a LaunchDaemon, in it's lifecycle I never call any AppKit functions (I start it with CFRunLoopRun). (mentioned on this post as well).
I intercept a couple of signals using signal(s) in order to trigger CFRunLoopStop(CFRunLoopGetCurrent()) to do some cleanup.
This LaunchDaemon has the purpose of providing VPN connectivity, as such I call connect functions that trigger the "Add VPN configuration" dialog (I can't provide extra details about this, as I integrate another SDK so I'm not sure what happens under the hood) and I noticed that whenever it is displayed, after allowing it, during the lifecycle of the application when it's time to send the signal, the signal isn't received.
I tried re-adding the NSApp callbacks in order to investigate, but it looks like those aren't called as well.
I'm interested in knowing more about this scenario and what happens... I couldn't really find information about this dialog...
Thanks!
Hello,
I have an app that is using iOS 26 Network Framework APIs.
It is using QUIC, TLS 1.3 and Bonjour. For TLS I am using a PKCS#12 identity.
All works well and as expected if the devices (iPhone with no cellular, iPhone with cellular, and iPad no cellular) are all on the same wifi network.
If I turn off my router (ie no more wifi network) and leave on the wifi toggle on the iOS devices - only the non cellular iPhone and iPad are able to discovery and connect to each other. My iPhone with cellular is not able to.
By sharing my logs with Cursor AI it was determined that the connection between the two problematic peers (iPad with no cellular and iPhone with cellular) never even makes it to the TLS step because I never see the logs where I print out the certs I compare.
I tried doing "builder.requiredInterfaceType(.wifi)" but doing that blocked the two non cellular devices from working. I also tried "builder.prohibitedInterfaceTypes([.cellular])" but that also did not work.
Is AWDL on it's way out? Should I focus my energy on Wi-Fi Aware?
Regards,
Captadoh
When installing a new version the app while a tunnel is connected, seemingly the old packet tunnel process gets stopped but the new one does not come back up. Reportedly, a path monitor is reporting that the device has no connectivity. Is this the expected behavior?
When installing an update from TestFlight or the App store, the packet tunnel instance from the old tunnel is stopped, but, due to the profile being on-demand and incldueAllNetworks, the path monitoring believes the device has no connectivity - so the new app is never downloaded. Is this the expected behavior?
During development, the old packet tunnel gets stopped, the new app is installed, but the new packet tunnel is never started. To start it, the user has to toggle the VPN twice from the Settings app. The tunnel could be started from the VPN app too, if we chose to not take the path monitor into account, but then the user still needs to attempt to start the tunnel twice - it only works on the second try. As far as we can tell, the first time around, the packet tunnel never gets started, the app receives an update about NEVPNStatus being set to disconnecting yet NEVPNConnection does not throw.
The behavior I was naively expecting was that the packet tunnel process would be stopped only when the new app is fully downloaded and when the update is installed, Are we doing something horribly wrong here?
I want to know the right way/API/usage to use NWConnectionGroup to send both datagram and non-datagram stream.
I am currently working on an P2P video streaming app. I want to leverage NWConnectionGroup over QUIC to handle both message channel (traditionally handled by a TCP connection) and media channel (traditionally handled by sth. over UDP) to transmit SRT packets back and forth.
I created a NWConnectionGroup and it worked fine on non-datagram parts. The problems are with datagram part. I tried
extracting a connection with datagram = true either from the group or from message, doesn't and in some cases it breaks other non-datagram connections.
I currently send datagram directly using the NWConnectionGroup.send(content:completion). It kinda works but I keep seeing it canceled a lot of messages, which breaks SRT shortly after start. The warnings belong flooded my console. (Seems like want me to create a connection to transmit datagram, how?)
nw_connection_create_with_connection [C1600] Original connection not yet connected
nw_connection_group_create_connection_for_endpoint_and_parameters [G1] failed to create connection with parameters quic, local: fe80::439:68b4:6ec2:694%en0.60517, definite, attribution: developer, server
I must use it in wrong way. What should I do to fix it?
I have an app that has been using the following code to down load audio files:
if let url = URL(string: episode.fetchPath()) {
var request = URLRequest(url: url)
request.httpMethod = "get"
let task = session.downloadTask(with: request)
And then the following completionHandler code:
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
try FileManager.default.moveItem(at: location, to: localUrl)
In the spirit of modernization, I'm trying to update this code to use async await:
var request = URLRequest(url: url)
request.httpMethod = "get"
let (data, response) = try await URLSession.shared.data(for: request)
try data.write(to: localUrl, options: [.atomicWrite, .completeFileProtection])
Both these code paths use the same url value. Both return the same Data blobs (they return the same hash value)
Unfortunately the second code path (using await) introduces a problem. When the audio is playing and the iPhone goes to sleep, after 15 seconds, the audio stops. This problem does not occur when running the first code (using the didFinish completion handler)
Same data, stored in the same URL, but using different URLSession calls. I would like to use async/await and not have to experience the audio ending after just 15 seconds of the device screen being asleep. any guidance greatly appreciated.
Topic:
App & System Services
SubTopic:
Networking
Tags:
Files and Storage
Network
CFNetwork
Background Tasks
Hi everyone 👋
As a network engineer and indie iOS developer, I couldn’t find a lightweight mobile tool that fully supports IPv4/IPv6 dual-stack diagnostics — so I built NetToolbox -All-In-One Utility for engineers, DevOps, and developers.
Here are its core features that solve real mobile networking pain points:
One-Click Full Diagnostics: Integrates ping, traceroute, and multi-type DNS queries (A/AAAA/CNAME) — no need to switch between apps
IPv4/IPv6 Dual-Stack Support: Seamlessly works in IPv6-only networks, with the ability to test connectivity differences between dual-stack environments
LAN Device Scanning: Quickly identifies all devices on the same network segment and checks port availability
Offline Functionality: Diagnostic logic is stored locally, enabling LAN troubleshooting without an internet connection
Lightweight Design: 5MB install size, no storage bloat, and low power consumption during operation
Dark Mode Support: Tailored for developers who work late at night
During development, I leveraged Apple Intelligence alongside Claude Code and Gemini 3 to accelerate the process, optimize iOS native networking stack adaptation and local storage logic, and significantly boost development efficiency.
I’d love to hear from the community:
What must-have features are missing from mobile network diagnostic tools?
Do you have experience optimizing iOS workflows with Apple Intelligence?
👉 You can try the app here:
https://apps.apple.com/us/app/nettoolbox-all-in-one-utility/id6757392404
Feedback is highly appreciated — I’ll keep iterating to make it better! 🚀
Topic:
App & System Services
SubTopic:
Networking
Tags:
Developer Tools
Network Extension
Network
Apple Intelligence
Apple supports Wi‑Fi Aware, but it’s not clear what channel bandwidth Apple’s Wi‑Fi Aware uses. Is it 80 MHz or 40 MHz? Also, what is the channel bandwidth used by AirDrop?
For a long time our app had this creation of a URLRequest:
var urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeout)
But since iOS 26 was released we started to get crashes in this call. It is created on a background thread.
Thread 10 Crashed:
0 libsystem_malloc.dylib 0x00000001920e309c _xzm_xzone_malloc_freelist_outlined + 864 (xzone_malloc.c:1869)
1 libswiftCore.dylib 0x0000000184030360 swift::swift_slowAllocTyped(unsigned long, unsigned long, unsigned long long) + 56 (Heap.cpp:110)
2 libswiftCore.dylib 0x0000000184030754 swift_allocObject + 136 (HeapObject.cpp:245)
3 Foundation 0x00000001845dab9c specialized _ArrayBuffer._consumeAndCreateNew(bufferIsUnique:minimumCapacity:growForAppend:) + 120
4 Foundation 0x00000001845daa58 specialized static _SwiftURL._makeCFURL(from:baseURL:) + 2288 (URL_Swift.swift:1192)
5 Foundation 0x00000001845da118 closure #1 in _SwiftURL._nsurl.getter + 112 (URL_Swift.swift:64)
6 Foundation 0x00000001845da160 partial apply for closure #1 in _SwiftURL._nsurl.getter + 20 (<compiler-generated>:0)
7 Foundation 0x00000001845da0a0 closure #1 in _SwiftURL._nsurl.getterpartial apply + 16
8 Foundation 0x00000001845d9a6c protocol witness for _URLProtocol.bridgeToNSURL() in conformance _SwiftURL + 196 (<compiler-generated>:974)
9 Foundation 0x000000018470f31c URLRequest.init(url:cachePolicy:timeoutInterval:) + 92 (URLRequest.swift:44)# Live For Studio
Any idea if this crash is caused by our code or if it is a known problem in iOS 26?
I have attached one of the crash reports from Xcode:
2025-10-08_10-13-45.1128_+0200-8acf1536892bf0576f963e1534419cd29e6e10b8.crash
As part of the OpenJDK testing we run several regression tests, including for Java SE networking APIs. These APIs ultimately end up calling BSD socket functions. On macos, starting macos 26, including on recent 26.2 version, we have started seeing some unexplained but consistent exception from one of these BSD socket APIs. We receive a "ENOBUFS" errno (No buffer space available) when trying to construct a socket(). These exact same tests continue to pass on many other older versions of macos (including 15.7.x). After looking into this more, we have been able to narrow this down to a very trivial C code which is as follows (also attached):
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <sys/errno.h>
static int create_socket(const int attempt_number) {
const int fd = socket(AF_INET6, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "socket creation failed on attempt %d,"
" due to: %s\n", attempt_number, strerror(errno));
return fd;
}
return fd;
}
int main() {
const unsigned int num_times = 250000;
for (unsigned int i = 1; i <= num_times; i++) {
const int fd = create_socket(i);
if (fd < 0) {
return -1;
}
close(fd);
}
fprintf(stderr, "successfully created and closed %d sockets\n", num_times);
}
The code very trivially creates a socket() and close()s it. It does this repeatedly in a loop for a certain number of iterations.
Compiling this as:
clang sockbufspaceerr.c -o sockbufspaceerr.o
and running it as:
./sockbufspaceerr.o
consistently generates an error as follows on macos 26.x:
socket creation failed on attempt 160995, due to: No buffer space available
The iteration number on which the socket() creation fails varies, but the issue does reproduce. Running the same on older versions of macos doesn't reproduce the issue and the program terminates normally after those many iterations.
Looking at the xnu source that is made available for each macos release here https://opensource.apple.com/releases/, I see that for macos 26.x there have been changes in this kernel code and there appears to be some kind of memory accountability code introduced in this code path. However, looking at the reproducer/application code in question, I believe it uses the right set of functions to both create as well as release the resources, so I can't see why this should cause the above error in macos 26.x.
Does this look like some issue that needs attention in the macos kernel and should I report it through feedback assitant tool?
After App uses Network.framework PrivacyContext Api, dns has been encrypted, that is good.
But when using wkwebview to load web page, wireshark captures normal dns request sent by wkwebview.
Does wkwebview use DoH to resolve domain? if can, how to config params?
If can not, is there anyway to stop wkwebview sending normal dns, such as local proxy.
We would be creating N NWListener objects and M NWConnection objects in our process' communication subsystem to create server sockets, accepted client sockets on server and client sockets on clients.
Both NWConnection and NWListener rely on DispatchQueue to deliver state changes, incoming connections, send/recv completions etc.
What DispatchQueues should I use and why?
Global Concurrent Dispatch Queue (and which QoS?) for all NWConnection and NWListener
One custom concurrent queue (which QoS?) for all NWConnection and NWListener? (Does that anyways get targetted to one of the global queues?)
One custom concurrent queue per NWConnection and NWListener though all targetted to Global Concurrent Dispatch Queue (and which QoS?)?
One custom concurrent queue per NWConnection and NWListener though all targetted to single target custom concurrent queue?
For every option above, how am I impacted in terms of parallelism, concurrency, throughput & latency and how is overall system impacted (with other processes also running)?
Seperate questions (sorry for the digression):
Are global concurrent queues specific to a process or shared across all processes on a device?
Can I safely use setSpecific on global dispatch queues in our app?
I want to configure one aspect of my networking configuration (the QUIC keepalive interval). This only seems to be configurable via Network.framework’s nw_quic_set_keepalive_interval. Is there any way to apply this to a URLSession? Or do I need to implement the whole connection management myself using Network.framework?
When setting new entitlements com.apple.developer.networking.carrier-constrained.appcategory and com.apple.developer.networking.carrier-constrained.app-optimized, I have a question about how URLSession should behave.
I notice we have a way to specify whether a Network connection should allow ultra-constrained paths via
NWParameters allowUltraConstrainedPaths: https://developer.apple.com/documentation/network/nwparameters/allowultraconstrainedpaths
There does not appear to be a similar property on URLSessionConfiguration.
In an ultra-constrained (eg. satellite) network, should we expect all requests made through an URLSession to fail?
Does all network activity when ultra-constrained need to go through a NWConnection or NetworkConnection specifically configured with allowUltraConstrainedPaths, or can URLSession ever be configured to allow ultra-constrained paths?
Hello,
I am working to integrate the new com.apple.developer.networking.carrier-constrained.app-optimized entitlement in my iOS 26 app so that my app can use a carrier-provided satellite network, and want to confirm my understanding of how to detect and optimize for satellite network conditions.
(Ref: https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.networking.carrier-constrained.app-optimized )
My current approach:
I plan to set the entitlement to true once my app is optimized for satellite networks.
To detect if the device is connected to a satellite network, I intend to use the Network framework’s NWPath properties:
isUltraConstrained — I understand this should be set to true when the device is connected to a satellite network.
(Ref: https://developer.apple.com/documentation/network/nwpath/isultraconstrained )
linkQuality == .minimal — I believe this will also be set in satellite scenarios, though it may not be exclusive to satellite connections.
(Ref:
https://developer.apple.com/documentation/network/nwpath/linkquality-swift.enum/minimal )
Questions:
Is it correct that isUltraConstrained will reliably indicate a satellite connection?
Should I also check for linkQuality == .minimal, or is isUltraConstrained sufficient?
Are there any additional APIs or best practices for detecting and optimizing for satellite connectivity that I should be aware of?
Thank you for confirming whether my understanding and approach are correct, and for any additional guidance.
Hi there,
We have been trying to set up URL filtering for our app but have run into a wall with generating the bloom filter.
Firstly, some context about our set up:
OHTTP handlers
Uses pre-warmed lambdas to expose the gateway and the configs endpoints using the javascript libary referenced here - https://developers.cloudflare.com/privacy-gateway/get-started/#resources
Status = untested
We have not yet got access to Apples relay servers
PIR service
We run the PIR service through AWS ECS behind an ALB
The container clones the following repo https://github.com/apple/swift-homomorphic-encryption, outside of config changes, we do not have any custom functionality
Status = working
From the logs, everything seems to be working here because it is responding to queries when they are sent, and never blocking anything it shouldn’t
Bloom filter generation
We generate a bloom filter from the following url list:
https://example.com
http://example.com
example.com
Then we put the result into the url filtering example application from here - https://developer.apple.com/documentation/networkextension/filtering-traffic-by-url
The info generated from the above URLs is:
{
"bits": 44,
"hashes": 11,
"seed": 2538058380,
"content": "m+yLyZ4O"
}
Status = broken
We think this is broken because we are getting requests to our PIR server for every single website we visit
We would have expected to only receive requests to the PIR server when going to example.com because it’s in our block list
It’s possible that behind the scenes Apple runs sporadically makes requests regardless of the bloom filter result, but that isn’t what we’d expect
We are generating our bloom filter in the following way:
We double hash the URL using fnv1a for the first, and murmurhash3 for the second
hashTwice(value: any, seed?: any): any {
return {
first: Number(fnv1a(value, { size: 32 })),
second: murmurhash3(value, seed),
};
}
We calculate the index positions from the following function/formula , as seen in https://github.com/ameshkov/swift-bloom/blob/master/Sources/BloomFilter/BloomFilter.swift#L96
doubleHashing(n: number, hashA: number, hashB: number, size: number): number {
return Math.abs((hashA + n * hashB) % size);
}
Questions:
What hashing algorithms are used and can you link an implementation that you know is compatible with Apple’s?
How are the index positions calculated from the iteration number, the size, and the hash results?
There was mention of a tool for generating a bloom filter that could be used for Apple’s URL filtering implementation, when can we expect the release of this tool?
Hi,
I am in need of your help with publishing my game.
I got the following explanation for the negative review of my app/game.
Issue Description
One or more purpose strings in the app do not sufficiently explain the use of protected resources. Purpose strings must clearly and completely describe the app's use of data and, in most cases, provide an example of how the data will be used.
Next Steps
Update the local network information purpose string to explain how the app will use the requested information and provide a specific example of how the data will be used. See the attached screenshot.
Resources
Purpose strings must clearly describe how an app uses the ability, data, or resource. The following are hypothetical examples of unclear purpose strings that would not pass review:
"App would like to access your Contacts"
"App needs microphone access"
See examples of helpful, informative purpose strings.
The problem is that they say my app asks to allow my app to find devices on local networks. And that this needs more explanation in the purpose strings.
Totally valid to ask, but the problem is my app doesn't need local access to devices, and there shouldn't be code that asks this?? FYI the game is build with Unity.
Would love some help on how to turn this off so that my app can get published.
I want to know the reason for last Wi-Fi disconnection. It would be helpful to that I can get the reason-code received from the access point.
It works when one device is only a publisher and the other is only a subscriber. However, when both devices act as both publisher and subscriber simultaneously—which Apple’s documentation (https://developer.apple.com/documentation/wifiaware/adopting-wi-fi-aware#Declare-services) indicates is valid—the connection never establishes. After timing out, both NetworkListener and NetworkBrowser transition to the failed state. This appears to be a race condition in Network framework.
Task.detached {
try await NetworkListener(
for: .wifiAware(
.connecting(
to: .myService,
from: .allPairedDevices,
datapath: .defaults
)
),
using: .parameters {
Coder(
sending: ...,
receiving: ...,
using: NetworkJSONCoder()
) {
TCP()
}
}
).run { connection in
await self.add(connection: connection)
}
}
Task.detached {
try await NetworkBrowser(
for: .wifiAware(
.connecting(
to: .allPairedDevices,
from: .myService
)
),
using: .tcp
).run { endpoints in
for endpoint in endpoints {
await self.connect(to: endpoint)
}
}
}