I am developing an App based on Network Extension that lets all network requests on device access the Internet through a private Relay.
I created an empty iOS App and only the entitlements file and ViewController.swift(Main.storyboard) file have been modified. The code was copied from the official video https://developer.apple.com/videos/play/wwdc2023/10002/
But, running the App on iPhone, the saveToPreferences API reported Error Domain=NERelayErrorDomain Code=3 "(null)" and the App doesn't look like it's changed at all (it doesn't jump to the Settings - VPN&Relay). Does anyone know why?Any reply would be greatly appreciated.
The contents of the entitlements file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>relay</string>
</array>
</dict>
</plist>
ViewController.swift:
import UIKit
import NetworkExtension
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func tap(_ sender: Any) {
let newRelay = NERelay()
let relayURL = URL(string: "https://relay.example.com:443/")
newRelay.http3RelayURL = relayURL
newRelay.http2RelayURL = relayURL
newRelay.additionalHTTPHeaderFields = ["Authorization" : "PrivateToken=123"]
let manager = NERelayManager.shared()
manager.relays = [newRelay]
manager.matchDomains = ["internal.example.com"]
manager.isEnabled = false
manager.saveToPreferences { err in
print(err)
}
}
}
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
Hello,
I have been testing my app in iOS 18 device and while creating a server with TCP, then apple make a request for local network permission automatically. If we don't allow the permission, the connection not working. We are getting the connection timeout error even after allowing again from device setting.
Has something changed in the flow for iOS 18 version? Can someone help me to solve this issue?
Hi, when I perform an overlay installation via a PKG on macOS for an application containing the NEFilterDataProvider functionality, there is a chance that the entire system network becomes unreachable. Disabling the corresponding Content Filter in "System Settings > Network > Filters" immediately restores network connectivity. This issue does not occur every time, with a frequency of approximately 1 in 20 installation attempts.
The following details may help identify the problem:
The Filter.app containing the NEFilterDataProvider resides within the main app's Resources directory, e.g., /Applications/Main.app/Contents/Resources/Filter.app
Main.app is installed via a PKG; the issue typically occurs during an overlay installation of Main.app.
The NEFilterDataProvider operates as a System Extension.
The func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict {} returns .allow.
Wireshark packet captures show TCP packets but no UDP packets; TCP handshakes cannot complete.
Disabling the corresponding content filter in "System Settings > Network > Filters" restores the network; re-enabling it breaks connectivity again.
After waiting for a period, approximately 30-60 minutes, network connectivity can recover automatically.
What causes this and how can it be fixed? Any workarounds?
How can NEPacketTunnelProvider launch the companion application, or notify user to launch the application?
I have built an iOS VPN that uses credentials stored in the keychain, and it works as expected. Now I'm trying to add OAuth login support.
Everything works fine at first. I login from the companion application, store tokens in the keychain, then launch the VPN from either System Settings or the companion application.
However, when the OAuth refresh tokens expire, or the OAuth IdP otherwise requires login, I can't perform the OAuth login from the NEPacketTunnelProvider. Login must happen from the companion application, which likely isn't running. I need the NEPacketTunnelProvider to either launch the companion application directly or to notify the user to do so.
Searching and reading docs yields:
You can't perform OAuth login from within the NEPacketTunnelProvider because it requires user interaction
There is no way to guarantee that the companion application is running on iOS (otherwise one would use NEVPNStatusDidChange)
You can't launch the companion application from NEPacketTunnelProvider using a custom URL because of security concerns
You might be able to launch the companion application from a system extension...
Some sources say you still can't guarantee that the system extension is loaded whenever the NEPacketTunnelProvider needs it anyway.
Of course, any of these conclusions could be wrong.
At this point I'm not sure where to begin. Is there another approach that could be initiated by the NEPacketTunnelProvider (push notifications, system notifications, smoke signals)?
Any help would be appreciated.
Thanks,
Bill Welch
Topic:
App & System Services
SubTopic:
Networking
Tags:
Extensions
Network Extension
User Notifications
Could anyone tell me how to detect status of Local Network for iOS 18+ systems ?
Hi everyone, I developed an Android version of a VPN app built with Flutter using OpenVPN, and it works perfectly on Android. However, when porting it to iOS, I’ve encountered an issue: the app connects successfully but then automatically disconnects when tested via TestFlight. We’ve already added all the necessary network extensions. Despite this, we decided to submit the app to the App Store. It’s been five days now, and the app is still 'Waiting for Review.' Could anyone share their experience deploying and working on an iOS version of a VPN app? I’d really appreciate your insights!
I am working on a macos application that uses NetworkExtension and works fine in the debug environment. However, when I use the Release package, I am always prompted that my description file does not contain NetworkExtension. I am sure that my description file does contain NetworkExtension. How to solve this problem
I'm creating a custom VPN app which should only work on Cellular. Apart from cellular interface binding VPN is working fine. Even though I specified cellular interface like
let cellularParams = NWParameters.udp
cellularParams.requiredInterfaceType = .cellular
It is going via Wifi when it is ON. I know this is the default iOS behaviour.
How can I prevent this and route through cellular only even when Wifi is enabled on device?
Hello,
I am in a very similar situation as described in the thread: https://developer.apple.com/forums/thread/655183
Context: I am working on an app that receives data from a hardware device through its Wifi network, and the hardware is not connected to the internet. Now, I would need to call some API while still connected to hardware so I would need to use the cellular data.
As mentioned on the thread, I can achieve this via Network framework, using the requiredInterfaceType property. But Is there any other way I can achieve this? I can also do some suggestion on the hardware if that's helpful.
Thank you!
I'm working on enabling a content filter in my iOS app using NEFilterManager and NEFilterProviderConfiguration. The setup works perfectly in debug builds when running via Xcode, but fails on TestFlight builds with the following error:
**Failed to save filter settings: permission denied
**
**Here is my current implementation:
**
(void)startContentFilter {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults synchronize];
[[NEFilterManager sharedManager] loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"Failed to load filter: %@", error.localizedDescription);
[self showAlertWithTitle:@"Error" message:[NSString stringWithFormat:@"Failed to load content filter: %@", error.localizedDescription]];
return;
}
NEFilterProviderConfiguration *filterConfig = [[NEFilterProviderConfiguration alloc] init];
filterConfig.filterSockets = YES;
filterConfig.filterBrowsers = YES;
NEFilterManager *manager = [NEFilterManager sharedManager];
manager.providerConfiguration = filterConfig;
manager.enabled = YES;
[manager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
NSLog(@"Failed to save filter settings: %@", error.localizedDescription);
[self showAlertWithTitle:@"Error" message:[NSString stringWithFormat:@"Failed to save filter settings: %@", error.localizedDescription]];
} else {
NSLog(@"Content filter enabled successfully!");
[self showAlertWithTitle:@"Success" message:@"Content filter enabled successfully!"];
}
});
}];
});
}];
}
**What I've tried:
**
Ensured the com.apple.developer.networking.networkextension entitlement is set in both the app and system extension.
The Network extension target includes content-filter-provider.
Tested only on physical devices.
App works in development build, but not from TestFlight.
**My questions: **
Why does saveToPreferencesWithCompletionHandler fail with “permission denied” on TestFlight?
Are there special entitlements required for using NEFilterManager in production/TestFlight builds?
Is MDM (Mobile Device Management) required to deploy apps using content filters?
Has anyone successfully implemented NEFilterProviderConfiguration in production, and if so, how?
Topic:
App & System Services
SubTopic:
Networking
Tags:
Extensions
Swift
Network Extension
Objective-C
Hi all!
I’m having trouble distributing an iOS app with a DNS Proxy NetworkExtension via AdHoc. The app and extension work perfectly with development profiles, but when I export and install the AdHoc IPA, I get a “permission denied” error when trying to install/enable the DNS Proxy extension.
What I’ve done:
Both the app and the DNS Proxy extension have their own App IDs in the Apple Developer portal.
Both App IDs have the same App Group enabled: group.com.irakai.SafeLinkApp2.
The extension App ID has the NetworkExtension capability with dns-proxy enabled.
I created two AdHoc provisioning profiles (one for the app, one for the extension), both including the same devices and the correct entitlements.
I assigned the correct AdHoc profiles to each target in Xcode and exported the IPA via Organizer.
I install the IPA on a registered device using Apple Configurator.
Entitlements (extracted from the signed binaries on device):
App:
<key>application-identifier</key><string>6PBG234246.com.irakai.SafeLinkApp2</string>
<key>com.apple.developer.networking.networkextension</key><array>
<string>packet-tunnel-provider</string>
<string>dns-proxy</string>
</array>
<key>com.apple.developer.team-identifier</key><string>6PBG234246</string>
<key>com.apple.security.application-groups</key><array>
<string>group.com.irakai.SafeLinkApp2</string>
</array>
<key>get-task-allow</key><false/>
DNSProxy Extension:
<key>application-identifier</key><string>6PBG234246.com.irakai.SafeLinkApp2.DNSProxy</string>
<key>com.apple.developer.networking.networkextension</key><array>
<string>dns-proxy</string>
</array>
<key>com.apple.developer.team-identifier</key><string>6PBG234246</string>
<key>com.apple.security.application-groups</key><array>
<string>group.com.irakai.SafeLinkApp2</string>
</array>
<key>get-task-allow</key><false/>
Error message (from my app’s logs):
Error instalando DNS Proxy: permission denied
Usuario: Roberto
AppGroup: group.com.irakai.SafeLinkApp2
AppGroupPath: /private/var/mobile/Containers/Shared/AppGroup/D8AD2DED-AD96-4915-9B7A-648C9504679B
Entitlements:
BundleId: com.irakai.SafeLinkApp2
Debug info: Error Domain=NEDNSProxyErrorDomain Code=1 "permission denied" UserInfo={NSLocalizedDescription=permission denied}
Other details:
The device is included in both AdHoc profiles.
The App Group is present and identical in both entitlements.
The extension’s bundle identifier matches the App ID in the portal.
The extension is signed with the correct AdHoc profile.
I have tried rebooting the device and reinstalling the IPA.
The error only occurs with AdHoc; development builds work fine.
Questions:
Is there anything else I should check regarding AdHoc provisioning for NetworkExtension DNS Proxy?
Are there any known issues with AdHoc and NetworkExtension on recent iOS versions?
Is there a way to get more detailed diagnostics from the system about why the permission is denied?
Could this be a bug in iOS, or am I missing a subtle configuration step?
Any help or suggestions would be greatly appreciated.
Thank you!
Hi,
I am trying to create an App which connects to a Device via Wifi and then has to do some HTTP Requests. Connecting to the Wifi is working properly but when I try to make an HTTP API Call I get the response that the Domain is unavailable (No Internet Connection). I created the App in Flutter on Android everything works perfectly. The packages are all iOS Compatible. But in Safari the URL works so it is probably a permission Issue. I have the Following permissions granted:
NSAppTransportSecurity
NSBonjourServices
NSLocalNetworkUsageDescription
I even have Multicast Networking
When I test the App I get asked to grant the access to local Network which I am granting.
I don´t know what I should do next can somebody help?
Feel free to ask for more Information
This is the log on the publisher side.
Publisher discovered the subscriber, but could not pair.
Follow up is sent with response rejected
We have a Java application built for macOS. On the first launch, the application prompts the user to allow local network access. We've correctly added the NSLocalNetworkUsageDescription key to the Info.plist, and the provided description appears in the system prompt.
After the user grants permission, the application can successfully connect to a local server using its hostname. However, the issue arises after the system is rebooted. When the application is launched again, macOS does not prompt for local network access a second time—which is expected, as the permission was already granted.
Despite this, the application is unable to connect to the local server. It appears the previously granted permission is being ignored after a reboot. A temporary workaround is to manually toggle the Local Network permission off and back on via System Settings > Privacy & Security, which restores connectivity—until the next reboot.
This behavior is highly disruptive, both for us and for a significant number of our users. We can reproduce this on multiple systems...
The issues started from macOS Sequoia 15.0
By opening the application bundle using "Show Package Contents," we can launch the application via "JavaAppLauncher" without any issues. Once started, the application is able to connect to our server over the local network. This seems to bypass the granted permissions? "JavaAppLauncher" is also been used in our Info.plist file
Removing the following plist in Recovery Mode seems to resolve the issue
rm "/Volumes/Macintosh HD/Library/Preferences/com.apple.networkextension.plist"
Is this safe to do?
Topic:
App & System Services
SubTopic:
Networking
I have an accessory which uses both Bluetooth and WiFi to communicate with the app. I am trying to migrate to Accessory Setup Kit.
However, the API expects both the bluetooth identifiers and WIFI SSID or SSID prefix in the ASDiscoveryDescriptor. The problem is we only have the WIFI SSID after BLE pairing.
Our current flow looks like this:
Pair via BLE
Connect via BLE
Send a BLE command to request WIFI settings (SSID and password) (Each device has a different SSID and password)
Connect to WI-FI hotspot by calling NEHotspotConfigurationManager applyConfiguration with the retrieved credentials.
Is there a way to set the Wi-Fi SSID of an ASAccessory object after the initial setup?
To use Accessory Setup Kit we would need something like this:
Call Accessory Setup Kit with bluetooth identifiers in the descriptor, finish the setup and get ASAccessory object.
Connect via BLE
Send a BLE command to request WIFI settings (SSID and password)
Set the SSID of the ASAccessory to the retrieved value.
Connect to WI-FI hotspot by calling `NEHotspotConfigurationManager joinAccessoryHotspot.
Thanks!
Topic:
App & System Services
SubTopic:
Networking
My app sent a network request to the backend. The backend returns a 200, but the front end received a -1001 or -1005 NSURLError. Any clue why this could be happening?
Could anyone teach me how to ask iOS 18 to have a prompt during set-up process of a new APP if user accidentally turns off Local Network ?
Hi there, I am working on an app that configures a PacketTunnelProvider to establish a VPN connection. Unfortunately, while a VPN connection is established, I am unable to update the app via testflight. Downloading other app updates works fine.
I noticed that after I receive the alert that updating failed, the vpn badge appears at the top of my screen (the same ux that occurs when the connection is first established). So it's almost like it tried to close the tunnel, and seeing that the app update failed it restablishes the tunnel.
I am unsure of why I would not be able to update my app. Maybe stopTunnel is not being called with NEProviderStopReason.appUpdate?
Is it possible using the network framework to retrieve the list of certificates presented by the host alone, and not the reconstructed chain assembled by the system?
For example, in OpenSSL one can call SSL_get_peer_cert_chain which will return exactly this - a list of the certificates presented by the server. This is useful for when you may want to manually reconstruct the chain, or if the server is misconfigured (for example, is missing an intermediate cert).
Is something like this possible with the network framework?
If I connect to a host that I know only returns 1 certificate, the trust ref already has the reconstructed chain by the time my code is called:
sec_protocol_options_set_verify_block(tlsOptions.securityProtocolOptions, { metadata, trustRef, verifyComplete in
let trust = sec_trust_copy_ref(trustRef).takeRetainedValue()
let numberOfCertificates = SecTrustGetCertificateCount(trust) // Returns 3 even though the server only sent 1
Hi everyone,
I’m developing an app called FindMyNet that allows users to find the best internet provider based on their postal code (CAP). The app is built with Xcode and the macOS simulator. I’ve set up a FastAPI backend that communicates with an Excel database containing internet provider data for each postal code.
Unfortunately, when I try to run the app, I encounter an error that prevents me from retrieving data from the database and displaying the correct provider.
Task <6B5C86B6-181A-4235-AE68-23AAF6645683>.<1> finished with error [1] Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <6B5C86B6-181A-4235-AE68-23AAF6645683>.<1>, _kCFStreamErrorDomainKey=1, _kCFStreamErrorCodeKey=1, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <6B5C86B6-181A-4235-AE68-23AAF6645683>.<1>" ), _NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi}
Problem description:
• The FastAPI backend is running on a Raspberry Pi and communicates with the app via an HTTP request.
• When I enter a postal code, the app should return the best provider for that region, but I only get a 500 error.
• I’ve verified that the FastAPI server is running, but it seems there’s an issue with communication between the app and the server.
Steps taken so far:
• I’ve checked the logs on the FastAPI server, but there are no obvious errors.
• I’ve manually tested the API using Postman, and it works fine, so the issue seems to be app-side.
Support request:
I’d like to understand better what could be causing this error and if anyone has had similar experiences. Any advice on diagnosing the problem or solutions for resolving it would be greatly appreciated.
Thanks in advance for your help!
Topic:
App & System Services
SubTopic:
Networking