Post

Replies

Boosts

Views

Activity

iOS 26 Network Framework AWDL not working
Hello, I have an app that is using iOS 26 Network Framework APIs. It is using QUIC, TLS 1.3 and Bonjour. For TLS I am using a PKCS#12 identity. All works well and as expected if the devices (iPhone with no cellular, iPhone with cellular, and iPad no cellular) are all on the same wifi network. If I turn off my router (ie no more wifi network) and leave on the wifi toggle on the iOS devices - only the non cellular iPhone and iPad are able to discovery and connect to each other. My iPhone with cellular is not able to. By sharing my logs with Cursor AI it was determined that the connection between the two problematic peers (iPad with no cellular and iPhone with cellular) never even makes it to the TLS step because I never see the logs where I print out the certs I compare. I tried doing "builder.requiredInterfaceType(.wifi)" but doing that blocked the two non cellular devices from working. I also tried "builder.prohibitedInterfaceTypes([.cellular])" but that also did not work. Is AWDL on it's way out? Should I focus my energy on Wi-Fi Aware? Regards, Captadoh
17
0
459
1d
Video Audio + Speech To Text
Hello, I am wondering if it is possible to have audio from my AirPods be sent to my speech to text service and at the same time have the built in mic audio input be sent to recording a video? I ask because I want my users to be able to say "CAPTURE" and I start recording a video (with audio from the built in mic) and then when the user says "STOP" I stop the recording.
1
0
281
3d
How to close / cancel a NetworkConnection
Hello, I have an app that was using the iOS 18 Network Framework APIs. It used Peer to Peer, QUIC and Bonjour. It was all working as expected. I wanted to upgrade to the new iOS 26 Network Framework APIs (NetworkBrowser, NetworkListener, NetworkConnection...). I have things working (multiple devices can discover each other, connection to each other and send messages to each other) but my app crashes when I go to toggle of all the networking stuff. In the iOS 18 Network Framework API NWConnection had a .cancel() function I could use to tell the other side the connection was done. I dont see a cancel function for NetworkConnection. My question is - how do I properly close down a NetworkConnection and also properly tell the other side the connection is done.
2
0
87
3d
How to start a NetworkConnection
Hello, I am studying the Building peer-to-peer apps codebase https://developer.apple.com/documentation/wifiaware/building-peer-to-peer-apps and am wondering why no connection is ever started? I searched the codebase and didn't find .start() be called once. Start function I'm referencing https://developer.apple.com/documentation/network/networkconnection/start() Are NetworkConnections started automatically? Note that I am using QUIC NetworkConnections (NetworkConnection) in what I'm trying to do.
1
0
64
1w
iOS 26 Network Framework APIs with QUIC
Hello, I have a peer to peer networking setup in my app that uses Network Framework with Bonjour and QUIC via NWBrowser, NWListener, NWConnection, and NWEndpoint and all works as expected. I watched the videos about the new iOS 26 Networking stuff (NetworkBrowser, NetworkListener, NetworkConnection) and wanted to try and migrate all my code to use the the new APIs (still use Bonjour and NOT use Wi-Fi Aware) but hit some issues. I was following how the Wi-Fi Aware example app was receiving messages for try await messageData in connection.messages { but when I got things setup with QUIC in a similar fashion I got the following compile error Requirement from conditional conformance of '(content: QUIC.ContentType, metadata: QUIC.Metadata)' to 'Copyable' Requirement from conditional conformance of '(content: QUIC.ContentType, metadata: QUIC.Metadata)' to 'Escapable' Requirement from conditional conformance of '(content: QUIC.ContentType, metadata: QUIC.Metadata)' to 'Copyable' Requirement from conditional conformance of '(content: QUIC.ContentType, metadata: QUIC.Metadata)' to 'Escapable' When I asked Cursor about what I was facing its response was as follows: "The connection.messages stream changed in the new Network APIs: it now yields typed (content, metadata) tuples. Iterating with for try await incoming in connection.messages asks the compiler to conform that tuple to Copyable/Escapable; for QUIC the tuple isn’t copyable, so you hit the conditional-conformance error." I am curious if you've been able to use the new iOS 26 network APIs with QUIC? Thank you, Captadoh
1
0
101
Nov ’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
88
Nov ’25
NWBrowser + NWListener + NWConnection
I am seeking assistance with how to properly handle / save / reuse NWConnections when it comes to the NWBrowser vs NWListener. Let me give some context surrounding why I am trying to do what I am. I am building an iOS app that has peer to peer functionality. The design is for a user (for our example the user is Bob) to have N number of devices that have my app installed on it. All these devices are near each other or on the same wifi network. As such I want all the devices to be able to discover each other and automatically connect to each other. For example if Bob had three devices (A, B, C) then A discovers B and C and has a connection to each, B discovers B and C and has a connection to each and finally C discovers A and B and has a connection to each. In the app there is a concept of a leader and a follower. A leader device issues commands to the follower devices. A follower device just waits for commands. For our example device A is the leader and devices B and C are followers. Any follower device can opt to become a leader. So if Bob taps the “become leader” button on device B - device B sends out a message to all the devices it’s connected to telling them it is becoming the new leader. Device B doesn’t need to do anything but device A needs to set itself as a follower. This detail is to show my need to have everyone connected to everyone. Please note that I am using .includePeerToPeer = true in my NWParameters. I am using http/3 and QUIC. I am using P12 identity for TLS1.3. I am successfully able to verify certs in sec_protocal_options_set_verify_block. I am able to establish connections - both from the NWBrowser and from NWListener. My issue is that it’s flaky. I found that I have to put a 3 second delay prior to establishing a connection to a peer found by the NWBrowser. I also opted to not save the incoming connection from NWListener. I only save the connection I created from the peer I found in NWBrowser. For this example there is Device X and Device Y. Device X discovers device Y and connects to it and saves the connection. Device Y discovers device X and connects to it and saves the connection. When things work they work great - I am able to send messages back and forth. Device X uses the saved connection to send a message to device Y and device Y uses the saved connection to send a message to device X. Now here come the questions. Do I save the connection I create from the peer I discovered from the NWBrowser? Do I save the connection I get from my NWListener via newConnectionHandler? And when I save a connection (be it from NWBrowser or NWListener) am I able to reuse it to send data over (ie “i am the new leader command”)? When my NWBrowser discovers a peer, should I be able to build a connection and connect to it immediately? I know if I save the connection I create from the peer I discover I am able to send messages with it. I know if I save the connection from NWListener - I am NOT able to send messages with it — but should I be able to? I have a deterministic algorithm for who makes a connection to who. Each device has an ID - it is a UUID I generate when the app loads - I store it in UserDefaults and the next time I try and fetch it so I’m not generating new UUIDs all the time. I set this deviceID as the name of the NWListener.Service I create. As a result the peer a NWBrowser discovers has the deviceID set as its name. Due to this the NWBrowser is able to determine if it should try and connect to the peer or if it should not because the discovered peer is going to try and connect to it. So the algorithm above would be great if I could save and use the connection from NWListener to send messages over.
37
0
760
Nov ’25
Using Network Framework + Bonjour + QUIC + TLS
Hello, I was able to use the TicTackToe code base and modify it such that I have a toggle at the top of the screen that allows me to start / stop the NWBrowser and NWListener. I have it setup so when the browser finds another device it attempts to connect to it. I support N devices / connections. I am able to use the NWParameters extension that is in the TickTackToe game that uses a passcode and TLS. I am able to send messages between devices just fine. Here is what I used extension NWParameters { // Create parameters for use in PeerConnection and PeerListener. convenience init(passcode: String) { // Customize TCP options to enable keepalives. let tcpOptions = NWProtocolTCP.Options() tcpOptions.enableKeepalive = true tcpOptions.keepaliveIdle = 2 // Create parameters with custom TLS and TCP options. self.init(tls: NWParameters.tlsOptions(passcode: passcode), tcp: tcpOptions) // Enable using a peer-to-peer link. self.includePeerToPeer = true } // Create TLS options using a passcode to derive a preshared key. private static func tlsOptions(passcode: String) -> NWProtocolTLS.Options { let tlsOptions = NWProtocolTLS.Options() let authenticationKey = SymmetricKey(data: passcode.data(using: .utf8)!) let authenticationCode = HMAC<SHA256>.authenticationCode(for: "HI".data(using: .utf8)!, using: authenticationKey) let authenticationDispatchData = authenticationCode.withUnsafeBytes { DispatchData(bytes: $0) } sec_protocol_options_add_pre_shared_key(tlsOptions.securityProtocolOptions, authenticationDispatchData as __DispatchData, stringToDispatchData("HI")! as __DispatchData) sec_protocol_options_append_tls_ciphersuite(tlsOptions.securityProtocolOptions, tls_ciphersuite_t(rawValue: TLS_PSK_WITH_AES_128_GCM_SHA256)!) return tlsOptions } // Create a utility function to encode strings as preshared key data. private static func stringToDispatchData(_ string: String) -> DispatchData? { guard let stringData = string.data(using: .utf8) else { return nil } let dispatchData = stringData.withUnsafeBytes { DispatchData(bytes: $0) } return dispatchData } } When I try to modify it to use QUIC and TLS 1.3 like so extension NWParameters { // Create parameters for use in PeerConnection and PeerListener. convenience init(psk: String) { self.init(quic: NWParameters.quicOptions(psk: psk)) self.includePeerToPeer = true } private static func quicOptions(psk: String) -> NWProtocolQUIC.Options { let quicOptions = NWProtocolQUIC.Options(alpn: ["h3"]) let authenticationKey = SymmetricKey(data: psk.data(using: .utf8)!) let authenticationCode = HMAC<SHA256>.authenticationCode(for: "hello".data(using: .utf8)!, using: authenticationKey) let authenticationDispatchData = authenticationCode.withUnsafeBytes { DispatchData(bytes: $0) } sec_protocol_options_set_min_tls_protocol_version(quicOptions.securityProtocolOptions, .TLSv13) sec_protocol_options_set_max_tls_protocol_version(quicOptions.securityProtocolOptions, .TLSv13) sec_protocol_options_add_pre_shared_key(quicOptions.securityProtocolOptions, authenticationDispatchData as __DispatchData, stringToDispatchData("hello")! as __DispatchData) sec_protocol_options_append_tls_ciphersuite(quicOptions.securityProtocolOptions, tls_ciphersuite_t(rawValue: TLS_AES_128_GCM_SHA256)!) sec_protocol_options_set_verify_block(quicOptions.securityProtocolOptions, { _, _, sec_protocol_verify_complete in sec_protocol_verify_complete(true) }, .main) return quicOptions } // Create a utility function to encode strings as preshared key data. private static func stringToDispatchData(_ string: String) -> DispatchData? { guard let stringData = string.data(using: .utf8) else { return nil } let dispatchData = stringData.withUnsafeBytes { DispatchData(bytes: $0) } return dispatchData } } I get the following errors in the console boringssl_session_handshake_incomplete(241) [C3:1][0x109d0c600] SSL library error boringssl_session_handshake_error_print(44) [C3:1][0x109d0c600] Error: 4459057536:error:100000ae:SSL routines:OPENSSL_internal:NO_CERTIFICATE_SET:/Library/Caches/com.apple.xbs/Sources/boringssl/ssl/tls13_server.cc:882: boringssl_session_handshake_incomplete(241) [C4:1][0x109d0d200] SSL library error boringssl_session_handshake_error_print(44) [C4:1][0x109d0d200] Error: 4459057536:error:100000ae:SSL routines:OPENSSL_internal:NO_CERTIFICATE_SET:/Library/Caches/com.apple.xbs/Sources/boringssl/ssl/tls13_server.cc:882: nw_endpoint_flow_failed_with_error [C3 fe80::1884:2662:90ca:b011%en0.65328 in_progress channel-flow (satisfied (Path is satisfied), viable, interface: en0[802.11], scoped, ipv4, dns, uses wifi)] already failing, returning nw_endpoint_flow_failed_with_error [C4 192.168.0.98:65396 in_progress channel-flow (satisfied (Path is satisfied), viable, interface: en0[802.11], scoped, ipv4, dns, uses wifi)] already failing, returning quic_crypto_connection_state_handler [C1:1] [2ae0263d7dc186c7-] TLS error -9858 (state failed) nw_connection_copy_connected_local_endpoint_block_invoke [C3] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection nw_connection_copy_connected_remote_endpoint_block_invoke [C3] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection nw_connection_copy_protocol_metadata_internal_block_invoke [C3] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection quic_crypto_connection_state_handler [C2:1] [84fdc1e910f59f0a-] TLS error -9858 (state failed) nw_connection_copy_connected_local_endpoint_block_invoke [C4] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection nw_connection_copy_connected_remote_endpoint_block_invoke [C4] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection nw_connection_copy_protocol_metadata_internal_block_invoke [C4] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection Am I missing some configuration? I noticed with the working code that uses TCP and TLS that there is an NWParameters initializer that accepts tls options and tcp option but there isnt one that accepts tls and quic. Thank you for any help :)
19
0
1.8k
Dec ’24