Networking

RSS for tag

Explore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.

Networking Documentation

Posts under Networking subtopic

Post

Replies

Boosts

Views

Activity

Stumped by URLSession behaviour I don't understand...
I have an app that has been using the following code to down load audio files: if let url = URL(string: episode.fetchPath()) { var request = URLRequest(url: url) request.httpMethod = "get" let task = session.downloadTask(with: request) And then the following completionHandler code: func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { try FileManager.default.moveItem(at: location, to: localUrl) In the spirit of modernization, I'm trying to update this code to use async await: var request = URLRequest(url: url) request.httpMethod = "get" let (data, response) = try await URLSession.shared.data(for: request) try data.write(to: localUrl, options: [.atomicWrite, .completeFileProtection]) Both these code paths use the same url value. Both return the same Data blobs (they return the same hash value) Unfortunately the second code path (using await) introduces a problem. When the audio is playing and the iPhone goes to sleep, after 15 seconds, the audio stops. This problem does not occur when running the first code (using the didFinish completion handler) Same data, stored in the same URL, but using different URLSession calls. I would like to use async/await and not have to experience the audio ending after just 15 seconds of the device screen being asleep. any guidance greatly appreciated.
7
0
818
Jan ’26
Getting a basic URL Filter to work
I haven’t been able to get this to work at any level! I’m running into multiple issues, any light shed on any of these would be nice: I can’t implement a bloom filter that produces the same output as can be found in the SimpleURLFilter sample project, after following the textual description of it that’s available in the documentation. No clue what my implementation is doing wrong, and because of the nature of hashing, there is no way to know. Specifically: The web is full of implementations of FNV-1a and MurmurHash3, and they all produce different hashes for the same input. Can we get the proper hashes for some sample strings, so we know which is the “correct” one? Similarly, different implementations use different encodings for the strings to hash. Which should we use here? The formulas for numberOfBits and numberOfHashes give Doubles and assign them to Ints. It seems we should do this conversing by rounding them, is this correct? Can we get a sample correct value for the combined hash, so we can verify our implementations against it? Or ignoring all of the above, can we have the actual code instead of a textual description of it? 😓 I managed to get Settings to register my first attempt at this extension in beta 1. Now, in beta 2, any other project (including the sample code) will redirect to Settings, show the Allow/Deny message box, I tap Allow, and then nothing happens. This must be a bug, right? Whenever I try to enable the only extension that Settings accepted (by setting its isEnabled to true), its status goes to .stopped and the error is, of course, .unknown. How do I debug this? While the extension is .stopped, ALL URL LOADS are blocked on the device. Is this to be expected? (shouldFailClosed is set to false) Is there any way to manually reload the bloom filter? My app ships blocklist updates with background push, so it would be wasteful to fetch the filter at a fixed interval. If so, can we opt out of the periodic fetch altogether? I initially believed the API to be near useless because I didn’t know of its “fuzzy matching” capabilities, which I’ve discovered by accident in a forum post. It’d be nice if those were documented somewhere! Thanks!!
81
2
6.3k
1w
DNS Proxy Provider remains active after app uninstall | iOS
Hi, I've encountered a strange behavior in the DNS Proxy Provider extension. Our app implements both DNS Proxy Provider and Content Filter Providers extensions, configured via MDM. When the app is uninstalled, the behavior of the providers differs: For Content Filter Providers (both Filter Control and Filter Data Providers), the providers stop as expected with the stop reason: /** @const NEProviderStopReasonProviderDisabled The provider was disabled. */ case providerDisabled = 5 However, for the DNS Proxy Provider, the provider remains in the "Running" state, even though there is no app available to match the provider's bundle ID in the uploaded configuration profile. When the app is reinstalled: The Content Filter Providers start as expected. The DNS Proxy Provider stops with the stop reason: /** @const NEProviderStopReasonAppUpdate The NEProvider is being updated */ @available(iOS 13.0, *) case appUpdate = 16 At this point, the DNS Proxy Provider remains in an 'Invalid' state. Reinstalling the app a second time seems to resolve the issue, with both the DNS Proxy Provider and Content Filter Providers starting as expected. This issue seems to occur only if some time has passed after the DNS Proxy Provider entered the 'Running' state. It appears as though the system retains a stale configuration for the DNS Proxy Provider, even after the app has been removed. Steps to reproduce: Install the app and configure both DNS Proxy Provider and Content Filter Providers using MDM. Uninstall the app. Content Filter Providers are stopped as expected (NEProviderStopReason.providerDisabled = 5). DNS Proxy Provider remains in the 'Running' state. Reinstall the app. Content Filter Providers start as expected. DNS Proxy Provider stops with NEProviderStopReason.appUpdate (16) and remains 'Invalid'. Reinstall the app again. DNS Proxy Provider now starts as expected. This behavior raises concerns about how the system manages the lifecycle of DNS Proxy Provider, because DNS Proxy Provider is matched with provider bundle id in .mobileconfig file. Has anyone else experienced this issue? Any suggestions on how to address or debug this behavior would be highly appreciated. Thank you!
22
1
1k
Oct ’25
App Store Requirements: SSL Certificates for Home Raspberry Pi Servers – Practical Solutions?
Hello, A customer has requested the development of a home assistance app to be published on the App Store. The app will connect to a server running locally at the end user's home, for example on a Raspberry Pi. Users would enter the IP address or hostname of their personal server into the app. A strict requirement is that, for data protection reasons, there must not be any proxy server. The app should only communicate directly with the local server (e.g., Raspberry Pi). We are able to solve technical challenges such as DNS, dynamic IP, and port forwarding, router configuration. However, I'm concerned about Apple's requirement that the endpoint – in this case, the Raspberry Pi at the user's home – must not use self-signed SSL certificates. While it may be technically possible to secure the home server with a certificate provider like Let's Encrypt, it is unrealistic to expect a typical user with no technical training to accomplish this setup independently. Is there a recommended solution to this problem, particularly in the context of IoT devices and apps? Any advice or experiences would be deeply appreciated.
1
0
131
Jan ’26
Once started, NWPathMonitor appears to be kept alive until cancelled, but is this documented?
NWPathMonitor appears to retain itself (or is retained by some internal infrastructure) once it has been started until cancelled. This seems like it can lead to memory leaks if the references to to the monitor are dropped. Is this behavior documented anywhere? func nwpm_self_retain() { weak var weakRef: NWPathMonitor? autoreleasepool { let monitor: NWPathMonitor = NWPathMonitor() weakRef = monitor monitor.start(queue: .main) // monitor.cancel() // assertion fails unless this is called } assert(weakRef == nil) } nwpm_self_retain()
3
0
151
Jan ’26
Content & URL filtering
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,
4
0
156
Jan ’26
System Information in macOS 26.2 RC no longer shows Wi-Fi SSIDs
System Information in macOS from 26.0 to 26.2 RC no longer provides Wi-Fi SSIDs; instead, it displays "< redacted> " for every SSID on my two MacBooks. This issue has been fixed in macOS 26.1 beta and macOS 26.2 beta, but it returns in the RC and the Final Release versions. Is it an expected behaviour or a bug in the Release Candidate? MacBook Air 2025: MacBook Pro 2021:
1
0
259
Dec ’25
KeyChain Sharing with App Extensions
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
4
0
378
Dec ’25
NetworkConnection throws EINVAL when receiving ping/pong control frames
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
5
0
296
Dec ’25
Can an e-commerce iOS app running in the Xcode Simulator disrupt NETransparentProxyProvider and NEFilterDataProvider, causing DNS failures on macOS
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.
3
0
453
Dec ’25
TN3134 clarification: DNS Proxy Provider unusable without MDM on iOS?
Hi, I’m looking for clarification on TN3134: Network Extension provider deployment, specifically iOS deployment requirements for: packet tunnel provider DNS proxy provider From the documentation: Packet Tunnel Provider App extension (min iOS 9.0): per-app mode requires a managed device DNS Proxy Provider App extension (min iOS 11.0): supervised devices only App extension (min iOS 11.0): per-app mode requires managed devices Issue I implemented a DNS proxy using NEDNSProxyManager. Works as expected in debug builds on a local device Fails to configure when distributed via TestFlight Console Output (TestFlight build) error 10:05:39.872258-0500 nehelper The production version of *** is not allowed to create DNS proxy configurations. Use MDM to create DNS Proxy configurations for the production version of ***. Question Is it possible to distribute a DNS proxy provider for use on non-MDM / non-supervised devices? If not: Is the limitation strictly enforced at distribution/runtime? Is a packet tunnel provider the only viable alternative for App Store distribution? There is a lot of different VPN apps on the App Store that appear to work out of the box without MDM or supervision, which suggests they are using a different deployment model. Thank you for any clarification or guidance!
2
0
245
Apr ’26
How to use DNSServiceReconfirmRecord?
TL;DR: How does one use DNSServiceReconfirmRecord() to invalidate mDNS state of a device that's gone offline? I'm using the DNSServiceDiscovery API (dns_sd.h) for a local P2P service. The problem I'm trying to solve is how to deal with a peer that abruptly loses connectivity, i.e. by turning off WiFi or simply by moving out of range or otherwise losing connectivity. In this situation there is of course no notification that the peer device has gone offline; it simply stops sending any packets. After my own timeout mechanism determines the peer is not responding, I mark it as offline in my own data structures. The problem is how to discover when/if it comes back online later. My DNSServiceBrowse callback won't be invoked because mDNS doesn't know the device went offline in the first place. I am trying to use DNSServiceReconfirmRecord, which appears to be for exactly this use case -- "Instruct the daemon to verify the validity of a resource record that appears to be out of date (e.g. because TCP connection to a service's target failed.)" However my attempts always return a BadReference error (-65541). The function requires me to pass a DNS record, and the only one I know is the TXT record; perhaps it needs a different one? Which, and how would I get it? Thanks!
7
0
227
Feb ’26
Why nslookup dns queries not routed to NETransparentProxyProvider
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?
1
0
134
Dec ’25
VPN with per-app and allowed IPs
We’re implementing VPN application using the WireGuard protocol and aiming to support both split-tunnel and per-app VPN configurations. Each mode works correctly on its own: per-app VPN functions well when configured with a full tunnel and split-tunnel works as expected when per-app is disabled. However, combining both configurations leads to issues. Specifically, the routing table is not set up properly, resulting in traffic that should not be routed through the tunnel is routed through the tunnel. Detailed description: Through our backend, we are pushing these two plist files to the iPad one after the other: VPN config with allowed IPs 1.1.1.1/32 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" http://www.apple.com/DTDs/PropertyList-1.0.dtd> <plist version="1.0"> <dict> <key>PayloadUUID</key> <string>3fd861df-c917-4716-97e5-f5e96452436a</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadOrganization</key> <string>someorganization</string> <key>PayloadIdentifier</key> <string>config.11ff5059-369f-4a71-afea-d5fdbfa99c91</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadDisplayName</key> <string> test</string> <key>PayloadDescription</key> <string>(Version 13) </string> <key>PayloadRemovalDisallowed</key> <true /> <key>PayloadContent</key> <array> <dict> <key>VPN</key> <dict> <key>AuthenticationMethod</key> <string>Password</string> <key>ProviderType</key> <string>packet-tunnel</string> <key>OnDemandUserOverrideDisabled</key> <integer>1</integer> <key>RemoteAddress</key> <string>172.17.28.1:51820</string> <key>OnDemandEnabled</key> <integer>1</integer> <key>OnDemandRules</key> <array> <dict> <key>Action</key> <string>Connect</string> </dict> </array> <key>ProviderBundleIdentifier</key> <string>some.bundle.id.network-extension</string> </dict> <key>VPNSubType</key> <string>some.bundle.id</string> <key>VPNType</key> <string>VPN</string> <key>VPNUUID</key> <string>d2773557-b535-414f-968a-5447d9c02d52</string> <key>OnDemandMatchAppEnabled</key> <true /> <key>VendorConfig</key> <dict> <key>VPNConfig</key> <string> Some custom configuration here </string> </dict> <key>UserDefinedName</key> <string>TestVPNServerrra</string> <key>PayloadType</key> <string>com.apple.vpn.managed.applayer</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadIdentifier</key> <string>vpn.5e6b56be-a4bb-41a5-949e-4e8195a83f0f</string> <key>PayloadUUID</key> <string>9bebe6e2-dbef-4849-a1fb-3cca37221116</string> <key>PayloadDisplayName</key> <string>Vpn</string> <key>PayloadDescription</key> <string>Configures VPN settings</string> <key>PayloadOrganization</key> <string>someorganization</string> </dict> </array> </dict> </plist> Command to set up per-app with Chrome browser <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" http://www.apple.com/DTDs/PropertyList-1.0.dtd> <plist version="1.0"> <dict> <key>Command</key> <dict> <key>Settings</key> <array> <dict> <key>Identifier</key> <string>com.google.chrome.ios</string> <key>Attributes</key> <dict> <key>VPNUUID</key> <string>d2773557-b535-414f-968a-5447d9c02d52</string> <key>TapToPayScreenLock</key> <false /> <key>Removable</key> <true /> </dict> <key>Item</key> <string>ApplicationAttributes</string> </dict> </array> <key>RequestType</key> <string>Settings</string> </dict> <key>CommandUUID</key> <string>17ce3e19-35ef-4dbc-83d9-4ca2735ac430</string> </dict> </plist> From the log we see that our VPN application set up allowed IP 1.1.1.1 via NEIPv4Settings.includedRoutes but system routing all of the Chrome browser traffic through our application. Is this expected Apple iOS behavior, or are we misconfiguring the profiles?
1
0
169
Nov ’25
Crash in URLConnectionLoader::loadWithWhatToDo
There are multiple report of crashes on URLConnectionLoader::loadWithWhatToDo. The crashed thread in the stack traces pointing to calls inside CFNetwork which seems to be internal library in iOS. The crash has happened quite a while already (but we cannot detect when the crash started to occur) and impacted multiple iOS versions recorded from iOS 15.4 to 18.4.1 that was recorded in Xcode crash report organizer so far. Unfortunately, we have no idea on how to reproduce it yet but the crash keeps on increasing and affect more on iOS 18 users (which makes sense because many people updated their iOS to the newer version) and we haven’t found any clue on what actually happened and how to fix it on the crash reports. What we understand is it seems to come from a network request that happened to trigger the crash but we need more information on what (condition) actually cause it and how to solve it. Hereby, I attach sample crash report for both iOS 15 and 18. I also have submitted a report (that include more crash reports) with number: FB17775979. Will appreciate any insight regarding this issue and any resolution that we can do to avoid it. iOS 15.crash iOS 18.crash
10
1
801
Jan ’26
Wi-Fi Raw Socket Disconnection Issue on iPhone 17 Series
On my iPhone 16 Pro and iPhone 16 Pro Max devices, running iOS 26.0, 26.0.1, and 26.1, Wi-Fi raw socket communication works flawlessly. Even after keeping the connection active for over 40 minutes, there are no disconnections during data transmission. However, on the iPhone 17 and iPhone 17 Pro, the raw socket connection drops within 20 seconds. Once it disconnects, the socket cannot reconnect unless the Wi-Fi module itself is reset. I believe this issue is caused by a bug in the iPhone 17 series’ communication module. I have looked into many cases, and it appears to be related to a bug in the N1 chipset. Are there any possible solutions or workarounds for this issue?
7
1
407
Mar ’26
Content filter installed but not running
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?
1
0
133
Oct ’25
URL filter app with multiple configurations
Hello, We've been working on an app that uses the new NEUrlFilter API and we've got a question. Currently, the system is designed with the assumption that a single app == usecase == single remote database. But what if we would like to give the user the ability to use different blocklists? For example, the user may want to: Block scam domains Block tracking domains Block adult domains Or any composition of these 3 What should we do to give the user this option? It seems that we could differentiate different databases by using different PIR service hostnames, but that would also mean that we'll have to send several requests for the same usecase but with different PIR service hostnames (and they'll all share the same app bundle ID). Will these requests be accepted then? If not, is there an alternative? PS: By sending a request I mean submitting this form
1
1
169
Oct ’25
Wi-Fi connectivity Issue - Captive.apple.com returns “application/octet-stream” instead of “text/html”,
In our system, when a user enables a mobile hotspot and the system connects to it, the system attempts to verify WIFI availability by sending an HTTP GET request to http://captive.apple.com. Normally, the server returns: HTTP Status: 200 (OK) Content-Type: text/html This has always been used as a sign of normal connectivity. Issue: Since last Friday, the server sometimes responds with: Content-Type: application/octet-stream When this occurs, our system determines that the network is unavailable and displays a connection warning (a “!” icon). Question: Has Apple recently made any backend or CDN configuration changes to captive.apple.com that could affect the response type? Any advice how can we solve this problem? Thanks!
3
1
1.1k
Jan ’26
Stumped by URLSession behaviour I don't understand...
I have an app that has been using the following code to down load audio files: if let url = URL(string: episode.fetchPath()) { var request = URLRequest(url: url) request.httpMethod = "get" let task = session.downloadTask(with: request) And then the following completionHandler code: func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { try FileManager.default.moveItem(at: location, to: localUrl) In the spirit of modernization, I'm trying to update this code to use async await: var request = URLRequest(url: url) request.httpMethod = "get" let (data, response) = try await URLSession.shared.data(for: request) try data.write(to: localUrl, options: [.atomicWrite, .completeFileProtection]) Both these code paths use the same url value. Both return the same Data blobs (they return the same hash value) Unfortunately the second code path (using await) introduces a problem. When the audio is playing and the iPhone goes to sleep, after 15 seconds, the audio stops. This problem does not occur when running the first code (using the didFinish completion handler) Same data, stored in the same URL, but using different URLSession calls. I would like to use async/await and not have to experience the audio ending after just 15 seconds of the device screen being asleep. any guidance greatly appreciated.
Replies
7
Boosts
0
Views
818
Activity
Jan ’26
Getting a basic URL Filter to work
I haven’t been able to get this to work at any level! I’m running into multiple issues, any light shed on any of these would be nice: I can’t implement a bloom filter that produces the same output as can be found in the SimpleURLFilter sample project, after following the textual description of it that’s available in the documentation. No clue what my implementation is doing wrong, and because of the nature of hashing, there is no way to know. Specifically: The web is full of implementations of FNV-1a and MurmurHash3, and they all produce different hashes for the same input. Can we get the proper hashes for some sample strings, so we know which is the “correct” one? Similarly, different implementations use different encodings for the strings to hash. Which should we use here? The formulas for numberOfBits and numberOfHashes give Doubles and assign them to Ints. It seems we should do this conversing by rounding them, is this correct? Can we get a sample correct value for the combined hash, so we can verify our implementations against it? Or ignoring all of the above, can we have the actual code instead of a textual description of it? 😓 I managed to get Settings to register my first attempt at this extension in beta 1. Now, in beta 2, any other project (including the sample code) will redirect to Settings, show the Allow/Deny message box, I tap Allow, and then nothing happens. This must be a bug, right? Whenever I try to enable the only extension that Settings accepted (by setting its isEnabled to true), its status goes to .stopped and the error is, of course, .unknown. How do I debug this? While the extension is .stopped, ALL URL LOADS are blocked on the device. Is this to be expected? (shouldFailClosed is set to false) Is there any way to manually reload the bloom filter? My app ships blocklist updates with background push, so it would be wasteful to fetch the filter at a fixed interval. If so, can we opt out of the periodic fetch altogether? I initially believed the API to be near useless because I didn’t know of its “fuzzy matching” capabilities, which I’ve discovered by accident in a forum post. It’d be nice if those were documented somewhere! Thanks!!
Replies
81
Boosts
2
Views
6.3k
Activity
1w
DNS Proxy Provider remains active after app uninstall | iOS
Hi, I've encountered a strange behavior in the DNS Proxy Provider extension. Our app implements both DNS Proxy Provider and Content Filter Providers extensions, configured via MDM. When the app is uninstalled, the behavior of the providers differs: For Content Filter Providers (both Filter Control and Filter Data Providers), the providers stop as expected with the stop reason: /** @const NEProviderStopReasonProviderDisabled The provider was disabled. */ case providerDisabled = 5 However, for the DNS Proxy Provider, the provider remains in the "Running" state, even though there is no app available to match the provider's bundle ID in the uploaded configuration profile. When the app is reinstalled: The Content Filter Providers start as expected. The DNS Proxy Provider stops with the stop reason: /** @const NEProviderStopReasonAppUpdate The NEProvider is being updated */ @available(iOS 13.0, *) case appUpdate = 16 At this point, the DNS Proxy Provider remains in an 'Invalid' state. Reinstalling the app a second time seems to resolve the issue, with both the DNS Proxy Provider and Content Filter Providers starting as expected. This issue seems to occur only if some time has passed after the DNS Proxy Provider entered the 'Running' state. It appears as though the system retains a stale configuration for the DNS Proxy Provider, even after the app has been removed. Steps to reproduce: Install the app and configure both DNS Proxy Provider and Content Filter Providers using MDM. Uninstall the app. Content Filter Providers are stopped as expected (NEProviderStopReason.providerDisabled = 5). DNS Proxy Provider remains in the 'Running' state. Reinstall the app. Content Filter Providers start as expected. DNS Proxy Provider stops with NEProviderStopReason.appUpdate (16) and remains 'Invalid'. Reinstall the app again. DNS Proxy Provider now starts as expected. This behavior raises concerns about how the system manages the lifecycle of DNS Proxy Provider, because DNS Proxy Provider is matched with provider bundle id in .mobileconfig file. Has anyone else experienced this issue? Any suggestions on how to address or debug this behavior would be highly appreciated. Thank you!
Replies
22
Boosts
1
Views
1k
Activity
Oct ’25
App Store Requirements: SSL Certificates for Home Raspberry Pi Servers – Practical Solutions?
Hello, A customer has requested the development of a home assistance app to be published on the App Store. The app will connect to a server running locally at the end user's home, for example on a Raspberry Pi. Users would enter the IP address or hostname of their personal server into the app. A strict requirement is that, for data protection reasons, there must not be any proxy server. The app should only communicate directly with the local server (e.g., Raspberry Pi). We are able to solve technical challenges such as DNS, dynamic IP, and port forwarding, router configuration. However, I'm concerned about Apple's requirement that the endpoint – in this case, the Raspberry Pi at the user's home – must not use self-signed SSL certificates. While it may be technically possible to secure the home server with a certificate provider like Let's Encrypt, it is unrealistic to expect a typical user with no technical training to accomplish this setup independently. Is there a recommended solution to this problem, particularly in the context of IoT devices and apps? Any advice or experiences would be deeply appreciated.
Replies
1
Boosts
0
Views
131
Activity
Jan ’26
Once started, NWPathMonitor appears to be kept alive until cancelled, but is this documented?
NWPathMonitor appears to retain itself (or is retained by some internal infrastructure) once it has been started until cancelled. This seems like it can lead to memory leaks if the references to to the monitor are dropped. Is this behavior documented anywhere? func nwpm_self_retain() { weak var weakRef: NWPathMonitor? autoreleasepool { let monitor: NWPathMonitor = NWPathMonitor() weakRef = monitor monitor.start(queue: .main) // monitor.cancel() // assertion fails unless this is called } assert(weakRef == nil) } nwpm_self_retain()
Replies
3
Boosts
0
Views
151
Activity
Jan ’26
Content & URL filtering
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,
Replies
4
Boosts
0
Views
156
Activity
Jan ’26
System Information in macOS 26.2 RC no longer shows Wi-Fi SSIDs
System Information in macOS from 26.0 to 26.2 RC no longer provides Wi-Fi SSIDs; instead, it displays "< redacted> " for every SSID on my two MacBooks. This issue has been fixed in macOS 26.1 beta and macOS 26.2 beta, but it returns in the RC and the Final Release versions. Is it an expected behaviour or a bug in the Release Candidate? MacBook Air 2025: MacBook Pro 2021:
Replies
1
Boosts
0
Views
259
Activity
Dec ’25
KeyChain Sharing with App Extensions
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
Replies
4
Boosts
0
Views
378
Activity
Dec ’25
NetworkConnection throws EINVAL when receiving ping/pong control frames
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
Replies
5
Boosts
0
Views
296
Activity
Dec ’25
Can an e-commerce iOS app running in the Xcode Simulator disrupt NETransparentProxyProvider and NEFilterDataProvider, causing DNS failures on macOS
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.
Replies
3
Boosts
0
Views
453
Activity
Dec ’25
TN3134 clarification: DNS Proxy Provider unusable without MDM on iOS?
Hi, I’m looking for clarification on TN3134: Network Extension provider deployment, specifically iOS deployment requirements for: packet tunnel provider DNS proxy provider From the documentation: Packet Tunnel Provider App extension (min iOS 9.0): per-app mode requires a managed device DNS Proxy Provider App extension (min iOS 11.0): supervised devices only App extension (min iOS 11.0): per-app mode requires managed devices Issue I implemented a DNS proxy using NEDNSProxyManager. Works as expected in debug builds on a local device Fails to configure when distributed via TestFlight Console Output (TestFlight build) error 10:05:39.872258-0500 nehelper The production version of *** is not allowed to create DNS proxy configurations. Use MDM to create DNS Proxy configurations for the production version of ***. Question Is it possible to distribute a DNS proxy provider for use on non-MDM / non-supervised devices? If not: Is the limitation strictly enforced at distribution/runtime? Is a packet tunnel provider the only viable alternative for App Store distribution? There is a lot of different VPN apps on the App Store that appear to work out of the box without MDM or supervision, which suggests they are using a different deployment model. Thank you for any clarification or guidance!
Replies
2
Boosts
0
Views
245
Activity
Apr ’26
How to use DNSServiceReconfirmRecord?
TL;DR: How does one use DNSServiceReconfirmRecord() to invalidate mDNS state of a device that's gone offline? I'm using the DNSServiceDiscovery API (dns_sd.h) for a local P2P service. The problem I'm trying to solve is how to deal with a peer that abruptly loses connectivity, i.e. by turning off WiFi or simply by moving out of range or otherwise losing connectivity. In this situation there is of course no notification that the peer device has gone offline; it simply stops sending any packets. After my own timeout mechanism determines the peer is not responding, I mark it as offline in my own data structures. The problem is how to discover when/if it comes back online later. My DNSServiceBrowse callback won't be invoked because mDNS doesn't know the device went offline in the first place. I am trying to use DNSServiceReconfirmRecord, which appears to be for exactly this use case -- "Instruct the daemon to verify the validity of a resource record that appears to be out of date (e.g. because TCP connection to a service's target failed.)" However my attempts always return a BadReference error (-65541). The function requires me to pass a DNS record, and the only one I know is the TXT record; perhaps it needs a different one? Which, and how would I get it? Thanks!
Replies
7
Boosts
0
Views
227
Activity
Feb ’26
Why nslookup dns queries not routed to NETransparentProxyProvider
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?
Replies
1
Boosts
0
Views
134
Activity
Dec ’25
VPN with per-app and allowed IPs
We’re implementing VPN application using the WireGuard protocol and aiming to support both split-tunnel and per-app VPN configurations. Each mode works correctly on its own: per-app VPN functions well when configured with a full tunnel and split-tunnel works as expected when per-app is disabled. However, combining both configurations leads to issues. Specifically, the routing table is not set up properly, resulting in traffic that should not be routed through the tunnel is routed through the tunnel. Detailed description: Through our backend, we are pushing these two plist files to the iPad one after the other: VPN config with allowed IPs 1.1.1.1/32 <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" http://www.apple.com/DTDs/PropertyList-1.0.dtd> <plist version="1.0"> <dict> <key>PayloadUUID</key> <string>3fd861df-c917-4716-97e5-f5e96452436a</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadOrganization</key> <string>someorganization</string> <key>PayloadIdentifier</key> <string>config.11ff5059-369f-4a71-afea-d5fdbfa99c91</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadDisplayName</key> <string> test</string> <key>PayloadDescription</key> <string>(Version 13) </string> <key>PayloadRemovalDisallowed</key> <true /> <key>PayloadContent</key> <array> <dict> <key>VPN</key> <dict> <key>AuthenticationMethod</key> <string>Password</string> <key>ProviderType</key> <string>packet-tunnel</string> <key>OnDemandUserOverrideDisabled</key> <integer>1</integer> <key>RemoteAddress</key> <string>172.17.28.1:51820</string> <key>OnDemandEnabled</key> <integer>1</integer> <key>OnDemandRules</key> <array> <dict> <key>Action</key> <string>Connect</string> </dict> </array> <key>ProviderBundleIdentifier</key> <string>some.bundle.id.network-extension</string> </dict> <key>VPNSubType</key> <string>some.bundle.id</string> <key>VPNType</key> <string>VPN</string> <key>VPNUUID</key> <string>d2773557-b535-414f-968a-5447d9c02d52</string> <key>OnDemandMatchAppEnabled</key> <true /> <key>VendorConfig</key> <dict> <key>VPNConfig</key> <string> Some custom configuration here </string> </dict> <key>UserDefinedName</key> <string>TestVPNServerrra</string> <key>PayloadType</key> <string>com.apple.vpn.managed.applayer</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadIdentifier</key> <string>vpn.5e6b56be-a4bb-41a5-949e-4e8195a83f0f</string> <key>PayloadUUID</key> <string>9bebe6e2-dbef-4849-a1fb-3cca37221116</string> <key>PayloadDisplayName</key> <string>Vpn</string> <key>PayloadDescription</key> <string>Configures VPN settings</string> <key>PayloadOrganization</key> <string>someorganization</string> </dict> </array> </dict> </plist> Command to set up per-app with Chrome browser <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE plist PUBLIC "-//Apple Inc//DTD PLIST 1.0//EN" http://www.apple.com/DTDs/PropertyList-1.0.dtd> <plist version="1.0"> <dict> <key>Command</key> <dict> <key>Settings</key> <array> <dict> <key>Identifier</key> <string>com.google.chrome.ios</string> <key>Attributes</key> <dict> <key>VPNUUID</key> <string>d2773557-b535-414f-968a-5447d9c02d52</string> <key>TapToPayScreenLock</key> <false /> <key>Removable</key> <true /> </dict> <key>Item</key> <string>ApplicationAttributes</string> </dict> </array> <key>RequestType</key> <string>Settings</string> </dict> <key>CommandUUID</key> <string>17ce3e19-35ef-4dbc-83d9-4ca2735ac430</string> </dict> </plist> From the log we see that our VPN application set up allowed IP 1.1.1.1 via NEIPv4Settings.includedRoutes but system routing all of the Chrome browser traffic through our application. Is this expected Apple iOS behavior, or are we misconfiguring the profiles?
Replies
1
Boosts
0
Views
169
Activity
Nov ’25
Crash in URLConnectionLoader::loadWithWhatToDo
There are multiple report of crashes on URLConnectionLoader::loadWithWhatToDo. The crashed thread in the stack traces pointing to calls inside CFNetwork which seems to be internal library in iOS. The crash has happened quite a while already (but we cannot detect when the crash started to occur) and impacted multiple iOS versions recorded from iOS 15.4 to 18.4.1 that was recorded in Xcode crash report organizer so far. Unfortunately, we have no idea on how to reproduce it yet but the crash keeps on increasing and affect more on iOS 18 users (which makes sense because many people updated their iOS to the newer version) and we haven’t found any clue on what actually happened and how to fix it on the crash reports. What we understand is it seems to come from a network request that happened to trigger the crash but we need more information on what (condition) actually cause it and how to solve it. Hereby, I attach sample crash report for both iOS 15 and 18. I also have submitted a report (that include more crash reports) with number: FB17775979. Will appreciate any insight regarding this issue and any resolution that we can do to avoid it. iOS 15.crash iOS 18.crash
Replies
10
Boosts
1
Views
801
Activity
Jan ’26
After updating to Xcode26, the current SSID can no longer be retrieved
fetchCurrent(completionHandler:) https://developer.apple.com/documentation/networkextension/nehotspotnetwork/fetchcurrent(completionhandler:) The same code works fine in Xcode 16, but when I run the same project in Xcode 26, it doesn't work
Replies
1
Boosts
1
Views
112
Activity
Oct ’25
Wi-Fi Raw Socket Disconnection Issue on iPhone 17 Series
On my iPhone 16 Pro and iPhone 16 Pro Max devices, running iOS 26.0, 26.0.1, and 26.1, Wi-Fi raw socket communication works flawlessly. Even after keeping the connection active for over 40 minutes, there are no disconnections during data transmission. However, on the iPhone 17 and iPhone 17 Pro, the raw socket connection drops within 20 seconds. Once it disconnects, the socket cannot reconnect unless the Wi-Fi module itself is reset. I believe this issue is caused by a bug in the iPhone 17 series’ communication module. I have looked into many cases, and it appears to be related to a bug in the N1 chipset. Are there any possible solutions or workarounds for this issue?
Replies
7
Boosts
1
Views
407
Activity
Mar ’26
Content filter installed but not running
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?
Replies
1
Boosts
0
Views
133
Activity
Oct ’25
URL filter app with multiple configurations
Hello, We've been working on an app that uses the new NEUrlFilter API and we've got a question. Currently, the system is designed with the assumption that a single app == usecase == single remote database. But what if we would like to give the user the ability to use different blocklists? For example, the user may want to: Block scam domains Block tracking domains Block adult domains Or any composition of these 3 What should we do to give the user this option? It seems that we could differentiate different databases by using different PIR service hostnames, but that would also mean that we'll have to send several requests for the same usecase but with different PIR service hostnames (and they'll all share the same app bundle ID). Will these requests be accepted then? If not, is there an alternative? PS: By sending a request I mean submitting this form
Replies
1
Boosts
1
Views
169
Activity
Oct ’25
Wi-Fi connectivity Issue - Captive.apple.com returns “application/octet-stream” instead of “text/html”,
In our system, when a user enables a mobile hotspot and the system connects to it, the system attempts to verify WIFI availability by sending an HTTP GET request to http://captive.apple.com. Normally, the server returns: HTTP Status: 200 (OK) Content-Type: text/html This has always been used as a sign of normal connectivity. Issue: Since last Friday, the server sometimes responds with: Content-Type: application/octet-stream When this occurs, our system determines that the network is unavailable and displays a connection warning (a “!” icon). Question: Has Apple recently made any backend or CDN configuration changes to captive.apple.com that could affect the response type? Any advice how can we solve this problem? Thanks!
Replies
3
Boosts
1
Views
1.1k
Activity
Jan ’26