I'm trying to detect the state of Local Network privacy on macOS Sequoia via NWBrowser, as recommended in https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy
Regardless of the state of Local Network privacy - undetermined, allowed or denied, NWBrowser receives an update indicating that its in the ready state.
Scanning does not seem to trigger the Local Network privacy alert for me - I have to use the other recommended method to trigger the prompt. Enabling or disabling Local Network privacy does not seem to send any updates for NWBrowser.
https://developer.apple.com/forums/thread/666431 seems related, and implies that they did receive further updates to NWBrowser.
Filed as FB16077972
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
We have developed a DNS filter based on NEDNSProxyProvider. It works great for a minute, then it stops responding. Our logs indicate that during the outage our extension gets DNS requests and formulates DNS responses that it hands back to the OS, but from outside of our code it is as though our extension is not responding.
Hello,
Since the release of iOS 26.0, we are seeing DNS traffic being blocked from within our NEPacketTunnelExtension on some devices. We have not isolated exact reproduction steps, but DNS resolves successfully for a period of time after enabling "iCloud Private Relay" (varying from 1-day to 2-weeks), until it then fails as MDNSResponder then returns:
mDNSResponder [Q37046] DetermineUnicastQuerySuppression: Query suppressed for <mask.hash: 'REDACTED'> Addr (blocked by policy)
DNS resolution continues to fail for all domains with the above until the device is rebooted.
The Packet Tunnel intentionally does not have a DNS server set and this occurs for traffic from the Extension yet off-tunnel, which needs resolution from the system DNS server (and this configuration works perfectly for a period of time before being "blocked by policy").
The following do not resolve the issue once DNS queries are being "blocked by policy" on affected devices: disconnecting then reconnecting the vpn; toggling airplane mode for 10+ seconds; switching connection between WiFi & cellular data; disabling iCloud Private Relay.
We have currently only seen this on unmanaged devices running iOS 26.0 or 26.1 beta and with iCloud Private Relay enabled. We did not see this issue on iOS 16,17 nor 18. We also have not yet seen this when iCloud Private Relay is disabled nor on iOS 26.0.1, however we cannot confirm whether they too are also affected.
Is there a known a bug with iOS 26.0 & 26.1 Beta 1 that could cause this? How can we prevent DNS requests from NEPacketTunnelExtension being sporadically "blocked by policy" until the device is rebooted?
Many thanks in advance.
We have a content filter system extension as part of our macOS app. The filter normally works correctly, activation and deactivation works as expected but occasionally we see an issue when the content filter is activated.
When this issues occurs, the filter activation appears to behave correctly, no errors are reported. Using "systemextensionsctl list" we see the filter is labelled as "[activated enabled]". However, the installed content filter executable does not run.
We have seen this issue on macOS 15.3 and later and on the beta macOS 26.1 RC.
It happens only occasionally but when it does there is no indication as to why the executable is not running. There are no crash logs or errors in launchd logs.
Both rebooting and deactivating/activating the filter do not resolve the issue. The only fix appears to be completely uninstalling the app (including content filter) and reinstalling.
I have raised a FB ticket, FB20866080.
Does anyone have any idea what could cause this?
On macOS 15, if a program installed in /Applications is allowed to connect to a PostgreSQL server on another machine on the local network, a program launched in debug mode from Xcode is not allowed to connect to the local network, and no prompt appears.
Although it is possible to turn off registered programs in Local Network Privacy in Beta 2, permissions for programs launched from Xcode cannot be obtained at all.
Does anyone know how to solve this problem?
Hello,
We are facing an issue with performing a DTLS handshake when our iOS application is in the background. Our app (Vocera Collaboration Suite – VCS) uses secure DTLS-encrypted communication for incoming VoIP calls.
Problem Summary:
When the app is in the background and a VoIP PushKit notification arrives, we attempt to establish a DTLS handshake over our existing socket. However, the handshake consistently fails unless the app is already in the foreground. Once the app is foregrounded, the same DTLS handshake logic succeeds immediately.
Key Questions:
Is performing a DTLS handshake while the app is in the background technically supported by iOS?
Or is this an OS-level limitation by design?
If not supported, what is the Apple-recommended alternative to establish secure DTLS communication for VoIP flows without bringing the app to the foreground?
Any guidance or clarification from Apple engineers or anyone who has solved a similar problem would be greatly appreciated.
Thank you.
Description:
We are investigating an issue where running a specific e-commerce iOS app inside the Xcode Simulator intermittently disrupts the Mac’s network connectivity.
When the app is launched in the Simulator, our NETransparentProxyProvider and NEFilterDataProvider extensions occasionally stop receiving traffic correctly, and shortly afterward the entire macOS DNS resolution fails. Once this happens, all apps on the Mac lose internet access until mac is restarted. Disabling extensions also fixing the issue.
This issue only appears when the app runs in the Xcode Simulator.
I would like to confirm:
Is it possible for traffic patterns or network behavior inside the Simulator to interfere with system-level Network Extension providers on macOS?
Are there known limitations or conflicts between the Simulator’s virtual networking interfaces and Network Extensions?
Any recommended debugging steps or best practices to isolate this behavior?
Any guidance, known issues, or suggestions would be appreciated.
Hello team,
I am developing a security app where I am denying certain flows/packets if the are communicating with known malicious endpoints. Therefore I want to make use of NetworkExtensions such as the new URLFilter or ContentFilter (NEURLFilterManager, NEFilterDataProvider, NEFilterControlProvider).
Does NEURLFilterManager require the user's device to be at a minimun of ios 26?
Does any of these APIs/Extensions require the device to be managed/supervised or can it be released to all consumers?
Thanks,
Topic:
App & System Services
SubTopic:
Networking
Hi, We are trying to use Apple Security API for KeyChain Services.
Using the common App Group : Specifying the common app group in the "kSecAttrAccessGroup" field of the KeyChain query, allowed us to have a shared keychains for different apps (targets) in the app group, but this did not work for extensions.
Enabling the KeyChain Sharing capability : We enabled the KeyChain Sharing Ability in the extensions and the app target as well, giving a common KeyChain Access group. Specifying this in the kSecAttrAccessGroup field also did not work. This was done in XCode as we were unable to locate it in the Developer portal in Indentifiers.
We tried specifying "$AppIdentifier.KeyChainSharingGroup" in the kSecAttrAccessGroup field , but this did not work as well
The error code which we get in all these 3 cases when trying to access the Keychain from the extension is error code 25291 (errSecNotAvailable). The Documentation says this error comes when "No Trust Results are available" and printing the error in xcode using the status says "No keychain is available.
The online Documentation says that it is possible to share keychain with extensions, but by far we are unable to do it with the methods suggested.
Do we need any special entitlement for this or is there something we are missing while using these APIs?
We really appreciate any and all help in solving this issue!
Thank you
Summary
NetworkConnection<WebSocket> in iOS 26 Network framework throws POSIXErrorCode(rawValue: 22): Invalid argument when receiving WebSocket ping (opcode 9) or pong (opcode 10) control frames. This prevents proper WebSocket keep-alive functionality.
Environment
iOS 26.0 (Simulator)
macOS 26.1
Xcode 26.0
Note: This issue was initially discovered on iOS 26 Simulator. The same behavior was confirmed on macOS 26, suggesting a shared bug in the Network framework. The attached sample code is for macOS for easier reproduction.
Description
When using the new NetworkConnection<WebSocket> API introduced in iOS 26 or macOS 26, the receive() method throws EINVAL error whenever a ping or pong control frame is received from the server.
This is a critical issue because:
WebSocket servers commonly send ping frames to keep connections alive
Clients send ping frames to verify connection health
The receive callback never receives the ping/pong frame - the error occurs before the frame reaches user code
Steps to Reproduce
Create a WebSocket connection to any server that supports ping/pong (e.g., wss://echo.websocket.org):
import Foundation
import Network
// MARK: - WebSocket Ping/Pong EINVAL Bug Reproduction
// This sample demonstrates that NetworkConnection<WebSocket> throws EINVAL
// when receiving ping or pong control frames.
@main
struct WebSocketPingPongBug {
static func main() async {
print("=== WebSocket Ping/Pong EINVAL Bug Reproduction ===\n")
do {
try await testPingPong()
} catch {
print("Test failed with error: \(error)")
}
}
static func testPingPong() async throws {
let host = "echo.websocket.org"
let port: UInt16 = 443
print("Connecting to wss://\(host)...")
let endpoint = NWEndpoint.hostPort(
host: NWEndpoint.Host(host),
port: NWEndpoint.Port(rawValue: port)!
)
try await withNetworkConnection(to: endpoint, using: {
WebSocket {
TLS {
TCP()
}
}
}) { connection in
print("Connected!\n")
// Start receive loop in background
let receiveTask = Task {
var messageCount = 0
while !Task.isCancelled {
do {
let (data, metadata) = try await connection.receive()
messageCount += 1
print("[\(messageCount)] Received frame - opcode: \(metadata.opcode)")
if let text = String(data: data, encoding: .utf8) {
print("[\(messageCount)] Content: \(text)")
} else {
print("[\(messageCount)] Binary data: \(data.count) bytes")
}
} catch let error as NWError {
if case .posix(let code) = error, code == .EINVAL {
print("❌ EINVAL error occurred! (POSIXErrorCode 22: Invalid argument)")
print(" This is the bug - ping/pong frame caused EINVAL")
// Continue to demonstrate workaround
continue
}
print("Receive error: \(error)")
break
} catch {
print("Receive error: \(error)")
break
}
}
}
// Wait for initial message from server
try await Task.sleep(for: .seconds(2))
// Test 1: Send text message (should work)
print("\n--- Test 1: Sending text message ---")
try await connection.send("Hello, WebSocket!")
print("✅ Text message sent")
try await Task.sleep(for: .seconds(1))
// Test 2: Send ping (pong response will cause EINVAL)
print("\n--- Test 2: Sending ping frame ---")
print("Expecting EINVAL when pong is received...")
let pingMetadata = NWProtocolWebSocket.Metadata(opcode: .ping)
try await connection.ping(Data()) {
pingMetadata
}
print("✅ Ping sent, waiting for pong...")
// Wait for pong response
try await Task.sleep(for: .seconds(2))
// Cleanup
receiveTask.cancel()
print("\n=== Test Complete ===")
print("If you saw 'EINVAL error occurred!' above, the bug is reproduced.")
}
}
}
The receive() call fails with error when pong arrives:
❌ EINVAL error occurred! (POSIXErrorCode 22: Invalid argument)
Test Results
Scenario
Result
Send/receive text (opcode 1)
✅ OK
Client sends ping, receives pong
❌ EINVAL on pong receive
Expected Behavior
The receive() method should successfully return ping and pong frames, or at minimum, handle them internally without throwing an error. The autoReplyPing option should allow automatic pong responses without disrupting the receive loop.
Actual Behavior
When a ping or pong control frame is received:
The receive() method throws NWError.posix(.EINVAL)
The frame never reaches user code (no opcode check is possible)
The connection remains valid, but the receive loop is interrupted
Workaround
Catch the EINVAL error and restart the receive loop:
while !Task.isCancelled {
do {
let received = try await connection.receive()
// Process message
} catch let error as NWError {
if case .posix(let code) = error, code == .EINVAL {
// Control frame caused EINVAL, continue receiving
continue
}
throw error
}
}
This workaround allows continued operation but:
Cannot distinguish between ping-related EINVAL and other EINVAL errors
Cannot access the ping/pong frame content
Cannot implement custom ping/pong handling
Impact
WebSocket connections to servers that send periodic pings will experience repeated EINVAL errors
Applications must implement workarounds that may mask other legitimate errors
Additional Information
Packet capture confirms ping/pong frames are correctly transmitted at the network level
The error occurs in the Network framework's internal processing, before reaching user code
Our app has a network extension (as I've mentioned lots 😄). We do an upgrade by downloading the new package, stopping & removing all of our components except for the network extension, and then installing the new package, which then loads a LaunchAgent causing the containing app to run. (The only difference between a new install and upgrade is the old extension is left running, but not having anything to tell it what to do, just logs and continues.)
On some (but not all) upgrades... nothing ends up able to communicate via XPC with the Network Extension. My simplest cli program to talk to it gets
Could not create proxy: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named blah was invalidated: failed at lookup with error 3 - No such process." UserInfo={NSDebugDescription=The connection to service named bla was invalidated: failed at lookup with error 3 - No such process.}
Could not communicate with blah
Restarting the extension by doing a kill -9 doesn't fix it; neither does restarting the control daemon. The only solution we've come across so far is rebooting.
I filed FB11086599 about this, but has anyone thoughts about this?
Hi,
Since iOS 26 (and any other apple system with a 26 version) there is a very weird behavior in the whole apple ecosystem (iOS, iPadOS, macOS and visionOS).
I'm self-hosting a web project called mempool (https://github.com/Retropex/mempool). This project is entirely self-hosted on my own infrastructure, so I have advanced control to be sure it's just not an anti-DDoS feature that makes the bug happen.
So the bug is once I visit my website, for example this page (https://mempool.guide/tx/d86192252a6631831e55f814aea901e65407b6dbda77e1abdea8ec27861e9682) the OS will lose the ability to connect to the underlying IP of the domain (mempool.guide) but the issue seems to affect only the HTTPS/HTTP port (443/80). The issue is system wide, not only is Safari.
For exemple I have another domain that resolve to the same IP (haf.ovh) and if this link above trigger the bug then I will also lose the ability to connect to https://haf.ovh
A temporary fix that I have is that if I turn off wifi/cellular then I turn it on again I can connect again to my server again until the bug is triggered again.
I have done test with tcpdump on my server and the connection isn't making it to my server that's why I think it's an OS issue, especially given the fix above.
This issue can be reproduced on any apple device out of the box with a system with >v26.
All device (Mac, iPad, iPhone, vision) with version pre-26 are completely unaffected by the bug and can freely explore the website without loosing the connection
macOS is less affected by this bug, it can be random with it.
With iOS/iPadOS it's systematic.
Another thing to note is that the same URL on firefox/chrome for iOS doesn't trigger the bug.
Let me know if anyone has an idea on what's going on.
Thanks, Léo.
My code makes an iPhone use the CBCentralManager to talk to devices peripherals over core bluetooth.
After attempting a connect to a peripheral device, I get a didConnect callback on CBCentralManagerDelegate.
After this I initiate discovery of services using:
peripheral.discoverServices([CBUUID(nsuuid: serviceUUID)])
Since I am only interested in discovering my service of interest and not the others to speed up time to the actual sending of data.
This also gives me the didDiscoverServices callback without error prints in which I do the following:
guard let services = peripheral.services, !services.isEmpty else {
print("Empty services")
centralManager.cancelPeripheralConnection(peripheral)
return
}
And for next steps
if let serviceOfInterest = services.first(where: {$0.uuid == CBUUID(nsuuid: serviceUUID)}) { //double check for service we want
initiateDiscoverCharacteristics(peripheral: peripheral, service: serviceOfInterest)
}
Below is what initiateDiscoverCharacteristics() does. I basically only tries to discover certain characteristics of the selected service:
peripheral.discoverCharacteristics(
[CBUUID(nsuuid: readUUID),
CBUUID(nsuuid: writeUUID)],
for: serviceOfInterest)
For this also we get the didDiscoverCharacteristicsFor callback without error prints.
Here in this callback however we were not doing the serviceOfInterest check to see that we are getting the callback for the service we expect, since our understanding was that we will get didDiscoverCharacteristicsFor callback for the characteristics on the serviceOfInterest because that is what peripheral.discoverCharacteristics() was initiated for.
When we go ahead to write some data/subscribe for notify/read data we have 2 guard statements for services and characteristics of a particular service.
The first guard below passes:
if(peripheral.services == nil) {
print("services yet to be discovered \(peripheral.identifier.uuidString)")
return
}
However the second guard below fails:
let serviceOfInterest = peripheral.services?.first(where: {$0.uuid == CBUUID(nsuuid: serviceUUID})
if((serviceOfInterest?.characteristics == nil) || (serviceOfInterest?.characteristics == [])) {
print("characteristics yet to be discovered \(peripheral.identifier.uuidString)")
return
}
First of all, does the iPhone go ahead and discover other characteristics and services separately even when we explicitly mention the service and the characteristics it should discover?
Now if you say yes and that it maybe the reason of our bug because we didn't do a check for serviceOfInterest in didDiscoverCharacteristicsFor callback, then I have another question.
Why don't we get a second/third print in didDiscoverCharacteristicsFor callback signifying that more characteristics were discovered?
The peripheral device just disconnects after a set timeout (peripheral device used in our testing does this if we are not communicating with it for a certain amount of time).
This issue is extremely rare. We have seen it only twice in our customer base. Both the instances were on the same iPhone 15 Pro. Once a few months back and once recently. Currently, this iPhone is having iOS version 18.1.1 running on it.
Hi,
We’re seeing our build system (Gradle) get stuck in sendto system calls while trying to communicate with other processes via the local interface over UDP. To the end user it appears that the build is stuck or they will receive an error “Timeout waiting to lock XXX. It is currently in use by another Gradle instance”. But when the process is sampled/profiled, we can see one of the threads is stuck in a sendto system call. The only way to resolve the issue is to kill -s KILL <pid> the stuck Gradle process.
A part of the JVM level stack trace:
"jar transforms Thread 12" #90 prio=5 os_prio=31 cpu=0.85ms elapsed=1257.67s tid=0x000000012e6cd400 nid=0x10f03 runnable [0x0000000332f0d000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.DatagramChannelImpl.send0(java.base@17.0.10/Native Method)
at sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(java.base@17.0.10/DatagramChannelImpl.java:901)
at sun.nio.ch.DatagramChannelImpl.send(java.base@17.0.10/DatagramChannelImpl.java:863)
at sun.nio.ch.DatagramChannelImpl.send(java.base@17.0.10/DatagramChannelImpl.java:821)
at sun.nio.ch.DatagramChannelImpl.blockingSend(java.base@17.0.10/DatagramChannelImpl.java:853)
at sun.nio.ch.DatagramSocketAdaptor.send(java.base@17.0.10/DatagramSocketAdaptor.java:218)
at java.net.DatagramSocket.send(java.base@17.0.10/DatagramSocket.java:664)
at org.gradle.cache.internal.locklistener.FileLockCommunicator.pingOwner(FileLockCommunicator.java:61)
at org.gradle.cache.internal.locklistener.DefaultFileLockContentionHandler.maybePingOwner(DefaultFileLockContentionHandler.java:203)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock$1.run(DefaultFileLockManager.java:380)
at org.gradle.internal.io.ExponentialBackoff.retryUntil(ExponentialBackoff.java:72)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock.lockStateRegion(DefaultFileLockManager.java:362)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock.lock(DefaultFileLockManager.java:293)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock.<init>(DefaultFileLockManager.java:164)
at org.gradle.cache.internal.DefaultFileLockManager.lock(DefaultFileLockManager.java:110)
at org.gradle.cache.internal.LockOnDemandCrossProcessCacheAccess.incrementLockCount(LockOnDemandCrossProcessCacheAccess.java:106)
at org.gradle.cache.internal.LockOnDemandCrossProcessCacheAccess.acquireFileLock(LockOnDemandCrossProcessCacheAccess.java:168)
at org.gradle.cache.internal.CrossProcessSynchronizingCache.put(CrossProcessSynchronizingCache.java:57)
at org.gradle.api.internal.changedetection.state.DefaultFileAccessTimeJournal.setLastAccessTime(DefaultFileAccessTimeJournal.java:85)
at org.gradle.internal.file.impl.SingleDepthFileAccessTracker.markAccessed(SingleDepthFileAccessTracker.java:51)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.markAccessed(DefaultCachedClasspathTransformer.java:209)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.transformFile(DefaultCachedClasspathTransformer.java:194)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.lambda$cachedFile$6(DefaultCachedClasspathTransformer.java:186)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer$$Lambda$368/0x0000007001393a78.call(Unknown Source)
at org.gradle.internal.UncheckedException.unchecked(UncheckedException.java:74)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.lambda$transformAll$8(DefaultCachedClasspathTransformer.java:233)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer$$Lambda$372/0x0000007001398470.call(Unknown Source)
at java.util.concurrent.FutureTask.run(java.base@17.0.10/FutureTask.java:264)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@17.0.10/ThreadPoolExecutor.java:1136)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@17.0.10/ThreadPoolExecutor.java:635)
at java.lang.Thread.run(java.base@17.0.10/Thread.java:840)
A part of the process sample:
2097 Thread_3879661: Java: jar transforms Thread 12
+ 2097 thread_start (in libsystem_pthread.dylib) + 8 [0x18c42eb80]
...removed for brevity...
+ 2097 Java_sun_nio_ch_DatagramChannelImpl_send0 (in libnio.dylib) + 84 [0x102ef371c]
+ 2097 __sendto (in libsystem_kernel.dylib) + 8 [0x18c3f612c]
We have observed the following system logs around the time the issue manifests:
2025-08-26 22:03:23.280255+0100 0x3b2c00 Default 0x0 0 0 kernel: cfil_hash_entry_log:6088 <CFIL: Error: sosend_reinject() failed>: [4628 java] <UDP(17) in so 9e934ceda1c13379 50826943645358435 50826943645358435 ag>
2025-08-26 22:03:23.280267+0100 0x3b2c00 Default 0x0 0 0 kernel: cfil_service_inject_queue:4472 CFIL: sosend() failed 22
The issue seems to be rooted in the built-in Application Firewall, as disabling it “fixes” the issue. It doesn’t seem to matter that the process is on the “allow” list.
We’re using Gradle 7.6.4, 8.0.2 and 8.14.1 in various repositories, so the version doesn’t seem to matter, neither does which repo we use.
The most reliable way to reproduce is to run two Gradle builds at the same time or very quickly after each other.
We would really appreciate a fix for this as it really negatively affects the developer experience. I've raised FB19916240 for this.
Many thanks,
This is a major issue. After my iPhone 12 Pro was upgraded to iOS 26 beta 6, Apple's official Wi-Fi Aware Sample APP crashed immediately and couldn't be opened. It just force closes.
Has any developer encountered this problem?
I'm building an app that helps manage my own wifi access points. Now, all my wifis emit SSIDs starting with the same prefix. Is it possible for me to list down all the SSIDs near me that start with that prefix, so that determine which of my wifis are near me? (Swift)
Can NEHotspotHelper or NEHotspotConfigurationManager help in this regard?
I’m using an NETransparentProxyProvider where I add UDP-53 rules to intercept DNS queries from a private application. These queries are resolved locally on the endpoint by returning a custom DNS response.
Example Rules look like this:
NENetworkRule(destinationHost: NWHostEndpoint(hostname: "mypaapp.com", port: 53),protocol:.UDP)
This works as expected through browser and ping.
handleNewUDPFlow/handleNewFlow with NEAppProxyUDPFlow gets called where custom dns response get written.
Using nslookup mypaapp.com doesn't works.
Why does this behaves differently for nslookup?
we use the api as
NEHotspotConfigurationManager.shared.apply(hotspotConfig)
to join a wifi, but we find that in in iphone 17+, some user report the time to join wifi is very slow
the full code as
let hotspotConfig = NEHotspotConfiguration(ssid: sSSID, passphrase: sPassword, isWEP: false)
hotspotConfig.joinOnce = bJoinOnce
if #available(iOS 13.0, *) {
hotspotConfig.hidden = true
}
NEHotspotConfigurationManager.shared.apply(hotspotConfig) { [weak self] (error) in
guard let self else {
return
}
if let error = error {
log.i("connectSSID Error while configuring WiFi: \(error.localizedDescription)")
if error.localizedDescription.contains("already associated") {
log.i("connectSSID Already connected to this WiFi.")
result(["status": 0])
} else {
result(["status": 0])
}
} else {
log.i("connectSSID Successfully connected to WiFi network \(sSSID)")
result(["status": 1])
}
}
Normally it might only take 5-10 seconds, but on the iPhone 17+ it might take 20-30 seconds.
We have an application which is written in Swift, which activates two network extensions (Content Filter, Transparent Proxy). We want to use MDM deployment for these network system extensions.
For Content Filter, we already have Jamf Profile which has Web Content Filter payload and it works fine.
Our Transparent Proxy module is a system extension, which is exposing an app proxy provider interface (We are using NETransparentProxyProvider class and in extension’s Info.plist we use com.apple.networkextension.app-proxy key.) We don’t have any remote server setup to forward the traffic, instead we open a connection with a certain localhost:port to redirect the traffic which is received in our transparent proxy. We have another module that listens to the particular localhost:port to process the traffic further.
We are unable to find the appropriate payload in any of the Profile Editor applications like Apple Configurator, iMazing Profile Editor and Jamf Pro that correctly describes our setup.
As per https://developer.apple.com/documentation/devicemanagement/vpn/transparentproxy documentation, we noticed that we can use the VPN payload with app-proxy as Provider Type for Transparent Proxy.
Here are the list of issues encountered with different MDM solutions.
**AppleConfigurator: **
We were able to install the profile created via Apple Configurator. However when we install our product (which has the above mentioned system extensions), the Transparent Proxy added by our product fails to map with the installed profile. User has to provide the credentials and follow the steps while installing the extension via the product.
Attached the screenshot of "Network->Filters" screen and the profile for reference.
Profile Created using Apple Configurator
iMazing Profile Editor:
Unable to install the profile created using iMazing Profile Editor.
Attached the screenshot of error and the profile for reference:
Profile Created Using iMazing Profile Editor
Jamf Pro:
We were able to install the profile created via Jamf Pro and also while in stalling our product the Transparent Proxy gets mapped with the one which is installed via profile. However after that the network is broken and hence unable to browse anything.
Attached the profile for reference.
Profile Created using Jamf Pro
What should be the correct profile payload to use for our Transparent Proxy?
Topic:
App & System Services
SubTopic:
Networking
Tags:
Network Extension
System Extensions
Device Management
In my application, there is a Network Extension with the bundle ID com.xxx.agent.yyy.zzz.ne. There is a user upgraded their system to macOS Sequoia 15.3, they faced an issue where enabling this Network Extension failed. Even after uninstalling the application and the Network Extension, restarting the system, and reinstalling multiple times, the enabling process still failed.
it alert: Failed to enable the Network Extension.
When checking the status via "systemextension list", it always shows "activated waiting for user".
This shows the normal enabling process log:
This shows the log when the enabling fails upon clicking. Strangely enough, there is no activation operation log when it fails. What could be the problem?