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

Post

Replies

Boosts

Views

Activity

Getting the Wi-Fi router BSSID from a Daemon.
Our macOS application (running as a LaunchDaemon) has been able to report the current Wi-Fi SSID and BSSID (if connected) using the airport command. Since airport has been removed from macOS, we have not been able to collect BSSID information. First, I demonstrate that the BSSID exists: I can option-click the Wi-Fi status menu icon and see the following: Wi-Fi Interface Name: en0 Address: a8:8f:d9:52:10:7d * * * Enable Wi-Fi Logging Create Diagnostics Report... Open Wireless Diagnostics... * * * Known Network polymorphic IP Address: 192.168.86.50 Router: 192.168.86.1 Security: WPA2 Personal BSSID: 88:3d:24:ba:36:81 Channel: 149 (5 GHz, 80 MHZ) Country Code: US RSSI: -60 dBm Noise: -89 dBm Tx Rate: 520 Mbps PHY Mode: 802.11ac MCS Index: 5 NSS: 2 * * * Other Networks * * * Wi-Fi Settings... This says to me that: The WiFi router I am connected to has SSID = polymorphic. The WiFi router I am connected to has BSSID = 88:3d:24:ba:36:81. My computer's Wi-Fi hardware has MAC address = a8:8f:d9:52:10:7d. My computer's Wi-Fi interface name = en0. To get this information now (from within an application), I have attempted to run: /usr/sbin/networksetup -listallhardwareports The output of that command includes the following Hardware Port: Wi-Fi Device: en0 Ethernet Address: a8:8f:d9:52:10:7d To get the SSID, I can then execute: $ /usr/sbin/networksetup -getairportnetwork en0 Current Wi-Fi Network: polymorphic But I still can't get the router's BSSID. So I try $/usr/sbin/networksetup -getinfo 'Wi-Fi' DHCP Configuration IP address: 192.168.86.50 Subnet mask: 255.255.255.0 Router: 192.168.86.1 Client ID: IPv6: Automatic IPv6 IP address: none IPv6 Router: none Wi-Fi ID: a8:8f:d9:52:10:7d Still no new information. $ /usr/sbin/networksetup -getmacaddress en0 Ethernet Address: a8:8f:d9:52:10:7d (Device: en0) This is not helpful either. Let's try another approach: $ /usr/sbin/netstat -nr -f inet | grep ^default default 192.168.86.1 UGScg en0 This tells me that my router's IP address is 192.168.86.1. The arp tool should be able to translate $ /usr/sbin/arp -a -n | grep "(192.168.86.1)" ? (192.168.86.1) at 88:3d:24:ba:36:7f on en0 ifscope [ethernet] This tells me that the router's MAC address is "88:3d:24:ba:36:7f", but it is not the same value as the router's BSSID, which we know to be 88:3d:24:ba:36:81! Another approach. I wrote the following Swift program: import CoreWLAN let c : CWWiFiClient = CWWiFiClient.shared() if let ifs : [CWInterface] = c.interfaces() { for i in ifs { print( i.interfaceName ?? "<nil>", i.powerOn(), i.ssid() ?? "<nil>", i.bssid() ?? "<nil>") } } When executing it with swift, I got: en0 true polymorphic <nil> So for some reason, the CoreWLAN API is hiding the BSSID, but not the SSID. When I use swiftc to compile before executing, I get: en0 true <nil> <nil> Why is the CoreWLAN API now hiding the SSID as well? I even tried an Objective-C program: // Link with: // -framework Foundation // -framework CoreWLAN #include <stdio.h> #include <CoreWLAN/CoreWLAN.h> void printWifi() { NSArray<CWInterface*>* ifs = [[CWWiFiClient sharedWiFiClient] interfaces]; for (CWInterface* i in ifs) { printf("%s %s %s %s\n", [i.interfaceName UTF8String], [i powerOn] ? "true" : "false", [[i ssid] UTF8String], [[i bssid] UTF8String]); } } int main() { printWifi(); return 0; } It prints out: en0 true (null) (null) Based on https://developer.apple.com/forums/thread/131636, I tried // Link with: // -framework Foundation // -framework CoreWLAN // -framework CoreLocation #include <stdio.h> #include <CoreWLAN/CoreWLAN.h> #include <CoreLocation/CoreLocation.h> void printWifi() { NSArray<CWInterface*>* ifs = [[CWWiFiClient sharedWiFiClient] interfaces]; for (CWInterface* i in ifs) { printf("%s %s %s %s\n", [i.interfaceName UTF8String], [i powerOn] ? "true" : "false", [[i ssid] UTF8String], [[i bssid] UTF8String]); } } CLLocationManager* startCoreLocation() { CLLocationManager* mgr = [[CLLocationManager alloc] init]; [mgr requestAlwaysAuthorization]; [mgr startUpdatingLocation]; return mgr; } int main() { CLLocationManager* locMgr = startCoreLocation(); printWifi(); return 0; } That change did not seem to make a difference. After more work, I found that I can not even figure out CLLocationManager authorization. So I attempted to create a minimal program that can get that: https://github.com/HalCanary/location. I am not sure how to proceed here. What is wrong with my location code? Will our application need to get the com.apple.security.personal-information.location entitlement in order to get the BSSID?
4
0
529
Jul ’24
Connecting to EAP-PEAP Networks via NEHotspotConfigurationManager
I need to programatically connect to a Enterprise Network with security type EAP-PEAP. NEHotspotEAPSettings *eapSettings = [[NEHotspotEAPSettings alloc] init]; eapSettings.username = username; eapSettings.password = password; eapSettings.supportedEAPTypes = [NSArray arrayWithObjects:[NSNumber numberWithInteger:NEHotspotConfigurationEAPTypeEAPPEAP], nil]; //Inner authentication eapSettings.ttlsInnerAuthenticationType = NEHotspotConfigurationEAPTTLSInnerAuthenticationMSCHAPv2; eapSettings.outerIdentity = @""; //Server name of the network eapSettings.trustedServerNames = @[@"servername"]; if (@available(iOS 11.0, *)) { // Create Hotspot Configuration NEHotspotConfiguration *configuration = [[NEHotspotConfiguration alloc] initWithSSID:ssid eapSettings:eapSettings]; NSLog(@"WIFIManager, NEHotspotConfiguration initialized"); [[NEHotspotConfigurationManager sharedManager] applyConfiguration:configuration completionHandler:^(NSError * _Nullable error) { NSLog(@"WIFIManager, NEHotspotConfiguration Configured"); if (error != nil) { NSLog(@"WIFIManager, NEHotspotConfiguration Error: %@", error); if (error.code == NEHotspotConfigurationErrorAlreadyAssociated) { resolve(@(YES)); } else { reject(@"connection_error", @"Failed to connect to Wi-Fi", error); } } else { resolve(@(YES)); NSLog(@"WIFIManager, NEHotspotConfiguration Success"); } }]; }else { reject(@"ios_error", @"Not supported in iOS<11.0", nil); } } This is the code I have tried to connect to the network. It is always giving a true-negative result. As the documentation states, does NEHotspotConfigurationManager supports EAP-PEAP with MSCHAPv2 inner authentication? If it does, is it the correct way of implementing it? Is there any other way to connect to EAP-PEAP networks using Swift or Objective C?
2
0
299
Jul ’24
Advanced UDP with Network.framework
I finally found a time to experiment with Network.framework and I find the experience very pleasant. The API looks well thought out and is a pleasure to work with. My app (on the App Store for around 13 years) uses UDP networking to create a mesh between multiple devices where each device acts as a server and client at the same time. It does that by creating one UDP socket on each device bound to a *:<port> and then uses that socket to sendmsg to other peers. That way all peers can communicate with each other using their well known <port>. This all works great and fine. To test the performance and verify the functionality I have multiple XCTestCase scenarios where I create multiple peers and simulate various communications and verify their correctness. Within the XCTestCase process that means creating multiple underlying sockets and then bind them to multiple local random <port>s. Works great. Now I'm trying to port this functionality to Network.framework. Let's assume two peers for now. Code simplified. Prepare NWParameter instances for both peers, plain UDP for now. // NOTE: params for peer 1 let p1 = NWParameters(dtls: nil, udp: .init()) p1.requiredLocalEndpoint = .hostPort(host: "0.0.0.0", port: 2222) p1.allowLocalEndpointReuse = true // NOTE: params for peer 2 let p2 = NWParameters(dtls: nil, udp: .init()) p2.requiredLocalEndpoint = .hostPort(host: "0.0.0.0", port: 3333) p2.allowLocalEndpointReuse = true Create NWListeners for each peer. // NOTE: listener for peer 1 - callbacks omitted for brevity let s1 = try NWListener(using: parameters) s1.start(queue: DispatchQueue.main) // NOTE: listener for peer 2 - callbacks omitted for brevity let s2 = try NWListener(using: parameters) s2.start(queue: DispatchQueue.main) The listeners start correctly and I can verify that I have two UDP ports open on my machine and bound to port 2222 and 3333. I can use netcat -u to send UDP packets to them and correctly see the appropriate NWConnection objects being created and all callbacks invoked. So far so good. Now in that XCTestCase, I want to exchange a packets between peer1 and peer2. So I will create appropriate NWConnection and send data. // NOTE: connection to port 3333 from port 2222 let c1 = NWConnection(host: "127.0.0.1", port: 3333, using: p1) c2.start(queue: DispatchQueue.main) // NOTE: wait for the c1 state .ready c2.send(content: ..., completion: ...) And now comes the problem. The connection transitions to .preparing state, with correct parameters, and then to .waiting state with Error 48. [L1 ready, local endpoint: <NULL>, parameters: udp, local: 0.0.0.0:2222, definite, attribution: developer, server, port: 3333, path satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, service: <NULL>] [L2 ready, local endpoint: <NULL>, parameters: udp, local: 0.0.0.0:3333, definite, attribution: developer, server, port: 2222, path satisfied (Path is satisfied), interface: en0[802.11], ipv4, dns, uses wifi, service: <NULL>] nw_socket_connect [C1:1] connectx(6 (guarded), [srcif=0, srcaddr=0.0.0.0:2222, dstaddr=127.0.0.1:3333], SAE_ASSOCID_ANY, 0, NULL, 0, NULL, SAE_CONNID_ANY) failed: [48: Address already in use] nw_socket_connect [C1:1] connectx failed (fd 6) [48: Address already in use] nw_socket_connect connectx failed [48: Address already in use] state: preparing connection: [C1 127.0.0.1:2222 udp, local: 0.0.0.0:2222, attribution: developer, path satisfied (Path is satisfied), interface: lo0] state: waiting(POSIXErrorCode(rawValue: 48): Address already in use) connection: [C1 127.0.0.1:3333 udp, local: 0.0.0.0:2222, attribution: developer, path satisfied (Path is satisfied), interface: lo0] I believe this happens because the connection c1 essentially tries to create under the hood a new socket or something instead of reusing the one prepared for s1. I can make the c1 work if I create the NWConnection without binding to the same localEndpoint as the listener s1. But in that case the packets sent via c1 use random outgoing port. What am I missing to make this scenario work in Network.framework ? P.S. I was able to make it work using the following trick: bind the s1 NWListener local endpoint to ::2222 (IPv6) connect the c1 NWConnection to 127.0.0.1:3333 (IPv4) That way packets on the wire are sent/received correctly. I would believe that this is a bug in the Network.framework. I can open a DTS if more information is needed.
8
0
1.1k
Mar ’24
Checking SIM Status on iPhone
I am developing an iOS application. In that i should show a status of their cellular provider such as Active, Inactive, or sim not available. Which also includes physical and eSim. I used Telephony.CTcarrier. One thing its deprecated and another case iOS 15 and below, even if i put my device in Airplane mode still its returning the carrierName and NetworkCode. Is there any specific API to retrieve these realtime data? TIA
4
0
460
Jul ’24
Network is not working when upload smb using NEFilterDataProvider in macOS
Network is not working when over 50MB size file upload smb using NEFilterDataProvider in macOS The event received through NEFilterDataProvider is returned immediately without doing any other work. override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict { guard let socketFlow = flow as? NEFilterSocketFlow, let auditToken = socketFlow.sourceAppAuditToken, let remoteEndpoint = socketFlow.remoteEndpoint as? NWHostEndpoint, let localEndpoint = socketFlow.localEndpoint as? NWHostEndpoint else { return .allow() } return .filterDataVerdict(withFilterInbound: true, peekInboundBytes: Int.max, filterOutbound: true, peekOutboundBytes: Int.max) } override func handleInboundData(from flow: NEFilterFlow, readBytesStartOffset offset: Int, readBytes: Data) -> NEFilterDataVerdict { guard let socketFlow = flow as? NEFilterSocketFlow, let auditToken = socketFlow.sourceAppAuditToken, let remoteEndpoint = socketFlow.remoteEndpoint as? NWHostEndpoint, let localEndpoint = socketFlow.localEndpoint as? NWHostEndpoint else { return .allow() } return NEFilterDataVerdict(passBytes: readBytes.count, peekBytes: Int.max) } override func handleOutboundData(from flow: NEFilterFlow, readBytesStartOffset offset: Int, readBytes: Data) -> NEFilterDataVerdict { guard let socketFlow = flow as? NEFilterSocketFlow, let auditToken = socketFlow.sourceAppAuditToken, let remoteEndpoint = socketFlow.remoteEndpoint as? NWHostEndpoint, let localEndpoint = socketFlow.localEndpoint as? NWHostEndpoint else { return .allow() } return NEFilterDataVerdict(passBytes: readBytes.count, peekBytes: Int.max) } override func handleInboundDataComplete(for flow: NEFilterFlow) -> NEFilterDataVerdict { guard let socketFlow = flow as? NEFilterSocketFlow, let auditToken = socketFlow.sourceAppAuditToken, let remoteEndpoint = socketFlow.remoteEndpoint as? NWHostEndpoint, let localEndpoint = socketFlow.localEndpoint as? NWHostEndpoint else { return .allow() } return .allow() } override func handleOutboundDataComplete(for flow: NEFilterFlow) -> NEFilterDataVerdict { guard let socketFlow = flow as? NEFilterSocketFlow, let auditToken = socketFlow.sourceAppAuditToken, let remoteEndpoint = socketFlow.remoteEndpoint as? NWHostEndpoint, let localEndpoint = socketFlow.localEndpoint as? NWHostEndpoint else { return .allow() } return .allow() } how can i fix it?
2
0
295
Jul ’24
local iOS Zeroconf Device vs. iOS simulator Zeroconf Visual Studio
Hello, I am not exactly sure this is the right place to ask this since it involves Microsoft's Visual Studio, but because the problem I am having involves iOS I figured I would anyway. Info: I am trying to develop a cross-platform application using .NET Maui in Visual Studio. I am on a Windows machine pairing to a mac with Xcode installed, so I can build for iOS. My local device is an iPhone 13 running on iOS Version 17.5.1. The simulators I am using in Visual Studio are all iOS Version 17+. I am using the .NET NuGet package Zeroconf which should work for both iOS and Android (Repo:https://github.com/novotnyllc/Zeroconf). I also believe I have given the correct permissions for iOS in my Info.plist. Problem: The problem I am coming across is that when I build and run my application in one of the installed iOS Simulators and I go to scan for local devices it is able to come back with 80-100 devices that we want to find, but when I build and run it on my local device it comes back with nothing found. I had searched for similar problems that other people were having and found that iOS 17+ has some potential problems when it comes to searching for devices. Is this true? If someone can help me solve this issue between the simulator and local device I would greatly appreciate it. If there is any other information that I can give to help with solving this problem please let me know. Thanks! Discovery Code: TimeSpan scanTime = TimeSpan.FromMilliseconds(2000); int retries = 4; int retryDelayMilliseconds = 2000; Action<IZeroconfHost> callback = null; CancellationToken cancellationToken = default; System.Net.NetworkInformation.NetworkInterface[] arrayofnics = NetworkInterface.GetAllNetworkInterfaces(); int index = 0; for (int i = 0; i < arrayofnics.Length; i++) { // en0 is for iOS 0 is for android. if (arrayofnics[i].Description.Equals("en0") || arrayofnics[i].Description.Equals("0")) { index = i; break; } } System.Net.NetworkInformation.NetworkInterface wifi = arrayofnics[index]; System.Net.NetworkInformation.NetworkInterface[] netInterfacesToSendRequestOn = { wifi }; IReadOnlyList<IZeroconfHost> results = null; IReadOnlyList<string> domains; var browseDomains = await ZeroconfResolver.BrowseDomainsAsync(); domains = browseDomains.Select(g => g.Key).ToList(); results = await ZeroconfResolver.ResolveAsync("_http._tcp.local.", scanTime, retries, retryDelayMilliseconds, callback, cancellationToken, netInterfacesToSendRequestOn); Info.plist: <key>NSLocalNetworkUsageDescription</key> <string>This app requires local network access to discover devices.</string> <key>NSBonjourServices</key> <array> <string>_ipspeaker._tcp.local</string> <string>_ipspeaker._tcp.local.</string> <string>_ipspeaker._tcp.</string> <string>_http._tcp.local.</string> <string>_http._tcp.</string> </array>
3
0
380
Jul ’24
filtering network data in multi thread
Hello, I need to implement filtering network data which is based on Network Extension (network content filter) Let's say I have rule which leads to monitoring several data flows in parallel. Are there any way to handle each data flow in separate thread? (number of threads is equal to number of analyzed flow) If one flow is paused by pauseVerdict, will the filter data provider recieve new data chunks in handleInboundDataFromFlow for other flows? Are there any possibility to change data flow on a fly? Thank you in advance.
3
0
336
Jul ’24
Content filter providers seem to block all requests during startup on iOS 16 or 17
Hi, Consider a content filter app that allows most requests. While running, it handles requests and determine what to do. It does not affect any request while it is not running. However, during startup, it seems to block all requests, on iOS 16 or 17. On iOS 15, the behavior is bit different. Show the picture below: Questions Is this the expected behavior? Is this documented? Steps to reproduce Create content filter app with filter data provider with lengthy startup, something like the following: import NetworkExtension class FilterDataProvider: NEFilterDataProvider { override func startFilter(completionHandler: @escaping ((any Error)?) -> Void) { Task { try await Task.sleep(nanoseconds: 10 * 1_000_000_000) completionHandler(nil) } } override func stopFilter(with reason: NEProviderStopReason) async {} override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict { guard let url: String = flow.url?.absoluteString else { return .allow() } if url.contains("example.net/") { return .drop() } if url.contains("example.org/") { exit(42) } return .allow() } } Install the app on a supervised iPhone or iPad. Install a WebContentFilter profile. Wait for the content filter to start. You can check the status in Settings > General > VPN & Device Management > Content Filter. Open Safari app. Request http://example.net/ and confirm that it is blocked. Request the other URLs and confirm that it is allowed. Request http://example.org. It kills the filter data provider. Request some URLs quickly. Background to the questions We offer a content filter app that might be stopped during the device sleeps. When a non-our-app’s push notification is received, the device wakes up, and the content filter starts up. Then the push notification seems to be lost. It is observed on iOS 16 and 17, not on iOS 15.
2
0
259
Jul ’24
Support for P2P Connectivity and Network Requests in the Background
We are currently developing an application that runs in the background and continuously scans for other nearby devices via peer-to-peer networking. Generally, the high-level goals are: Scan for nearby devices while the app is in the background state. We only need to discover devices that are also running our app. Read a small token of data from each peer device found (no need for full-duplex connection) Submit this token to our server via a background network request On Android we have demonstrated this functionality using both Bluetooth LE and WifiDirect service discovery, and background operation is easily achieved with Android services. We are currently trying to expand our application to support cross-platform compatibility between IOS and Android, including IOS<-->IOS and IOS<-->Android discovery (in the background). Is there a way to achieve this desired functionality on IOS?
3
0
403
Jul ’24
WiFi network setting won’t accept http proxy in iOS 18 beta 4
I am attempting to enter proxy settings under the settings for a WiFi network. I have triple checked the credentials and for whatever reason the settings wont save. I have attempted forgetting the wifi network and reconnecting, resetting all network settings, and even wiping the phone and starting over from scratch. The phone simply will not accept the setting. I have tried it on my MacStudio and an iPad and the settings saved the first time. What am I missing here? I am union iOS 18 beta 4
1
0
259
Jul ’24
Sample projects of NEFilterProvider use IPC but the documentation says that it blocks IPC
The sample project Filtering Network Traffic uses IPC (NSXPCConnection etc.) to send data from the network extension to the app, but the documentation for NEFilterProvider says The sandbox prevents the Filter Data Provider extension from moving network content outside of its address space by blocking all network access, IPC, and disk write operations. Since my network extension forwards all network traffic to the app so that the user can see it, I was wondering when the app isn’t running and the user shuts down the machine, if the network extension could write the flows it wasn’t able to forward to the app to disk, so that it could read them on the next successful connection to the app. Then almost by accident I read again the documentation and according to the quoted passage a network extension cannot write to disk, but it also cannot use IPC. Is NSXPCConnection not considered IPC, or could the statement that it cannot write to disk be false as well?
3
0
279
Jul ’24
Content Filter remoteEndpoint from Chrome
I've developed a network content filter extension for macOS. When overriding the handleNewFlow method, I want to examine the hostname for the given flow. I can do this for browsers like Safari, Firefox, and DuckDuckGo using flow.url?.host (WebKit flows) or (flow as? NEFilterSocketFlow)?.remoteHostname (Firefox flows). However, for Google Chrome, these properties return nil, and I only get an outgoing IP address using socketFlow.remoteEndpoint as? NWHostEndpoint. How can I retrieve the outgoing domain for flows from Google Chrome? I've tried resolving the IP to a domain name, but in most cases, I'm unable to retrieve the domain name using the following functions I found on forum posts: func reverseDNS(ip: String) -> String { var results: UnsafeMutablePointer<addrinfo>? = nil defer { if let results = results { freeaddrinfo(results) } } let error = getaddrinfo(ip, nil, nil, &results) if (error != 0) { NSLog("Unable to reverse ip: \(ip)") return ip } for addrinfo in sequence(first: results, next: { $0?.pointee.ai_next }) { guard let pointee = addrinfo?.pointee else { NSLog("Unable to reverse ip: \(ip)") return ip } let hname = UnsafeMutablePointer<Int8>.allocate(capacity: Int(NI_MAXHOST)) defer { hname.deallocate() } let error = getnameinfo(pointee.ai_addr, pointee.ai_addrlen, hname, socklen_t(NI_MAXHOST), nil, 0, 0) if (error != 0) { continue } return String(cString: hname) } return ip } func resolveIP(_ ipAddress: String) -> String? { var hints = addrinfo( ai_flags: AI_NUMERICHOST, ai_family: AF_UNSPEC, ai_socktype: SOCK_STREAM, ai_protocol: 0, ai_addrlen: 0, ai_canonname: nil, ai_addr: nil, ai_next: nil ) var res: UnsafeMutablePointer<addrinfo>? = nil let status = getaddrinfo(ipAddress, nil, &hints, &res) guard status == 0, let result = res else { print("Error: \(String(cString: gai_strerror(status)))") return nil } var hostBuffer = [CChar](repeating: 0, count: Int(NI_MAXHOST)) if let addr = result.pointee.ai_addr { let addrLen = socklen_t(result.pointee.ai_addrlen) if getnameinfo(addr, addrLen, &hostBuffer, socklen_t(hostBuffer.count), nil, 0, 0) == 0 { freeaddrinfo(res) return String(cString: hostBuffer) } } freeaddrinfo(res) return nil } I know that Little Snitch can block and display domain name requests using a content filter, even in Google Chrome, so I'm certain it's possible. However, I'm unsure how to accomplish this. Can anyone assist me in resolving IP addresses to hostnames for most IP addresses, or in obtaining the hostnames directly from the flow on macOS?
1
0
272
Jul ’24
Fragment large size data sent and received using NSKeyedArchiver.archivedData in GameCenter
Trying to send and receive data in the GameCenter environment using the following methods: func sendData(dictionaryWithData dictionary: Dictionary&lt;String, Any&gt;,toPeer targetPeers: [GKPlayer]) { guard let match = self.match else { return } do { let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false) try match.send(dataToSend, to: targetPeers, dataMode: .reliable) } catch { #if DEBUG print("CONNECTION MANAGER SEND DATA ERROR") #endif } } public func match(_ theMatch: GKMatch,didReceive data: Data,forRecipient recipient: GKPlayer,fromRemotePlayer player: GKPlayer) { if match != theMatch { return } DispatchQueue.main.async { do { guard let message = NSDictionary.unsecureUnarchived(from: data) as? Dictionary&lt;String, Any&gt; else {return} ... &lt;CODE&gt; ... } ///Source: https://stackoverflow.com/questions/51487622/unarchive-array-with-nskeyedunarchiver-unarchivedobjectofclassfrom static func unsecureUnarchived(from data: Data) -&gt; Self? { do { let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data) unarchiver.requiresSecureCoding = false let obj = unarchiver.decodeObject(of: self, forKey: NSKeyedArchiveRootObjectKey) if let error = unarchiver.error { print("Error:\(error)") } return obj } catch { print("Error:\(error)") } return nil } Everything works great until the data exceeds 87K (which, I understand, is the limit for exchanging data in GameCenter). The data is not sent and gives the following error: Async message[1FCA0D11-05DE-47D0-9714-983C8023F5C1] send error: FailedToSendData: , InternalError: reliable, maxPayloadSizeExceeded Interesting enough, I do not have this problem when using MCSession, as follows, even if data exceeds 87K: func sendData(dictionaryWithData dictionary: Dictionary&lt;String, Any&gt;, toPeer targetPeers: [MCPeerID]) { do { let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false) try session.send(dataToSend, toPeers: targetPeers, with: MCSessionSendDataMode.reliable) } catch { #if DEBUG print("CONNECTION MANAGER SEND DATA ERROR") #endif } } I have been doing research and found that I need to fragment data and send and receive it in packages. But I could not find a good explanation how to do it. Any help would be appreciated!
5
0
404
Jul ’24
Crashed: com.apple.network.connection-208 EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000d25b5b890
i got a crash report from Firebase Crashlytics ,i cannot reproduce the issue .it happens in iOS 17 it seems like it related to Network library Crashed: com.apple.network.connection-208 0 libobjc.A.dylib 0x3150 objc_retain_x23 + 16 1 Network 0x64138 nw_connection_report_state_with_handler_on_nw_queue + 1548 2 Network 0x20f64 __nw_connection_start_block_invoke + 428 3 libdispatch.dylib 0x26a8 _dispatch_call_block_and_release + 32 4 libdispatch.dylib 0x4300 _dispatch_client_callout + 20 5 libdispatch.dylib 0xb894 _dispatch_lane_serial_drain + 748 6 libdispatch.dylib 0xc3f8 _dispatch_lane_invoke + 432 7 libdispatch.dylib 0xd6a8 _dispatch_workloop_invoke + 1756 8 libdispatch.dylib 0x17004 _dispatch_root_queue_drain_deferred_wlh + 288 9 libdispatch.dylib 0x16878 _dispatch_workloop_worker_thread + 404 10 libsystem_pthread.dylib 0x1964 _pthread_wqthread + 288 11 libsystem_pthread.dylib 0x1a04 start_wqthread + 8 com.apple.main-thread 0 ??? 0x1c51e0678 (Missing) 1 ??? 0x1c51e0610 (Missing) 2 ??? 0x1c51dfee0 (Missing) 3 libsystem_c.dylib 0x176a8 backtrace_symbols + 144 4 Network 0x5fe380 __nw_create_backtrace_string + 208 5 Network 0x10c43c __nw_connection_set_queue_block_invoke + 376 6 Network 0x10bf6c nw_connection_set_queue + 184 7 Network 0x18fad0 NWConnection.start(queue:) + 280 8 NWWebSocket 0x4b24 $s11NWWebSocketAAC7connectyyF + 1472 9 PusherSwift 0x15534 $s11PusherSwift0A10ConnectionC7connectyyF + 240 10 PusherSwift 0x15568 $s11PusherSwift0A10ConnectionC7connectyyFTo + 24 11 Foundation 0x74dcec __NSFireTimer + 96 12 CoreFoundation 0xad5d0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 32 13 CoreFoundation 0xad278 __CFRunLoopDoTimer + 1004 14 CoreFoundation 0x36e74 __CFRunLoopDoTimers + 288 15 CoreFoundation 0x33e8c __CFRunLoopRun + 1856 16 CoreFoundation 0x33668 CFRunLoopRunSpecific + 608 17 GraphicsServices 0x35ec GSEventRunModal + 164 18 UIKitCore 0x22c294 -[UIApplication _run] + 888 19 UIKitCore 0x22b8d0 UIApplicationMain + 340 20 SwiftUI 0x11620fc OUTLINED_FUNCTION_31 + 604 21 SwiftUI 0x1161f40 OUTLINED_FUNCTION_31 + 160 22 SwiftUI 0xdd3868 OUTLINED_FUNCTION_26 + 2196 23 Prospace VMS Native 0x6a144 main + 4306067780 (Prospace_VMS_NativeApp.swift:4306067780) 24 ??? 0x1c51badcc (Missing)
6
0
293
Jun ’24
NETransparentProxyProvider excludedRules limit?
I have this in my start code: for p in [4500] + Array(3478...3497) + Array(16384...16387) + Array(16393...16402) { // According to the documentation, I *should* be able to // use "" for the hostname, and prefix:0, but it complained // about the prefix length, so we use the top bit for ipv4 // and ipv6. let port = "\(p)" os_log(.debug, log: Self.log, "Setting up to exclude port %{public}s", port) let host_1 = NWHostEndpoint(hostname:"0.0.0.0", port: port) let host_2 = NWHostEndpoint(hostname:"255.0.0.0", port: port) let host_3 = NWHostEndpoint(hostname:"0::0", port: port) let host_4 = NWHostEndpoint(hostname:"ffff::0", port: port) for host in [host_1, host_3] { let udpPortRule = NENetworkRule(destinationNetwork: host, prefix:1, protocol: .UDP) excludeRules.append(udpPortRule) } } settings.excludedNetworkRules = excludeRules This produces the log message 2024-07-23 11:16:38.335649+0100 0x901984 Debug 0x0 20686 0 com.kithrup.SimpleTPP.Provider: [com.kithrup:Provider] Setting up to exclude port 3483 Later on, when running, I log the new flows in handleNewUDPFlow(:,initialRemoteEndpoint:), and it produces 2024-07-23 11:17:05.712055+0100 0x901984 Debug 0x0 20686 0 com.kithrup.SimpleTPP.Provider: [com.kithrup:Provider] handleNewUDPFlow(_:initialRemoteEndpoint:): new UDP flow for host 17.252.13.7:3483 app com.apple.identityservicesd So port 3483 is definitely in the excludedRules array, but it's not being excluded. (All of this is because I still can't figure out why FaceTime isn't working with us.)
5
0
280
Jul ’24
SwiftUI URLRequest Warning: "Connection has no local endpoint"
I have a simple SwiftUI application that sends a URLRequest as shown in the code snippet below: import SwiftUI @main struct GOGODemoApp: App { var body: some Scene { WindowGroup { MyView() } } } struct MyView: View { var body: some View { Button("Click") { sendHTTPRequest(to: "https://www.google.com") { code, err in print("Finished, code: \(code ?? -1), err: \(String(describing: err))") } } } } func sendHTTPRequest(to urlString: String, completion: @escaping (Int?, Error?) -&gt; Void) { guard let url = URL(string: urlString) else { completion(nil, NSError(domain: "InvalidURL", code: 0, userInfo: nil)) return } let task = URLSession.shared.dataTask(with: url) { _, resp, error in if let httpResponse = resp as? HTTPURLResponse { completion(httpResponse.statusCode, error) } else { completion(-1, error) } } task.resume() } However, Xcode prints the following warning messages: nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint nw_connection_copy_connected_local_endpoint_block_invoke [C1] Connection has no local endpoint nw_connection_copy_connected_local_endpoint_block_invoke [C3] Connection has no local endpoint nw_connection_copy_connected_local_endpoint_block_invoke [C3] Connection has no local endpoint Finished, code: 200, err: nil What does the warning 'Connection has no local endpoint' mean? Thank you for your assistance!
1
0
461
Jul ’24
Where are 'socketfilterfw' changes being stored in macOS 15?
With the recent change to socketfilterfw in macOS 15 we can no longer check if the application firewall is enabled or not via a plist. This is significant in our app because we rely on the NSFilePresenter interface to monitor the plist to alert our app whenever a user changes their firewall settings. Removing the plist is a breaking change for us. Can you please advise either some new location on disk for us to monitor, or if there is another way to observe this setting? We would ideally rather not have to poll 'socketfilterfw' on an interval. Thanks!
2
0
540
Jul ’24
QUIC Network framework interoperability
We would like to understand/double check if it is possible to use QUIC in Swift via Network framework as the client along with some other QUIC solution on the server (ex. s2n-quic, quiche, msquic, etc..) which won't be a macOS server. If that interoperability is indeed possible, the NWConnectionGroup won't be an approach we could use IMO, since probably we will need to develop that from scratch on both sides. Thanks in advance.
3
0
431
Jul ’24