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

About the Relay payload in iOS configuration profiles
Are the network relays introduced in 2023 and https://developer.apple.com/videos/play/wwdc2023/10002/ the same thing as the Private Relay introduced in 2021? https://developer.apple.com/videos/play/wwdc2021/10096/ We are considering verifying the relay function, but we are not sure whether they are the same function or different functions. https://developer.apple.com/documentation/devicemanagement/relay?language=objc
0
0
40
Apr ’25
Determine outgoing flow source IPs without allowing data leakage using NEFilterDataProvider
I'm looking for help with a network extension filtering issue. Specifically, we have a subclass of NEFilterDataProvider that is used to filter flows based upon a set of rules, including source IP and destination IP. We've run into an issue where the source IP is frequently 0.0.0.0 (or the IPv6 equivalent) on outgoing flows. This has made it so rules based upon source IP don't work. This is also an issue as we report these connections, but we're lacking critical data. We were able to work around the issue somewhat by keeping a list of flows that we allow that we periodically check to see if the source IP is available, and then report after it becomes available. We also considered doing a "peekBytes" to allow a bit of data to flow and then recheck the flow, but we don't want to allow data leakage on connections that should be blocked because of the source IP. Is there a way to force the operating system or network extension frameworks to determine the source IP for an outbound flow without allowing any bytes to flow to the network? STEPS TO REPRODUCE Create a network filtering extension for filtering flows using NEFilterDataProvider See that when handleNewFlow: is called, the outgoing flow lacks the source IP (is 0.0.0.0) in most cases There is this post that is discussing a similar question, though for a slightly different reason. I imagine the answer to this and the other post will be related, at least as far as NEFilterDataProvider:handleNewFlow not having source IP is considered. Thanks!
1
0
135
Apr ’25
Ping DNS to check internet connection
I want to check if the device has a internet connection or not by pinging DNS "8.8.8.8". connection.send(content: content, completion: .contentProcessed {[weak self] error in send function is not returning any error even if the host is unreachable. I am checking if I can receive the data or not but connection.receiveMessage function never returns. This is the complete code which I am following: private let networkMonitor = NWPathMonitor() private var connection: NWConnection @MainActor var isConnectedToInternet = false init(host: NWEndpoint.Host = "8.8.8.8", port: NWEndpoint.Port = 53) { let endpoint = NWEndpoint.hostPort(host: host, port: port) connection = NWConnection(to: endpoint, using: .udp) startMonitoring() } private func startMonitoring() { networkMonitor.pathUpdateHandler = { [weak self] path in guard let self else { return } ping(callback: { isSuccess in print("***** ping status:", isSuccess) Task { @MainActor in self.isConnectedToInternet = isSuccess } }) } let queue = DispatchQueue(label: QueueLabel.networkMonitor) networkMonitor.start(queue: queue) } func ping( host: NWEndpoint.Host = "8.8.8.8", port: NWEndpoint.Port = 53, callback: @escaping ((Bool) -> Void) ) { var didSendState = false connection.stateUpdateHandler = {[weak self] state in guard let self = self else { return } guard !didSendState else { if state != .cancelled { cancel(connection) } return } switch state { case .ready: // State is ready now send data let content = "Ping".data(using: .utf8) let startTime = Date() connection.send(content: content, completion: .contentProcessed {[weak self] error in guard let self = self else { return } if error != nil { callback(false) didSendState = true cancel(connection) } else { print("Ping sent, waiting for response...") connection.receiveMessage { [weak self] content, _, _, receiveError in guard let self = self else { return } if let receiveError { print("Error receiving ping: \(receiveError.localizedDescription)") callback(false) } else if let content = content, String(data: content, encoding: .utf8) == "Ping" { let roundTripTime = Date().timeIntervalSince(startTime) print("Ping received! Round-trip time: \(roundTripTime) seconds") callback(true) } else { print("Invalid response received") callback(true) } didSendState = true cancel(connection) } } }) case .failed( _), .waiting( _), .cancelled: didSendState = true callback(false) case .setup, .preparing: // No callback because the ping has not yet succeeded or failed break @unknown default: didSendState = true callback(false) // We don't know what this unknown default means, so cancel pings to be safe cancel(connection) } } connection.start(queue: .main) } func cancel(_ connection: NWConnection) { connection.cancel() } } Can anyone please help what I am doing wrong.
2
0
290
Jan ’25
HTTP operation not permitted
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!
1
0
166
Feb ’25
I want to know why the "NSURLErrorDomain Code=-1000" error occurs and how to fix it?
PLATFORM AND VERSION: iOS Development environment: Xcode 15.4, macOS 14.4 PROBLEM iOS VERSION: iOS 17.2.1 ~ 18.1.1 DEVELOPMENT LANGUAGE: Object-C Case-ID: 10969723 (Due to privacy concerns, I have hidden part of the URL and included the complete plain text in the email demo project with Case-ID: 10969723) After our game was launched in Japan, a small number of Japanese users reported that they were unable to enter the game. After our investigation, we confirmed that the request under the yfy-api-oversea.xxxxxxxxxxxxxx.com domain name failed. iOS NSURLSession API returns the following error: Error Domain=NSURLErrorDomain Code=-1000 "無効なURL" UserInfo={_kCFStreamErrorCodeKey=22, NSUnderlyingError=0x3019e8030 {Error Domain=kCFErrorDomainCFNetwork Code=-1000 "(null)" UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], ipv4, ipv6, dns, proxy, uses wifi, _kCFStreamErrorCodeKey=22, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<7>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask .<7>" ), NSLocalizedDescription=無効なURL, NSErrorFailingURLStringKey=https://yfy-api-oversea.xxxxxxxxxxxxxx.com/init/info?channel_code=jpxxxxxxxxxxxxxxios&timestamp=1735012505&sign=1617e4cf88b58df2aa90a6b3985a8ac2&game_code=XXXXX, NSErrorFailingURLKey=https://yfy-api-oversea.xxxxxxxxxxxxxx.com/init/info?channel_code=jpxxxxxxxxxxxxxxios&timestamp=1735012505&sign=1617e4cf88b58df2aa90a6b3985a8ac2&game_code=XXXXX, _kCFStreamErrorDomainKey=1}。 We have tried various methods but cannot reproduce this error (Code=-1000). I can provide the following clues: 1、We have checked the server and confirmed that the request did not reach the server, but was intercepted by the iOS client and was not sent. 2、This problem does not seem to have much to do with the iOS system version. The system versions where the problem occurred are widely distributed: 17.2.1、17.7.1、17.5.1、17.6.1、17.7、18.0.1、18.1、18.1.1 e.g. 3、This problem seems to have nothing to do with the device model. The following models have experienced problems: iPhone16、iPhone 16 Pro、iPhone 14、iPhone 14 Plus、iPhone 14 Pro Max、iPhone 13、iPhone11 e.g. 4、By tracking the logs, some users who encountered the problem later recovered and the problem did not occur again(The user IP and iOS system restored by yourself have not changed). However, this problem persists for some users. Even if the iOS system is upgraded to the latest version, there are still problems. 5、The following two IPs are the IPs of users who encountered this problem (1.73.13.210, 153.252.131.136). But this problem seems to have nothing to do with IP. For some users who restored themselves, their IPs did not change, but the problem no longer occurred. 6、This problem seems to only occur in Japan. Mainland China, Taiwan, and Hong Kong have never encountered this situation. 7、It doesn't seem to have anything to do with GET requests. Another login request (https://yfy-api-oversea.xxxxxxxxxxxxxx.com/login/c/place) uses a POST request and will also encounter this error. 8、I wonder if it has something to do with the two symbol "-" in the domain name? I checked Apple documentation and searched online, but couldn't find any more information. This problem cannot be reproduced either. Only technical requests can be initiated. I provided a demo project (see email for Case-ID: 10969723) Thanks.
3
0
766
Jan ’25
NEAppPushProvider lifecycle guarantees for safety-critical local networking
We have an iOS companion app that talks to our IoT device over the device’s own Wi‑Fi network (often with no internet). The app performs bi-directional, safety-critical duties over that link. We use an NEAppPushProvider extension so the handset can keep exchanging data while the UI is backgrounded. During testing we noticed that if the user backgrounds the app (still connected to the device’s Wi‑Fi) and opens Safari, the extension’s stop is invoked with NEProviderStopReason.unrecoverableNetworkChange / noNetworkAvailable, and iOS tears the extension down. Until the system restarts the extension (e.g. the user foregrounds our app again), the app cannot send/receive its safety-critical data. Questions: Is there a supported way to stop a safety-critical NEAppPushProvider from being terminated in this “background app → open Safari” scenario when the device remains on the same Wi‑Fi network (possibly without internet)? If not, is NEAppPushProvider the correct extension type for an always-on local-network use case like this, or is there another API we should be using? For safety-critical applications, can Apple grant entitlements/exemptions so the system does not terminate the extension when the user switches apps but stays on the local Wi‑Fi? Any guidance on the expected lifecycle or alternative patterns for safety-critical local connectivity would be greatly appreciated.
1
0
20
1w
iOS Network Signal Strength
This issue has cropped up many times here on DevForums. Someone recently opened a DTS tech support incident about it, and I used that as an opportunity to post a definitive response here. If you have questions or comments about this, start a new thread and tag it with Network so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" iOS Network Signal Strength The iOS SDK has no general-purpose API that returns Wi-Fi or cellular signal strength in real time. Given that this has been the case for more than 10 years, it’s safe to assume that it’s not an accidental omission but a deliberate design choice. For information about the Wi-Fi APIs that are available on iOS, see TN3111 iOS Wi-Fi API overview. Network performance Most folks who ask about this are trying to use the signal strength to estimate network performance. This is a technique that I specifically recommend against. That’s because it produces both false positives and false negatives: The network signal might be weak and yet your app has excellent connectivity. For example, an iOS device on stage at WWDC might have terrible WWAN and Wi-Fi signal but that doesn’t matter because it’s connected to the Ethernet. The network signal might be strong and yet your app has very poor connectivity. For example, if you’re on a train, Wi-Fi signal might be strong in each carriage but the overall connection to the Internet is poor because it’s provided by a single over-stretched WWAN. The only good way to determine whether connectivity is good is to run a network request and see how it performs. If you’re issuing a lot of requests, use the performance of those requests to build a running estimate of how well the network is doing. Indeed, Apple practices what we preach here: This is exactly how HTTP Live Streaming works. Remember that network performance can change from moment to moment. The user’s train might enter or leave a tunnel, the user might step into a lift, and so on. If you build code to estimate the network performance, make sure it reacts to such changes. Keeping all of the above in mind, iOS 26 beta has two new APIs related to this issue: Network framework now offers a linkQuality property. See this post for my take on how to use this effectively. The WirelessInsights framework can notify you of anticipated WWAN condition changes. But what about this code I found on the ’net? Over the years various folks have used various unsupported techniques to get around this limitation. If you find code on the ’net that, say, uses KVC to read undocumented properties, or grovels through system logs, or walks the view hierarchy of the status bar, don’t use it. Such techniques are unsupported and, assuming they haven’t broken yet, are likely to break in the future. But what about Hotspot Helper? Hotspot Helper does have an API to read Wi-Fi signal strength, namely, the signalStrength property. However, this is not a general-purpose API. Like the rest of Hotspot Helper, this is tied to the specific use case for which it was designed. This value only updates in real time for networks that your hotspot helper is managing, as indicated by the isChosenHelper property. But what about MetricKit? MetricKit is so cool. Amongst other things, it supports the MXCellularConditionMetric payload, which holds a summary of the cellular conditions while your app was running. However, this is not a real-time signal strength value. But what if I’m working for a carrier? This post is about APIs in the iOS SDK. If you’re working for a carrier, discuss your requirements with your carrier’s contact at Apple. Revision History 2025-07-02 Updated to cover new features in the iOS 16 beta. Made other minor editorial changes. 2022-12-01 First posted.
0
0
4.3k
Jul ’25
Get Wi-Fi Aware demo app working
Hello, I have searched here on the forums for "WiFi Aware" and have read through just about every post. In a lot of them the person says they were able to get the example app https://developer.apple.com/documentation/wifiaware/building-peer-to-peer-apps working with their iOS devices. I, for some reason, am not able to get the example app to fully work. I am able to build the app and load the app onto two physical iPhone 12 minis (both are running iOS 26.0.1). I follow the steps shown at the link share above but I get stuck because I can't get past the "enter this pin code to connect" step. I make one device be a host of a simulation and the other device the viewer of a simulation. On each device I tap the "+" button. On the viewer device I tap the discovered device. On the host device I then see the pin. I then enter the pin on the viewer device. After this step nothing happens. My only choice on the viewer device is to tap "cancel" and exit the "enter the pin step". If I go into the actual device settings (Settings -> Privacy & Security -> Paired Devices) I see that the devices are "paired" but the app doesn't seem to think so. Are there some special settings I need to turn on for the app to work properly? In an attempt to figure out what was going wrong I took the example app and paired it down to just send back simple messages based on user button taps. These are my logs from when I start up the app and start one device as the hoster and one as the viewer. Selected Mode: Hoster Start NetworkListener [L1 ready, local endpoint: <NULL>, parameters: udp, traffic class: 700, interface: nan0, local: ::.0, definite, attribution: developer, server, port: 62182, path satisfied (Path is satisfied), interface: nan0[802.11], ipv4, uses wifi, LQM: unknown, service: com.example.apple-samplecode.Wi-FiAwareSample8B4DX93M9J._sat-simulation._udp scope:0 route:0 custom:107]: waiting(POSIXErrorCode(rawValue: 50): Network is down) [L1 ready, local endpoint: <NULL>, parameters: udp, traffic class: 700, interface: nan0, local: ::.0, definite, attribution: developer, server, port: 62182, path satisfied (Path is satisfied), interface: nan0[802.11], ipv4, uses wifi, LQM: unknown, service: com.example.apple-samplecode.Wi-FiAwareSample8B4DX93M9J._sat-simulation._udp scope:0 route:0 custom:107]: ready [L1 failed, local endpoint: <NULL>, parameters: udp, traffic class: 700, interface: nan0, local: ::.0, definite, attribution: developer, server, port: 62182, path satisfied (Path is satisfied), interface: nan0[802.11], ipv4, uses wifi, LQM: unknown, service: com.example.apple-samplecode.Wi-FiAwareSample8B4DX93M9J._sat-simulation._udp scope:0 route:0 custom:107]: failed(-11992: Wi-Fi Aware) nw_listener_cancel_block_invoke [L1] Listener is already cancelled, ignoring cancel nw_listener_cancel_block_invoke [L1] Listener is already cancelled, ignoring cancel nw_listener_cancel_block_invoke [L1] Listener is already cancelled, ignoring cancel Networking failed: -11992: Wi-Fi Aware Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Could not find attribute name in domain plist" UserInfo={NSLocalizedFailureReason=Could not find attribute name in domain plist}> <0x105e35400> Gesture: System gesture gate timed out. Selected Mode: Viewer Start NetworkBrowser [B1 <nw_browse_descriptor application_service _sat-simulation._udp bundle_id=com.example.apple-samplecode.Wi-FiAwareSample8B4DX93M9J device_types=7f device_scope=ff custom:109>, generic, interface: nan0, attribution: developer]: ready nw_browser_update_path_browser_locked Received browser Wi-Fi Aware nw_browser_cancel [B1] The browser has already been cancelled, ignoring nw_browser_cancel(). [B1 <nw_browse_descriptor application_service _sat-simulation._udp bundle_id=com.example.apple-samplecode.Wi-FiAwareSample8B4DX93M9J device_types=7f device_scope=ff custom:109>, generic, interface: nan0, attribution: developer]: failed(-11992: Wi-Fi Aware) nw_browser_cancel [B1] The browser has already been cancelled, ignoring nw_browser_cancel(). Networking failed: -11992: Wi-Fi Aware Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Could not find attribute name in domain plist" UserInfo={NSLocalizedFailureReason=Could not find attribute name in domain plist}> This guy stands out to me Networking failed: -11992: Wi-Fi Aware but I can't find any info on what it means. Thank you
1
0
60
1w
Local Network privacy blocking my app when it shouldn't
I have read the other most relevant posts on this topic here and here. However, the situations described in these posts are different. My app is just a regular Mach-O bundle with a single executable that is launched by the user from the Finder. I've read the Local Network Privacy FAQ and TN3179 carefully and these also doesn't cover the problem described below, which is being reported to me by several of my users. The problem is that some days after giving Local Network permission to my app, without having changed anything, local network connections will spontaneously start failing with EHOSTUNREACH, indicating that it is being blocked by macOS. This typically happens after a Mac reboot. Toggling off/on the Local Network permission for my app will get it working again, until the next time it fails. My users who are reporting this have stated that they are running macOS Sonoma 15.2, with only a single version/copy of my app installed. I've tried, and failed, to reproduce this in a VM with a clean 15.2 system, but maybe this is due to the relatively short duration of my testing (days rather than weeks). I know there isn't much to go on here, and it may be tempting to put this down to misreporting. After all, the vast majority of my users aren't reporting this, and I can't reproduce it. But, I have received enough similar reports at this point that it's starting to feel like a macOS bug. Is anyone else seeing this? If there is anything that anyone can suggest - either modifications in my app, or anything that my users can do on their side - this would be very much appreciated! Many thanks, Ben
1
0
424
Jan ’25
DeviceDiscoveryUI's UIViewControllers are available for Wi-Fi Aware?
HI, I am currently developing an app that utilizes Wi-Fi Aware. According to the Wi-Fi Aware framework examples and the WWDC25 session on Wi-Fi Aware, discovery is handled using DevicePairingView and DevicePicker from the DeviceDiscoveryUI module. However, these SwiftUI views present their connection UI modally when tapped. My app's design requires the ability to control the presentation of this UI programmatically, rather than relying on a user tap. While inspecting the DeviceDiscoveryUI module, I found DDDevicePairingViewController and DDDevicePickerViewController, which appear to be the UIViewController counterparts to the SwiftUI views. The initializer for DDDevicePairingViewController accepts a ListenerProvider, so it seems I can pass the same ListenerProvider instance that is used with the DevicePairingView. However, the initializer for DDDevicePickerViewController requires an NWBrowser.Descriptor, which seems incompatible with the parameters used for the SwiftUI DevicePicker. I have two main questions: (1) Can DDDevicePairingViewController and DDDevicePickerViewController be officially used for Wi-Fi Aware pairing? (2) Are there any plans to provide more customization or programmatic control over the DevicePairingView and DevicePicker (for example, allowing us to trigger their modal presentation programmatically)? Thank you.
0
0
28
2w
iOS26 captive portal detection changes?
Hi all, I work on a smart product that, for setup, uses a captive portal to allow users to connect and configure the device. It emits a WiFi network and runs a captive portal - an HTTP server operates at 10.0.0.1, and a DNS server responds to all requests with 10.0.0.1 to direct "any and all" request to the server. When iOS devices connect, they send a request to captive.apple.com/hotspot-detect.html; if it returns success, that means they're on the internet; if not, the typical behavior in the past has been to assume you're connected to a captive portal and display what's being served. I serve any requests to /hotspot-detect.html with my captive portal page (index.html). This has worked reliably on iOS18 for a long time (user selects my products WiFi network, iOS detects portal and opens it). But almost everyone who's now trying with iOS26 is having the "automatic pop up" behavior fail - usually it says "Error opening page - Hotspot login cannot open the page because the network connection was lost." However, if opening safari and navigating to any URL (or 10.0.0.1) the portal loads - it's just the iOS auto-detect and open that's not working iOS18 always succeeds; iOS26 always fails. Anybody have any idea what changes may have been introduced in iOS26 on this front, or anything I can do to help prompt or coax iOS26 into loading the portal? It typically starts reading, but then stops mid-read.
0
0
137
4w
Symbol not found: ___res_9_state
When running my app with Xcode16.4, it crashed with the error: dyld[1045]: Symbol not found: ___res_9_state Referenced from: <8B329554-5BEF-38D0-BFCD-1731FA6120CB> /private/var/containers/Bundle/Application/00C941BA-E397-4D0B-B280-E75583FF2890/xxx.app/xxx.debug.dylib Expected in: <7D74C679-8F55-3A01-9AA2-C205A4A19D3E> /usr/lib/libresolv.9.dylib The ___res_9_state related code in my app is: let state = __res_9_state() res_9_ninit(state) var servers = [res_9_sockaddr_union](repeating: res_9_sockaddr_union(), count: Int(MAXNS)) let found = Int(res_9_getservers(state, &servers, Int32(MAXNS))) res_9_nclose(state) if found > 0 { return Array(servers[0..<found]).filter() { $0.sin.sin_len > 0 } } else { return [] } Previously, __res_9_state() could run normally in Xcode 16.1 How to fix this problem?
2
0
162
Jul ’25
Intermittent SSL issue
Hi Team, We are getting below error when we try to connect our REST APIs from our device. Our application is enterprise application and its connecting all backend calls via MobileIron Secure Tunnel(VPN). We are not encountering this error when we try to connect backend system from Simulator on VPN connected machine. We are calling 13 APIs but we are getting below error intermittently for different APIs i.e each time we are facing this issue for different APIs. We connected with our Helpdesk team to troubleshoot the error and they checked the MobileIron VPN firewall and there is no log We configured below things Allow Arbitrary Loads - True <key>NSExceptionMinimumTLSVersion</key> <string>TLSv1.2</string> We are using Alamofire library to connect backend. We disabled all site validation and we configured minTLSVersion 1.2. Please find below code snippet static let serverTrustPolicies:[String: ServerTrustEvaluating] = { var sites = [String]() sites.append("apis.xyz.com") return sites.reduce([String: ServerTrustEvaluating]()) { (dictionary, site) -> [String: Alamofire.ServerTrustEvaluating] in var dictionary = dictionary dictionary[site] = DisabledTrustEvaluator() return dictionary } }() static let manager: Session = { var serverTrustPolicies: [String: ServerTrustEvaluating] = NetworkClient.serverTrustPolicies let configuration = URLSessionConfiguration.default configuration.tlsMinimumSupportedProtocolVersion = .TLSv12 return Alamofire.Session(configuration: configuration, serverTrustManager: CustomTrustManager(evaluators: serverTrustPolicies)) }() error from Alamofire
1
0
168
Jan ’25
iOS Secure WebSocket Connection Timing Out & Map Sync Issues with Custom SSL Server
Hello, all, I'm new to iOS development and working on a project with the following setup: Architecture: Windows PC running Ubuntu (WSL) hosting a WebSocket Server with self-signed SSL Python GUI application as a client to control iOS app iOS app as another client on physical iPhone Server running on wss://xxx.xxx.xxx.1:8001 (this is the mobile hotspot IP from Windows PC which the iPhone is needed to connect to as well) Current Status: ✓ Server successfully created and running ✓ Python GUI connects and functions properly ✓ iOS app initially connects and communicates for 30 seconds ✗ iOS connection times out after 30 seconds ✗ Map updates from GUI don't sync to iOS app Error Message in Xcode terminal: WebSocket: Received text message 2024-11-25 15:49:03.678384-0800 iVEERS[1465:454666] Task <CD21B8AD-86D9-4984-8C48-8665CD069CC6>.<1> finished with error [-1001] Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_kCFStreamErrorCodeKey=-2103, _NSURLErrorFailingURLSessionTaskErrorKey=LocalWebSocketTask <CD21B8AD-86D9-4984-8C48-8665CD069CC6>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalWebSocketTask <CD21B8AD-86D9-4984-8C48-8665CD069CC6>.<1>" ), NSLocalizedDescription=The request timed out., NSErrorFailingURLStringKey=wss://xxx.xxx.xxx.1:8001/, NSErrorFailingURLKey=wss://xxx.xxx.xxx.1:8001/, _kCFStreamErrorDomainKey=4} Technical Details: Using iOS built-in URLSessionWebSocketTask for WebSocket connection Self-signed SSL certificate Transport security settings configured in Info.plist Map updates use base64 encoded PNG data Questions: What's causing the timeout after 30 seconds? How can I maintain a persistent WebSocket connection? Why aren't map updates propagating to the iOS client? Any guidance/suggestions would be greatly appreciated. Please let me know if additional code snippets would help on what I currently have.
0
0
455
Nov ’24
Crash on "Dispatch queue: NEFlow queue" when __88-[NEExtensionAppProxyProviderContext setInitialFlowDivertControlSocket:extraValidation:]_block_invoke.90
I observed the following crash: Code Type: ARM-64 (Native) Parent Process: launchd [1] User ID: 0 Date/Time: 2025-10-07 13:48:29.082 OS Version: macOS 15.6 (24G84) Report Version: 12 Anonymous UUID: 8B651788-4B2E-7869-516B-1DA0D60F3744 Crashed Thread: 3 Dispatch queue: NEFlow queue Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000054 ... Thread 3 Crashed: Dispatch queue: NEFlow queue 0 libdispatch.dylib 0x000000019af6da34 dispatch_async + 192 1 libnetworkextension.dylib 0x00000001b0cf8580 __flow_startup_block_invoke.216 + 124 2 com.apple.NetworkExtension 0x00000001adf97da8 __88-[NEExtensionAppProxyProviderContext setInitialFlowDivertControlSocket:extraValidation:]_block_invoke.90 + 860 3 libnetworkextension.dylib 0x00000001b0cf8140 __flow_startup_block_invoke.214 + 172 4 libdispatch.dylib 0x000000019af67b2c _dispatch_call_block_and_release + 32 5 libdispatch.dylib 0x000000019af8185c _dispatch_client_callout + 16 6 libdispatch.dylib 0x000000019af70350 _dispatch_lane_serial_drain + 740 7 libdispatch.dylib 0x000000019af70e2c _dispatch_lane_invoke + 388 8 libdispatch.dylib 0x000000019af7b264 _dispatch_root_queue_drain_deferred_wlh + 292 9 libdispatch.dylib 0x000000019af7aae8 _dispatch_workloop_worker_thread + 540 10 libsystem_pthread.dylib 0x000000019b11be64 _pthread_wqthread + 292 11 libsystem_pthread.dylib 0x000000019b11ab74 start_wqthread + 8 ... It appears that the crash is caused by the flow director queue becoming NULL when dispatch_async is called (accessing address 0x0000000000000054). Meanwhile, my transparent proxy was still running. I'm wondering if this is a known issue or if anyone else has encountered the same problem. @eskimo
2
0
363
Oct ’25
Network Extension Provider Packaging
This is a topic that’s come up a few times on the forums, so I thought I’d write up a summary of the issues I’m aware of. If you have questions or comments, start a new thread in the App & System Services > Networking subtopic and tag it with Network Extension. That way I’ll be sure to see it go by. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Network Extension Provider Packaging There are two ways to package a network extension provider: App extension ( appex ) System extension ( sysex ) Different provider types support different packaging on different platforms. See TN3134 Network Extension provider deployment for the details. Some providers, most notably packet tunnel providers on macOS, support both appex and sysex packaging. Sysex packaging has a number of advantages: It supports direct distribution, using Developer ID signing. It better matches the networking stack on macOS. An appex is tied to the logged in user, whereas a sysex, and the networking stack itself, is global to the system as a whole. Given that, it generally makes sense to package your Network Extension (NE) provider as a sysex on macOS. If you’re creating a new product that’s fine, but if you have an existing iOS product that you want to bring to macOS, you have to account for the differences brought on by the move to sysex packaging. Similarly, if you have an existing sysex product on macOS that you want to bring to iOS, you have to account for the appex packaging. This post summarises those changes. Keep the following in mind while reading this post: The information here applies to all NE providers that can be packaged as either an appex or a sysex. When this post uses a specific provider type in an example, it’s just an example. Unless otherwise noted, any information about iOS also applies to iPadOS, tvOS, and visionOS. Process Lifecycle With appex packaging, the system typically starts a new process for each instance of your NE provider. For example, with a packet tunnel provider: When the users starts the VPN, the system creates a process and then instantiates and starts the NE provider in that process. When the user stops the VPN, the system stops the NE provider and then terminates the process running it. If the user starts the VPN again, the system creates an entirely new process and instantiates and starts the NE provider in that. In contrast, with sysex packaging there’s typically a single process that runs all off the sysex’s NE providers. Returning to the packet tunnel provider example: When the users starts the VPN, the system instantiates and starts the NE provider in the sysex process. When the user stops the VPN, the system stops and deallocates the NE provider instances, but leaves the sysex process running. If the user starts the VPN again, the system instantiates and starts a new instances of the NE provider in the sysex process. This lifecycle reflects how the system runs the NE provider, which in turn has important consequences on what the NE provider can do: An appex acts like a launchd agent [1], in that it runs in a user context and has access to that user’s state. A sysex is effectively a launchd daemon. It runs in a context that’s global to the system as a whole. It does not have access to any single user’s state. Indeed, there might be no user logged in, or multiple users logged in. The following sections explore some consequences of the NE provider lifecycle. [1] It’s not actually run as a launchd agent. Rather, there’s a system launchd agent that acts as the host for the app extension. App Groups With an app extension, the app extension and its container app run as the same user. Thus it’s trivial to share state between them using an app group container. Note When talking about extensions on Apple platforms, the container app is the app in which the extension is embedded and the host app is the app using the extension. For network extensions the host app is the system itself. That’s not the case with a system extension. The system extension runs as root whereas the container app runs an the user who launched it. While both programs can claim access to the same app group, the app group container location they receive will be different. For the system extension that location will be inside the home directory for the root user. For the container app the location will be inside the home directory of the user who launched it. This does not mean that app groups are useless in a Network Extension app. App groups are also a factor in communicating between the container app and its extensions, the subject of the next section. IMPORTANT App groups have a long and complex history on macOS. For the full story, see App Groups: macOS vs iOS: Working Towards Harmony. Communicating with Extensions With an app extension there are two communication options: App-provider messages App groups App-provider messages are supported by NE directly. In the container app, send a message to the provider by calling sendProviderMessage(_:responseHandler:) method. In the appex, receive that message by overriding the handleAppMessage(_:completionHandler:) method. An appex can also implement inter-process communication (IPC) using various system IPC primitives. Both the container app and the appex claim access to the app group via the com.apple.security.application-groups entitlement. They can then set up IPC using various APIs, as explain in the documentation for that entitlement. With a system extension the story is very different. App-provider messages are supported, but they are rarely used. Rather, most products use XPC for their communication. In the sysex, publish a named XPC endpoint by setting the NEMachServiceName property in its Info.plist. Listen for XPC connections on that endpoint using the XPC API of your choice. Note For more information about the available XPC APIs, see XPC Resources. In the container app, connect to that named XPC endpoint using the XPC Mach service name API. For example, with NSXPCConnection, initialise the connection with init(machServiceName:options:), passing in the string from NEMachServiceName. To maximise security, set the .privileged flag. Note XPC Resources has a link to a post that explains why this flag is important. If the container app is sandboxed — necessary if you ship on the Mac App Store — then the endpoint name must be prefixed by an app group ID that’s accessible to that app, lest the App Sandbox deny the connection. See the app groups documentation for the specifics. When implementing an XPC listener in your sysex, keep in mind that: Your sysex’s named XPC endpoint is registered in the global namespace. Any process on the system can open a connection to it [1]. Your XPC listener must be prepared for this. If you want to restrict connections to just your container app, see XPC Resources for a link to a post that explains how to do that. Even if you restrict access in that way, it’s still possible for multiple instances of your container app to be running simultaneously, each with its own connection to your sysex. This happens, for example, if there are multiple GUI users logged in and different users run your container app. Design your XPC protocol with this in mind. Your sysex only gets one named XPC endpoint, and thus one XPC listener. If your sysex includes multiple NE providers, take that into account when you design your XPC protocol. [1] Assuming that connection isn’t blocked by some other mechanism, like the App Sandbox. Inter-provider Communication A sysex can include multiple types of NE providers. For example, a single sysex might include a content filter and a DNS proxy provider. In that case the system instantiates all of the NE providers in the same sysex process. These instances can communicate without using IPC, for example, by storing shared state in global variables (with suitable locking, of course). It’s also possible for a single container app to contain multiple sysexen, each including a single NE provider. In that case the system instantiates the NE providers in separate processes, one for each sysex. If these providers need to communicate, they have to use IPC. In the appex case, the system instantiates each provider in its own process. If two providers need to communicate, they have to use IPC. Managing Secrets An appex runs in a user context and thus can store secrets, like VPN credentials, in the keychain. On macOS this includes both the data protection keychain and the file-based keychain. It can also use a keychain access group to share secrets with its container app. See Sharing access to keychain items among a collection of apps. Note If you’re not familiar with the different types of keychain available on macOS, see TN3137 On Mac keychain APIs and implementations. A sysex runs in the global context and thus doesn’t have access to user state. It also doesn’t have access to the data protection keychain. It must use the file-based keychain, and specifically the System keychain. That means there’s no good way to share secrets with the container app. Instead, do all your keychain operations in the sysex. If the container app needs to work with a secret, have it pass that request to the sysex via IPC. For example, if the user wants to use a digital identity as a VPN credential, have the container app get the PKCS#12 data and password and then pass that to the sysex so that it can import the digital identity into the keychain. Memory Limits iOS imposes strict memory limits an NE provider appexen [1]. macOS imposes no memory limits on NE provider appexen or sysexen. [1] While these limits are not documented officially, you can get a rough handle on the current limits by reading the posts in this thread. Frameworks If you want to share code between a Mac app and its embedded appex, use a structure like this: MyApp.app/ Contents/ MacOS/ MyApp PlugIns/ MyExtension.appex/ Contents/ MacOS/ MyExtension … Frameworks/ MyFramework.framework/ … There’s one copy of the framework, in the app’s Frameworks directory, and both the app and the appex reference it. This approach works for an appex because the system always loads the appex from your app’s bundle. It does not work for a sysex. When you activate a sysex, the system copies it to a protected location. If that sysex references a framework in its container app, it will fail to start because that framework isn’t copied along with the sysex. The solution is to structure your app like this: MyApp.app/ Contents/ MacOS/ MyApp Library/ SystemExtensions/ MyExtension.systemextension/ Contents/ MacOS/ MyExtension Frameworks/ MyFramework.framework/ … … That is, have both the app and the sysex load the framework from the sysex’s Frameworks directory. When the system copies the sysex to its protected location, it’ll also copy the framework, allowing the sysex to load it. To make this work you have to change the default rpath configuration set up by Xcode. Read Dynamic Library Standard Setup for Apps to learn how that works and then tweak things so that: The framework is embedded in the sysex, not the container app. The container app has an additional LC_RPATH load command for the sysex’s Frameworks directory (@executable_path/../Library/SystemExtensions/MyExtension.systemextension/Contents/Frameworks). The sysex’s LC_RPATH load command doesn’t reference the container app’s Frameworks directory (@executable_path/../../../../Frameworks) but instead points to the sysex’s Framweorks directory (@executable_path/../Frameworks). Entitlements When you build an app with an embedded NE extension, both the app and the extension must be signed with the com.apple.developer.networking.networkextension entitlement. This is a restricted entitlement, that is, it must be authorised by a provisioning profile. The value of this entitlement is an array, and the values in that array differ depend on your distribution channel: If you distribute your app directly with Developer ID signing, use the values with the -systemextension suffix. Otherwise — including when you distribute the app on the App Store and when signing for development — use the values without that suffix. Make sure you authorise these values with your provisioning profile. If, for example, you use an App Store distribution profile with a Developer ID signed app, things won’t work because the profile doesn’t authorise the right values. In general, the easiest option is to use Xcode’s automatic code signing. However, watch out for the pitfall described in Exporting a Developer ID Network Extension. Revision History 2025-11-06 Added the Entitlements section. Explained that, with sysex packaging, multiple instances of your container app might connect simultaneously with your sysex. 2025-09-17 First posted.
0
0
83
2w
NEAppPushProvider not works properly on iOS26
In my app I have Local Push connectivity for local push notifications. My app has proper entitlment granted by Apple and NEAppPushProvider was working perfectly on older iOS versions before iOS26. The problem I faced with iOS26: when i enable VPN - NEAppPushProvider stops with reason /** @const NEProviderStopReasonNoNetworkAvailable There is no network connectivity. */ case noNetworkAvailable = 3. But device is still connected to proper SSID that is included to matchSSIDs. I discovered it only happens if my VPN config file include this line redirect-gateway def1 without that line NEAppPushProvider works as expected with enabled VPN. I use OpenVPN app. Is it a bug of iOS26 or I need some additional setup? Please help!
2
0
64
Sep ’25
“Wi-Fi Aware Sample” on Phone quit unexpectedly.
The app “Wi-Fi Aware Sample” on Bojie的iPhone quit unexpectedly. Domain: IDEDebugSessionErrorDomain Code: 20 Failure Reason: Message from debugger: The LLDB RPC server has crashed. You may need to manually terminate your process. The crash log is located in ~/Library/Logs/DiagnosticReports and has a prefix 'lldb-rpc-server'. Please file a bug and attach the most recent crash log. User Info: { DVTErrorCreationDateKey = "2025-09-17 10:26:56 +0000"; IDEDebugSessionErrorUserInfoUnavailabilityError = "Error Domain=com.apple.dt.deviceprep Code=-10 "Fetching debug symbols for Bojie\U7684iPhone" UserInfo={NSLocalizedRecoverySuggestion=Xcode will continue when the operation completes., NSLocalizedDescription=Fetching debug symbols for Bojie\U7684iPhone}"; IDERunOperationFailingWorker = DBGLLDBLauncher; } Event Metadata: com.apple.dt.IDERunOperationWorkerFinished : { "device_identifier" = "00008101-001E29E01E63003A"; "device_isCoreDevice" = 1; "device_model" = "iPhone13,3"; "device_osBuild" = "26.0 (23A341)"; "device_osBuild_monotonic" = 2300034100; "device_os_variant" = 1; "device_platform" = "com.apple.platform.iphoneos"; "device_platform_family" = 2; "device_reality" = 1; "device_thinningType" = "iPhone13,3"; "device_transport" = 1; "dvt_coredevice_version" = "477.23"; "dvt_coredevice_version_monotonic" = 477023000000000; "dvt_coresimulator_version" = 1043; "dvt_coresimulator_version_monotonic" = 1043000000000000; "dvt_mobiledevice_version" = "1818.0.1"; "dvt_mobiledevice_version_monotonic" = 1818000001000000; "launchSession_schemeCommand" = Run; "launchSession_schemeCommand_enum" = 1; "launchSession_targetArch" = arm64; "launchSession_targetArch_enum" = 6; "operation_duration_ms" = 1922640; "operation_errorCode" = 20; "operation_errorDomain" = IDEDebugSessionErrorDomain; "operation_errorWorker" = DBGLLDBLauncher; "operation_error_reportable" = 1; "operation_name" = IDERunOperationWorkerGroup; "operation_unavailabilityErrorCode" = "-10"; "operation_unavailabilityErrorDomain" = "com.apple.dt.deviceprep"; "param_consoleMode" = 1; "param_debugger_attachToExtensions" = 0; "param_debugger_attachToXPC" = 1; "param_debugger_type" = 3; "param_destination_isProxy" = 0; "param_destination_platform" = "com.apple.platform.iphoneos"; "param_diag_MainThreadChecker_stopOnIssue" = 0; "param_diag_MallocStackLogging_enableDuringAttach" = 0; "param_diag_MallocStackLogging_enableForXPC" = 1; "param_diag_allowLocationSimulation" = 1; "param_diag_checker_mtc_enable" = 1; "param_diag_checker_tpc_enable" = 1; "param_diag_gpu_frameCapture_enable" = 0; "param_diag_gpu_shaderValidation_enable" = 0; "param_diag_gpu_validation_enable" = 0; "param_diag_guardMalloc_enable" = 0; "param_diag_memoryGraphOnResourceException" = 0; "param_diag_queueDebugging_enable" = 1; "param_diag_runtimeProfile_generate" = 0; "param_diag_sanitizer_asan_enable" = 0; "param_diag_sanitizer_tsan_enable" = 0; "param_diag_sanitizer_tsan_stopOnIssue" = 0; "param_diag_sanitizer_ubsan_enable" = 0; "param_diag_sanitizer_ubsan_stopOnIssue" = 0; "param_diag_showNonLocalizedStrings" = 0; "param_diag_viewDebugging_enabled" = 1; "param_diag_viewDebugging_insertDylibOnLaunch" = 1; "param_install_style" = 2; "param_launcher_UID" = 2; "param_launcher_allowDeviceSensorReplayData" = 0; "param_launcher_kind" = 0; "param_launcher_style" = 99; "param_launcher_substyle" = 0; "param_lldbVersion_component_idx_1" = 0; "param_lldbVersion_monotonic" = 170300230950; "param_runnable_appExtensionHostRunMode" = 0; "param_runnable_productType" = "com.apple.product-type.application"; "param_testing_launchedForTesting" = 0; "param_testing_suppressSimulatorApp" = 0; "param_testing_usingCLI" = 0; "sdk_canonicalName" = "iphoneos26.0"; "sdk_osVersion" = "26.0"; "sdk_platformID" = 2; "sdk_variant" = iphoneos; "sdk_version_monotonic" = 2300527605; } System Information macOS Version 15.5 (Build 24F74) Xcode 26.0 (24141.31) (Build 17A5241o) Timestamp: 2025-09-17T18:26:56+08:00
3
0
169
Sep ’25
VPN Stuck at connecting
Hello, I’ve run into some strange behavior with the macOS System Extension using a Packet Tunnel. The issue showed up after the device went to sleep while the VPN was running. When I woke the computer, the VPN tried to reconnect but never succeeded — it just stayed stuck in the “connecting” state. I was able to turn the VPN off, but every attempt to turn it back on failed and got stuck at “connecting” again. Even removing the VPN configuration from Settings didn’t help. The only thing that worked was disabling the system extension completely. While checking the logs, I noticed thousands of identical log messages appearing within just a few seconds: nesessionmanager(562) deny(1) system-fsctl (_IO "h" 47) 17:11:52.481498+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5454 com.apple.networkextension 17:11:52.481568+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5454 com.apple.networkextension 17:11:52.481580+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5454 com.apple.networkextension 17:11:52.481587+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5454 com.apple.networkextension 17:11:52.481646+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5446 com.apple.networkextension 17:11:52.481664+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5446 com.apple.networkextension 17:11:52.481671+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5446 com.apple.networkextension 17:11:52.481676+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5446 com.apple.networkextension 17:11:52.481682+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5446 com.apple.networkextension 17:11:52.481687+0200 NESMVPNSession[Primary Tunnel:Secure DNS: got On Demand start message from pid 5446 com.apple.networkextension After the burst of these repeated messages, I started seeing logs like the following: 17:11:52.481759+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from Spotify Helper[69038] com.apple.networkextension 17:11:52.481790+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from Spotify Helper[69038]: session in state connecting com.apple.networkextension 17:11:52.481949+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from Spotify Helper[69038] com.apple.networkextension 17:11:52.481966+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from Spotify Helper[69038]: session in state connecting com.apple.networkextension 17:11:52.481986+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from Spotify Helper[69038] com.apple.networkextension 17:11:52.481992+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from Spotify Helper[69038]: session in state connecting com.apple.networkextension 17:11:52.482003+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from Spotify Helper[69038] com.apple.networkextension 17:11:52.482011+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from Spotify Helper[69038]: session in state connecting com.apple.networkextension 17:11:52.482022+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from Spotify Helper[69038] com.apple.networkextension 17:11:52.482028+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from Spotify Helper[69038]: session in state connecting com.apple.networkextension 17:11:52.482039+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from Spotify Helper[69038] com.apple.networkextension 17:11:52.482049+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from Spotify Helper[69038]: session in state connecting com.apple.networkextension 17:11:52.482060+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from Slack Helper[84828] com.apple.networkextension 17:11:52.482069+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from Slack Helper[84828]: session in state connecting com.apple.networkextension 17:11:52.482079+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Received a start command from sharingd[764] com.apple.networkextension 17:11:52.482086+0200 NESMVPNSession[Primary Tunnel:Secure DNS: Skip a start command from sharingd[764]: session in state connecting com.apple.networkextension It is clear that the connection is in a loop of submitting request to start and then failing. This problem occured only after sleep on macOS 26.0 and 15.6. This issue only occured after the system woke up from sleep. macOS 15.6 and 26.0. Is this a known problem, and how should I go about troubleshooting or resolving it?
3
0
103
4w