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.
Networking
RSS for tagExplore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Questions about FTP crop up from time-to-time here on DevForums. In most cases I write a general “don’t use FTP” response, but I don’t have time to go into all the details. I’ve created this post as a place to collect all of those details, so I can reference them in other threads.
IMPORTANT Apple’s official position on FTP is:
All our FTP APIs have been deprecated, and you should avoid using deprecated APIs.
Apple has been slowly removing FTP support from the user-facing parts of our system. The most recent example of this is that we removed the ftp command-line tool in macOS 10.13.
You should avoid the FTP protocol and look to adopt more modern alternatives.
The rest of this post is an informational explanation of the overall FTP picture.
This post is locked so I can keep it focused. If you have questions or comments, please do create a new thread in the App & System Services > Networking subtopic and I’ll respond there.
Don’t Use FTP
FTP is a very old and very crufty protocol. Certain things that seem obvious to us now — like being able to create a GUI client that reliably shows a directory listing in a platform-independent manner — aren’t possible to do in FTP. However, by far the biggest problem with FTP is that it provides no security [1]. Specifically, the FTP protocol:
Provides no on-the-wire privacy, so anyone can see the data you transfer
Provides no client-authenticates-server authentication, so you have no idea whether you’re talking to the right server
Provides no data integrity, allowing an attacker to munge your data in transit
Transfers user names and passwords in the clear
Using FTP for anonymous downloads may be acceptable (see the explanation below) but most other uses of FTP are completely inappropriate for the modern Internet.
IMPORTANT You should only use FTP for anonymous downloads if you have an independent way to check the integrity of the data you’ve downloaded. For example, if you’re downloading a software update, you could use code signing to check its integrity. If you don’t check the integrity of the data you’ve downloaded, an attacker could substitute a malicious download instead. This would be especially bad in, say, the software update case.
These fundamental problems with the FTP protocol mean that it’s not a priority for Apple. This is reflected in the available APIs, which is the subject of the next section.
FTP APIs
Apple provides two FTP APIs:
All Apple platforms provide FTP downloads via URLSession.
Most Apple platforms (everything except watchOS) support CFFTPStream, which allows for directory listings, downloads, uploads, and directory creation.
All of these FTP APIs are now deprecated:
URLSession was deprecated for the purposes of FTP in the 2022 SDKs (macOS 13, iOS 16, iPadOS 16, tvOS 16, watchOS 9) [2].
CFFTPStream was deprecated in the 2016 SDKs (macOS 10.11, iOS 9, iPadOS 9, tvOS 9).
CFFTPStream still works about as well as it ever did, which is not particularly well. Specifically:
There is at least one known crashing bug (r. 35745763), albeit one that occurs quite infrequently.
There are clear implementation limitations — like the fact that CFFTPCreateParsedResourceListing assumes a MacRoman text encoding (r. 7420589) — that won’t be fixed.
If you’re looking for an example of how to use these APIs, check out SimpleFTPSample.
Note This sample hasn’t been updated since 2013 and is unlikely to ever be updated given Apple’s position on FTP.
The FTP support in URLSession has significant limitations:
It only supports FTP downloads; there’s no support for uploads or any other FTP operations.
It doesn’t support resumable FTP downloads [3].
It doesn’t work in background sessions. That prevents it from running FTP downloads in the background on iOS.
It’s only supported in classic loading mode. See the usesClassicLoadingMode property and the doc comments in <Foundation/NSURLSession.h>.
If Apple’s FTP APIs are insufficient for your needs, you’ll need to write or acquire your own FTP library. Before you do that, however, consider switching to an alternative protocol. After all, if you’re going to go to the trouble of importing a large FTP library into your code base, you might as well import a library for a better protocol. The next section discusses some options in this space.
Alternative Protocols
There are numerous better alternatives to FTP:
HTTPS is by far the best alternative to FTP, offering good security, good APIs on Apple platforms, good server support, and good network compatibility. Implementing traditional FTP operations over HTTPS can be a bit tricky. One possible way forward is to enable DAV extensions on the server.
FTPS is FTP over TLS (aka SSL). While FTPS adds security to the protocol, which is very important, it still inherits many of FTP’s other problems. Personally I try to avoid this protocol.
SFTP is a file transfer protocol that’s completely unrelated to FTP. It runs over SSH, making it a great alternative in many of the ad hoc setups that traditionally use FTP.
Apple doesn’t have an API for either FTPS or SFTP, although on macOS you may be able to make some headway by invoking the sftp command-line tool.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] In another thread someone asked me about FTP’s other problems, those not related to security, so let’s talk about that.
One of FTP’s implicit design goals was to provide cross-platform support that exposes the target platform. You can think of FTP as being kinda like telnet. When you telnet from Unix to VMS, it doesn’t aim to abstract away VMS commands, so that you can type Unix commands at the VMS prompt. Rather, you’re expected to run VMS commands. FTP is (a bit) like that.
This choice made sense back when the FTP protocol was invented. Folks were expecting to use FTP via a command-line client, so there was a human in the loop. If they ran a command and it produced VMS-like output, that was fine because they knew that they were FTPing into a VMS machine.
However, most users today are using GUI clients, and this design choice makes it very hard to create a general GUI client for FTP. Let’s consider the simple problem of getting the contents of a directory. When you send an FTP LIST command, the server would historically run the platform native directory list command and pipe the results back to you. To create a GUI client you have to parse that data to extract the file names. Doing that is a serious challenge. Indeed, just the first step, working out the text encoding, is a challenge. Many FTP servers use UTF-8, but some use ISO-Latin-1, some use other standard encodings, some use Windows code pages, and so on.
I say “historically” above because there have been various efforts to standardise this stuff, both in the RFCs and in individual server implementations. However, if you’re building a general client you can’t rely on these efforts. After all, the reason why folks continue to use FTP is because of it widespread support.
[2] To quote the macOS 13 Ventura Release Notes:
FTP is deprecated for URLSession and related APIs. Please adopt
modern secure networking protocols such as HTTPS. (92623659)
[3] Although you can implement resumable downloads using the lower-level CFFTPStream API, courtesy of the kCFStreamPropertyFTPFileTransferOffset property.
Revision History
2025-10-06 Explained that URLSession only supports FTP in classic loading mode. Made other minor editorial changes.
2024-04-15 Added a footnote about FTP’s other problems. Made other minor editorial changes.
2022-08-09 Noted that the FTP support in URLSession is now deprecated. Made other minor editorial changes.
2021-04-06 Fixed the formatting. Fixed some links.
2018-02-23 First posted.
Hello to all
I have coded in swift a headless app, that launches 3 go microservices and itself. The app listens via unix domain sockets for commands from the microservices and executes different VPN related operations, using the NEVPNManager extension. Because there are certificates and VPN operations, the headless app and two Go microservices must run as root.
The app and microservices run perfectly when I run in Xcode launching the swift app as root. However, I have been trying for some weeks already to modify the application so at startup it requests the password and runs as root or something similar, so all forked apps also run as root. I have not succeeded. I have tried many things, the last one was using SMApp but as the swift app is a headless app and not a CLI command app it can not be embedded. And CLI apps can not get the VPN entitlements. Can anybody please give me some pointers how can I launch the app so it requests the password and runs as root in background or what is the ideal framework here? thank you again.
What is the best way to detect if the Wifi is being used for Wireless Carplay or is just a normal network interface?
Dear Apple:
We found that after mirroring an iPhone and a Mac, calling the NEHotspotConfigurationManager applyConfiguration interface on the iPhone fails to connect to Wi-Fi. Are there any restrictions on using this interface in mirror mode?
Hi!
I'm working on a solution (iOS 18) that uses Network Extensions PacketTunnelProvider and Content Filter. Currently I'm trying to integrate it with another extension – DNSProxyProvider. My goal is to process dns queries and use resolved ips and names for additional routing inside of the packet tunnel. I'm running into a major issue: whenever both VPN and DNS proxy are active simultaneously, the device completely loses internet connectivity — no traffic goes through, and DNS resolution seems to stop working entirely.
I know about the mdm supervision requirement to use DNSProxyProvider and that's covered as I work with a managed device and install a DNS proxy profile, here's how its .mobileconfig file looks like:
The DNS proxy itself works fine when working by itself (without VPN being turned on), as I implemented it that it successfully processes DNS packets flows while collecting information about domains etc, and everything works perfectly. Problems begin when using VPN at the same time. I'm aware that tunnel settings include dns related options that can affect this, but I haven't had much luck with tweaking them. Here's how they look right now for reference:
let settings: NEPacketTunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "240.0.0.1")
// let dnsSettings = NEDNSSettings(servers: "8.8.8.8,8.8.4.4".components(separatedBy: ","))
// dnsSettings.matchDomains = [""]
// settings.dnsSettings = dnsSettings
settings.proxySettings = nil
/* ipv4 settings */
let ipv4Settings = NEIPv4Settings(addresses: ["240.0.0.2"], subnetMasks: ["255.255.255.0"])
ipv4Settings.includedRoutes = [NEIPv4Route.default()]
settings.ipv4Settings = ipv4Settings
/* MTU */
settings.mtu = 1500
return settings
I've tried excluding some dns related ip routes and dns settings shenanigans but nothing.
I haven't found any information that might suggest that using both of these extensions at the same time doesn't work, on the contrary, this page in the official documentation about the expected use of packet tunnel provider the expected use of packet tunnel provider, as it talks about the fact that you should not use it for interception of all of DNS traffic, as the use of DNSPRoxyProvider (or dns settings) are built for that, which in my mind, suggests that there should be no problem with using them both and just splitting the dns traffic handling to the proxy.
Will be thankful for any help!
For our outdoor power supply company that builds public WiFi networks at camping sites, we want to implement the following features in our app:
Scan surrounding WiFi networks
When detecting specific public WiFi SSIDs, provide users with corresponding passwords
Automatically connect to those WiFi networks
Regarding the NEHotspotHelper API permission application, when I clicked on https://developer.apple.com/contact/request/network-extension, it redirected me to https://developer.apple.com/unauthorized/. I'm not sure where to properly apply for this permission now.
Topic:
App & System Services
SubTopic:
Networking
All of our uses of CFSockets have started causing crashes in iOS 16. They seem to be deprecated so we are trying to transition over to using the Network framework and NWConnection to try to fix the crashes.
One of our uses of them is to ping a device on the local network to make sure it is there and online and provide a heartbeat status in logs as well as put the application into a disabled state if it is not available as it is critical to the functionality of the app. I know it is discouraged to disable any functionality based on the reachability of a resource but this is in an enterprise environment where the reachability of this device is mission critical.
I've seen other people ask about the ability to ping with the Network framework and the answers I've found have said that this is not possible and pointed people to the SimplePing sample code but it turns out our existing ping code is already using this technique and it is crashing just like our other CFSocket usages, inside CFSocketInvalidate with the error BUG IN CLIENT OF LIBPLATFORM: Trying to recursively lock an os_unfair_lock.
Is there any updated way to perform a ping without using the CFSocket APIs that now seem to be broken/unsupported on iOS 16?
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?
I’m developing a iOS VPN app, and I need to execute a task in the main app even when it’s in the background or killed state. I know the Network Extension continues running during those times. Is there a way for the extension to immediately notify the app or trigger a task on the app side?
Is Apple's Wi-Fi Aware certified by the Wi-Fi Alliance?
Is there any non-compliance of Apple's Wi-Fi Aware with the Wi-Fi Alliance standards?
Does Apple have a roadmap to switch AWDL to Wi-Fi Aware?
Does Apple have plans to adopt Wi-Fi Aware in Mac computers?
Hi,
I observed some unexpected behavior and hope that someone can enlighten me as to what this is about:
mDNSResponder prepends IP / network based default search domains that are checked before any other search domain. E.g. 0.1.168.192.in-addr.arpa. would be used for an interface with an address in the the 192.168.1.0/24 subnet. This is done for any configured non-link-local IP address.
I tried to find any mention of an approach like this in RFCs but couldn't spot anything.
Please note that this is indeed a search domain and different from reverse-DNS lookups.
Example output of tcpdump for ping devtest:
10:02:13.850802 IP (tos 0x0, ttl 64, id 43461, offset 0, flags [none], proto UDP (17), length 92)
192.168.1.2.52319 > 192.168.1.1.53: 54890+ [1au] A? devtest.0.1.168.192.in-addr.arpa. (64)
I was able to identify the code that adds those default IP subnet based search domains but failed to spot any indication as to what this is about: https://github.com/apple-oss-distributions/mDNSResponder/blob/d5029b5/mDNSMacOSX/mDNSMacOSX.c#L4171-L4211
Does anyone here have an ideas as to what this might be about?
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.
Hey!
We discovered an unexpected side-effect of enabling enforceRoutes in our iOS VPN application - video airplay from iOS to tvOS stopped working (Unable to Connect popup appears instead).
Our flags combination is:
includeAllNetworks = false
enforceRoutes = true
excludeLocalNetworks = true
Interestingly, music content can be AirPlayed with the same conditions.
Also, video AirPlay from iOS device to the macOS works flawlessly.
Do you know if this is a known issue? Do you have any advice if we can fix this problem on our side, while keeping enforcRoutes flag enabled?
From time to time the subject of NECP grows up, both here on DevForums and in DTS cases. I’ve posted about this before but I wanted to collect those tidbits into single coherent post.
If you have questions or comments, start a new thread in the App & System Services > Networking subtopic and tag it with Network Extension. That way I’ll be sure to see it go by.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
A Peek Behind the NECP Curtain
NECP stands for Network Extension Control Protocol. It’s a subsystem within the Apple networking stack that controls which programs have access to which network interfaces. It’s vitally important to the Network Extension subsystem, hence the name, but it’s used in many different places. Indeed, a very familiar example of its use is the Settings > Mobile Data [1] user interface on iOS.
NECP has no explicit API, although there are APIs that are offer some insight into its state. Continuing the Settings > Mobile Data example above, there is a little-known API, CTCellularData in the Core Telephony framework, that returns whether your app has access to WWAN.
Despite having no API, NECP is still relevant to developers. The Settings > Mobile Data example is one place where it affects app developers but it’s most important for Network Extension (NE) developers. A key use case for NECP is to prevent VPN loops. When starting an NE provider, the system configures the NECP policy for the NE provider’s process to prevent it from using a VPN interface. This means that you can safely open a network connection inside your VPN provider without having to worry about its traffic being accidentally routed back to you. This is why, for example, an NE packet tunnel provider can use any networking API it wants, including BSD Sockets, to run its connection without fear of creating a VPN loop [1].
One place that NECP shows up regularly is the system log. Next time you see a system log entry like this:
type: debug
time: 15:02:54.817903+0000
process: Mail
subsystem: com.apple.network
category: connection
message: nw_protocol_socket_set_necp_attributes [C723.1.1:1] setsockopt 39 SO_NECP_ATTRIBUTES
…
you’ll at least know what the necp means (-:
Finally, a lot of NECP infrastructure is in the Darwin open source. As with all things in Darwin, it’s fine to poke around and see how your favourite feature works, but do not incorporate any information you find into your product. Stuff you uncover by looking in Darwin is not considered API.
[1] Settings > Cellular Data if you speak American (-:
[2] Network Extension providers can call the createTCPConnection(to:enableTLS:tlsParameters:delegate:) method to create an NWTCPConnection [3] that doesn’t run through the tunnel. You can use that if it’s convenient but you don’t need to use it.
[3] NWTCPConnection is now deprecated, but there are non-deprecated equivalents. For the full story, see NWEndpoint History and Advice.
Revision History
2025-12-12 Replaced “macOS networking stack” with “Apple networking stack” to avoid giving the impression that this is all about macOS. Added a link to NWEndpoint History and Advice. Made other minor editorial changes.
2023-02-27 First posted.
cant open this website: https://appstoreconnect.apple.com/apps
Bad Gateway
Correlation Key: EJMQBY3TQQI6QR2RBCFRFK7WSM
Topic:
App & System Services
SubTopic:
Networking
ios構成プロファイルの制限のallowCloudPrivateRelayのプライベートリレーの制御とRelayペイロードの機能は関係がありますか?
それとも別々の機能でしょうか?
↓
s there a relationship between the private relay control in the iOS configuration profile restriction allowCloudPrivateRelay and the functionality of the Relay payload?
Or are they separate features?
Topic:
App & System Services
SubTopic:
Networking
1、已经检查过手机的存储空间,还有一百多G的空间。app端进行网络接口情况的时候报错了,报错信息如下:
Error : Error Domain=NSPOSIXErrorDomain Code=28 "No space left on device" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <7DB1CBFD-B9BE-422D-9C9A-78D8FC04DC1B>.<76>, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=28, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <7DB1CBFD-B9BE-422D-9C9A-78D8FC04DC1B>.<76>"
), _NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: pdp_ip0[lte], ipv4, ipv6, dns, expensive, estimated upload: 65536Bps, uses cell}
2、手机型号是iPhone 15 Plus,iOS 17.6.1
Topic:
App & System Services
SubTopic:
Networking
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.
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-11-11 Removed the discussion of TSI assets because those are no longer a thing.
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.
Hey there
Are there any recommendations or guidance for apps on alternatives to certificate pinning to secure their device network traffic?
I want to move away from the overhead and risk associated with rotating certificates when using leaf pinning.
However, I also don't want people to be able to perform a MITM attack easily using something like Charles Proxy with a self‑signed certificate added to the trust store.
My understanding is that an app cannot distinguish between user‑trusted certificates and system‑trusted certificates in the trust store, so it cannot block traffic that uses user‑trusted certificates.
Topic:
App & System Services
SubTopic:
Networking
Apology for repost. I needed to fix the tags for original thread.
https://developer.apple.com/forums/thread/777159
On iOS 18.3, I noted that partition "HTTPCookiePropertyKey: StoragePartition" is not observed to be set for cookies returned from the wkwebview cookie store.
Now on 18.4 beta 4 we are now seeing those same cookies are populated with a partition property. Is there documentation for this change? Is it intended to be suddenly populated in 18.4?
Now that partition property is set, HTTPCookieStorage.shared.cookies(for: serverUri) doesn't seem to return the expected cookies correctly. For context, we are using the cookies extracted from wkwebview, setting them in HTTPCookieStorage.shared and using URLSession to make network calls outside the webivew. Works fine once I forcefully set partition on the cookie to nil.
More details on what the cookie looks like here: https://feedbackassistant.apple.com/feedback/16906526
Hopefully this is on your radar?