I'm struggling to understand why the async-await version of URLSession download task APIs do not call the delegate functions, whereas the old non-async version that returns a reference to the download task works just fine.
Here is my sample code:
class DownloadDelegate: NSObject, URLSessionDownloadDelegate {
func urlSession(_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64,
totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64) {
// This only prints the percentage of the download progress.
let calculatedProgress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
let formatter = NumberFormatter()
formatter.numberStyle = .percent
print(formatter.string(from: NSNumber(value: calculatedProgress))!)
}
}
// Here's the VC.
final class DownloadsViewController: UIViewController {
private let url = URL(string: "https://pixabay.com/get/g0b9fa2936ff6a5078ea607398665e8151fc0c10df7db5c093e543314b883755ecd43eda2b7b5178a7e613a35541be6486885fb4a55d0777ba949aedccc807d8c_1280.jpg")!
private let delegate = DownloadDelegate()
private lazy var session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil)
// for the async-await version
private var task: Task<Void, Never>?
// for the old version
private var downloadTask: URLSessionDownloadTask?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
task?.cancel()
task = nil
task = Task {
let (_, _) = try! await session.download(for: URLRequest(url: url))
self.task = nil
}
// If I uncomment this, the progress listener delegate function above is called.
// downloadTask?.cancel()
// downloadTask = nil
// downloadTask = session.downloadTask(with: URLRequest(url: url))
// downloadTask?.resume()
}
}
What am I missing here?
Networking
RSS for tagExplore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
My app has local network permission on macOS Sequoia and works in most cases. I've noticed that after unlocking my MacBook Pro, the very first request will regularly fail with a No Route to Host. A simple retry resolves the issue, but I would have expected the very first request to succeed.
Is this is a known issue on macOS Sequoia or by design? I'd prefer not to add a retry for this particular request as the app is a network utility.
Topic:
App & System Services
SubTopic:
Networking
If an app has a text filtering extension and associated server that the iPhone OS communicates with, then how can that communication be authenticated?
In other words, how can the server verify that the request is valid and coming from the iPhone and not from some spoofer?
If somebody reverse engineers the associated domain urls our of the app's info.plist or entitlement files and calls the server url directly, then how can the server detect this has occurred and the request is not coming from the iPhone OS of a handset on which the app is installed?
Hello,
I'm working with the Network framework in Swift and have encountered an issue when attempting to create multiple NWListener instances on the same port. I am specifically trying to set the allowLocalEndpointReuse property on the NWParameters used for both listeners, but it seems that even with this property set, the second listener fails to start.
Here’s a simplified version of my implementation:
import Foundation
import Network
class UDPServer {
private var listener1: NWListener?
private var listener2: NWListener?
private let port: NWEndpoint.Port
init(port: UInt16) {
self.port = NWEndpoint.Port(rawValue: port) ?? NWEndpoint.Port(45000)
startListeners()
}
private func startListeners() {
let udpOptions = NWProtocolUDP.Options()
let params = NWParameters(udp: udpOptions)
params.allowLocalEndpointReuse = true
// Create first listener
do {
listener1 = try NWListener(using: params, on: port)
listener1?.start(queue: .global())
} catch {
print("Failed to create Listener 1: \(error)")
}
// Create second listener
do {
listener2 = try NWListener(using: params, on: port)
listener2?.start(queue: .global())
} catch {
print("Failed to create Listener 2: \(error)")
}
}
}
// Usage example
let udpServer = UDPServer(port: 45000)
RunLoop.main.run()
Observations:
I expect both listeners to operate without issues since I set allowLocalEndpointReuse to true.
However, when I attempt to start the second listener on the same port, it fails with an error.
output
nw_path_evaluator_evaluate NECP_CLIENT_ACTION_ADD error [48: Address already in use]
nw_path_create_evaluator_for_listener nw_path_evaluator_evaluate failed
nw_listener_start_on_queue [L2] nw_path_create_evaluator_for_listener failed
Listener 1 ready on port 45000
Listener 2 failed: POSIXErrorCode(rawValue: 48): Address already in use
Listener 2 cancelled
Questions:
Is there a limitation in the Network framework regarding multiple listeners on the same port even with allowLocalEndpointReuse?
Should I be using separate NWParameters for each listener, or is it acceptable to reuse them?
Even when trying to initialize NWParameters with NWProtocolUDP.Options, it doesn't seem to change anything. What steps should I take to modify these properties effectively?
If I wanted to set the noDelay option for TCP, how would I do that? Even when initializing NWParameters with init(.tls: , .tcp:), it doesn't seem to have any effect.
Any insights or recommendations would be greatly appreciated!
Thank you!
I'm developing in Swift and working on parsing DNS queries. I'm considering using dns_parse_packet, but I noticed that dns_util is deprecated (although it still seems to work in my limited testing).
As far as I know, there isn’t a built-in replacement for this. Is that correct?
On a related note, are there any libraries available for parsing TLS packets—specifically the ClientHello message to extract the Server Name Indication (SNI)—instead of relying on my own implementation?
Related to this post.
My code makes an iPhone use the CBCentralManager to talk to devices peripherals over core bluetooth.
After attempting a connect to a peripheral device, I get a didConnect callback on CBCentralManagerDelegate.
After this I initiate discovery of services using:
peripheral.discoverServices([CBUUID(nsuuid: serviceUUID)])
Since I am only interested in discovering my service of interest and not the others to speed up time to the actual sending of data.
This also gives me the didDiscoverServices callback without error prints in which I do the following:
guard let services = peripheral.services, !services.isEmpty else {
print("Empty services")
centralManager.cancelPeripheralConnection(peripheral)
return
}
And for next steps
if let serviceOfInterest = services.first(where: {$0.uuid == CBUUID(nsuuid: serviceUUID)}) { //double check for service we want
initiateDiscoverCharacteristics(peripheral: peripheral, service: serviceOfInterest)
}
Below is what initiateDiscoverCharacteristics() does. I basically only tries to discover certain characteristics of the selected service:
peripheral.discoverCharacteristics(
[CBUUID(nsuuid: readUUID),
CBUUID(nsuuid: writeUUID)],
for: serviceOfInterest)
For this also we get the didDiscoverCharacteristicsFor callback without error prints.
Here in this callback however we were not doing the serviceOfInterest check to see that we are getting the callback for the service we expect, since our understanding was that we will get didDiscoverCharacteristicsFor callback for the characteristics on the serviceOfInterest because that is what peripheral.discoverCharacteristics() was initiated for.
When we go ahead to write some data/subscribe for notify/read data we have 2 guard statements for services and characteristics of a particular service.
The first guard below passes:
if(peripheral.services == nil) {
print("services yet to be discovered \(peripheral.identifier.uuidString)")
return
}
However the second guard below fails:
let serviceOfInterest = peripheral.services?.first(where: {$0.uuid == CBUUID(nsuuid: serviceUUID})
if((serviceOfInterest?.characteristics == nil) || (serviceOfInterest?.characteristics == [])) {
print("characteristics yet to be discovered \(peripheral.identifier.uuidString)")
return
}
First of all, does the iPhone go ahead and discover other characteristics and services separately even when we explicitly mention the service and the characteristics it should discover?
Now if you say yes and that it maybe the reason of our bug because we didn't do a check for serviceOfInterest in didDiscoverCharacteristicsFor callback, then I have another question.
Why don't we get a second/third print in didDiscoverCharacteristicsFor callback signifying that more characteristics were discovered?
The peripheral device just disconnects after a set timeout (peripheral device used in our testing does this if we are not communicating with it for a certain amount of time).
This issue is extremely rare. We have seen it only twice in our customer base. Both the instances were on the same iPhone 15 Pro. Once a few months back and once recently. Currently, this iPhone is having iOS version 18.1.1 running on it.
I developed a iOS App, this App need to visit a local url. It can visit the url on iPhone 13 (iOS 15.4) and iPhone 14 Plus (iOS 16.5.1), but it can not visit the same url on iPhone 6s(iOS 15.8.1).
The error message is 'NSURLErrorDomain Code=-1009'.
1). The url can be visited by Safari on iPhone 6s, so the network of iPhone 6s is fine.
2). The Local Network has enabled in the APP settings.
3). I notice that in iPhone Settings -> WLAN -> Apps Using WLAN & Cellular, my App information can be found on iPhone 13 and iPhone 14 Plus, and can not find my App information on iPhone 6s.
How should I troubleshoot this issue? Thanks you!
Follows are full error message.
2024-02-08 17:49:39.706240+0800 AstroeyeWiFi[1186:114419] Task .<8> finished with error [-1009] Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x280715c20 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_NSURLErrorNWPathKey=unsatisfied (Denied over Wi-Fi interface), interface: en0, _kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<8>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask .<8>"
), NSLocalizedDescription=The Internet connection appears to be offline., NSErrorFailingURLStringKey=http://192.168.0.1:50628/form/getDeviceId, NSErrorFailingURLKey=http://192.168.0.1:50628/form/getDeviceId, _kCFStreamErrorDomainKey=1}
[DNO][getDeviceSysId][Error] underlying(Alamofire.AFError.sessionTaskFailed(error: Error Domain=NSURLErrorDomain Code=-1009 "The Internet connection appears to be offline." UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x280715c20 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_NSURLErrorNWPathKey=unsatisfied (Denied over Wi-Fi interface), interface: en0, _kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask .<8>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask .<8>"
), NSLocalizedDescription=The Internet connection appears to be offline., NSErrorFailingURLStringKey=http://192.168.0.1:50628/form/getDeviceId, NSErrorFailingURLKey=http://192.168.0.1:50628/form/getDeviceId, _kCFStreamErrorDomainKey=1}), nil)
when my iPhone15 pro max upgrade to iOS18.1.1,it can not connect to hotPot of my lot device(os android5.1) any more and my iPhone12(iOS 18.1.1) has no issues.
Both the 15 pro max and the iPhone12 works well with another device (OS android 10.0).
had tried:
1.Forget Network (and re-add your desired Wifi network),
2.Reset Network Settings (under Settings/General/Transfer or Reset iPhone)
3.Turn Airplane Mode On then Off after a few seconds
4.Restart the iPhone.
5.Rest all setting
6.Disable VPN
7.close the the settings from rotating my WiFi address
Did anyone have similar issues?
Our app has a network extension (as I've mentioned lots 😄). We do an upgrade by downloading the new package, stopping & removing all of our components except for the network extension, and then installing the new package, which then loads a LaunchAgent causing the containing app to run. (The only difference between a new install and upgrade is the old extension is left running, but not having anything to tell it what to do, just logs and continues.)
On some (but not all) upgrades... nothing ends up able to communicate via XPC with the Network Extension. My simplest cli program to talk to it gets
Could not create proxy: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named blah was invalidated: failed at lookup with error 3 - No such process." UserInfo={NSDebugDescription=The connection to service named bla was invalidated: failed at lookup with error 3 - No such process.}
Could not communicate with blah
Restarting the extension by doing a kill -9 doesn't fix it; neither does restarting the control daemon. The only solution we've come across so far is rebooting.
I filed FB11086599 about this, but has anyone thoughts about this?
Hello,
As a developer, I'm experiencing a problem with WebSocket connections since upgrading to MacOS 15.0 Sequoia.
When using a JSON RPC API from my workstation using tools such as Postman and/or Docker, I encounter the following problem: At the start of communications, messages received on the WS channel are fine. But after a while (indefinite) the messages become corrupted, truncated or jumbled.
For debugging purposes, I used the WireShark utility to confirm that the problem was not with the server itself. I was thus able to confirm that incoming WebSockets messages are not corrupted, whereas they are when received by Postman and/or Docker.
To confirm my hypothesis that the problem appeared with the latest version of MacOS, we tested on 6 different workstations.
3 MacBook Pro 13” running MacOS 14.6
3 MacBook Pro 13” running MacOS 15.0
The results were clear: the 3 MacOS 14.6 workstations never encountered the problem of corrupted data on the WebSocket channel, whereas the 3 MacOS 15.0 workstations did.
Should you require any further information, please do not hesitate to contact me.
Yours faithfully
Paul BESRET, R&D Engineer.
Topic:
App & System Services
SubTopic:
Networking
On Sequoia it became impossible to properly debug programs using third party mDNS, multicast or broadcast, thanks to a bug? in I guess the new local network privacy feature, every send call returns no route to host.
If I run the CI job, which properly packages, signs, notarizes said program, the resulting .app works fine and also requests permission to access the local network - which is impossible through lldb as it doesn't have an Info.plist, just the ***** binary itself. However this may not be the issue, see the repro method below.
A fast and easy method to reproduce is using an example from this repo: https://github.com/keepsimple1/mdns-sd/
Running the query example in a good old shell without lldb (cargo run --example query _smb._tcp) starts outputting results.
Then running the same binary through lldb (lldb -o run target/debug/examples/query _smb._tcp) would result in no route to host errors. I can't provide an output anymore as I was forced to downgrade. It works fine again on 14.6.1. I'm a bit reluctant to even try 14.7.
Also reported in feedback assistant: FB15185667
I cannot find in the documentation and samples how exactly the Bloom filter is generated.
Is there any code sample for that?
how can I prevent handshake when certificate is user installed
for example if user is using Proxyman or Charles proxy and they install their own certificates
now system is trusting those certificates
I wanna prevent that, and exclude those certificates that are installed by user,
and accept the handshake if CA certificate is in a real valid certificate defined in OS
I know this can be done in android by setting something like
<network-security-config>
<base-config>
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
On macOS 15, if a program installed in /Applications is allowed to connect to a PostgreSQL server on another machine on the local network, a program launched in debug mode from Xcode is not allowed to connect to the local network, and no prompt appears.
Although it is possible to turn off registered programs in Local Network Privacy in Beta 2, permissions for programs launched from Xcode cannot be obtained at all.
Does anyone know how to solve this problem?
I was wondering if anybody knows if it's possible for an app to use a QR code to join a Wi-Fi network - the same functionality as the iOS 11 Camera app?I have some code reading a QR Code that looks something like - "WIFI:S:name-of-network;T:WPA;P:password;;"This QR code works perfectly in the native camera app - asking the user if they'd like to join the Wi-Fi network and successfully joining if they do.When I scan the QR code in my own code, I get the following error: canOpenURL: failed for URL: "WIFI:S:name-of-network;T:WPA;P:password;;" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"In my app, I've got URL Schemes for "prefs" and have added "wifi" in LSApplicationQueriesSchemes.Am I doing something wrong, or is this simply not possible?If it's not possible, is there anyway to use the iOS native camera functionality within an app?
Hi,
We’re seeing our build system (Gradle) get stuck in sendto system calls while trying to communicate with other processes via the local interface over UDP. To the end user it appears that the build is stuck or they will receive an error “Timeout waiting to lock ***. It is currently in use by another Gradle instance”. But when the process is sampled/profiled, we can see one of the threads is stuck in a sendto system call. The only way to resolve the issue is to kill -s KILL <pid> the stuck Gradle process.
A part of the JVM level stack trace:
"jar transforms Thread 12" #90 prio=5 os_prio=31 cpu=0.85ms elapsed=1257.67s tid=0x000000012e6cd400 nid=0x10f03 runnable [0x0000000332f0d000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.DatagramChannelImpl.send0(java.base@17.0.10/Native Method)
at sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(java.base@17.0.10/DatagramChannelImpl.java:901)
at sun.nio.ch.DatagramChannelImpl.send(java.base@17.0.10/DatagramChannelImpl.java:863)
at sun.nio.ch.DatagramChannelImpl.send(java.base@17.0.10/DatagramChannelImpl.java:821)
at sun.nio.ch.DatagramChannelImpl.blockingSend(java.base@17.0.10/DatagramChannelImpl.java:853)
at sun.nio.ch.DatagramSocketAdaptor.send(java.base@17.0.10/DatagramSocketAdaptor.java:218)
at java.net.DatagramSocket.send(java.base@17.0.10/DatagramSocket.java:664)
at org.gradle.cache.internal.locklistener.FileLockCommunicator.pingOwner(FileLockCommunicator.java:61)
at org.gradle.cache.internal.locklistener.DefaultFileLockContentionHandler.maybePingOwner(DefaultFileLockContentionHandler.java:203)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock$1.run(DefaultFileLockManager.java:380)
at org.gradle.internal.io.ExponentialBackoff.retryUntil(ExponentialBackoff.java:72)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock.lockStateRegion(DefaultFileLockManager.java:362)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock.lock(DefaultFileLockManager.java:293)
at org.gradle.cache.internal.DefaultFileLockManager$DefaultFileLock.<init>(DefaultFileLockManager.java:164)
at org.gradle.cache.internal.DefaultFileLockManager.lock(DefaultFileLockManager.java:110)
at org.gradle.cache.internal.LockOnDemandCrossProcessCacheAccess.incrementLockCount(LockOnDemandCrossProcessCacheAccess.java:106)
at org.gradle.cache.internal.LockOnDemandCrossProcessCacheAccess.acquireFileLock(LockOnDemandCrossProcessCacheAccess.java:168)
at org.gradle.cache.internal.CrossProcessSynchronizingCache.put(CrossProcessSynchronizingCache.java:57)
at org.gradle.api.internal.changedetection.state.DefaultFileAccessTimeJournal.setLastAccessTime(DefaultFileAccessTimeJournal.java:85)
at org.gradle.internal.file.impl.SingleDepthFileAccessTracker.markAccessed(SingleDepthFileAccessTracker.java:51)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.markAccessed(DefaultCachedClasspathTransformer.java:209)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.transformFile(DefaultCachedClasspathTransformer.java:194)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.lambda$cachedFile$6(DefaultCachedClasspathTransformer.java:186)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer$$Lambda$368/0x0000007001393a78.call(Unknown Source)
at org.gradle.internal.UncheckedException.unchecked(UncheckedException.java:74)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer.lambda$transformAll$8(DefaultCachedClasspathTransformer.java:233)
at org.gradle.internal.classpath.DefaultCachedClasspathTransformer$$Lambda$372/0x0000007001398470.call(Unknown Source)
at java.util.concurrent.FutureTask.run(java.base@17.0.10/FutureTask.java:264)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@17.0.10/ThreadPoolExecutor.java:1136)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@17.0.10/ThreadPoolExecutor.java:635)
at java.lang.Thread.run(java.base@17.0.10/Thread.java:840)
A part of the process sample:
2097 Thread_3879661: Java: jar transforms Thread 12
+ 2097 thread_start (in libsystem_pthread.dylib) + 8 [0x18c42eb80]
...removed for brevity...
+ 2097 Java_sun_nio_ch_DatagramChannelImpl_send0 (in libnio.dylib) + 84 [0x102ef371c]
+ 2097 __sendto (in libsystem_kernel.dylib) + 8 [0x18c3f612c]
We have observed the following system logs around the time the issue manifests:
2025-08-26 22:03:23.280255+0100 0x3b2c00 Default 0x0 0 0 kernel: cfil_hash_entry_log:6088 <CFIL: Error: sosend_reinject() failed>: [4628 java] <UDP(17) in so 9e934ceda1c13379 50826943645358435 50826943645358435 ag>
2025-08-26 22:03:23.280267+0100 0x3b2c00 Default 0x0 0 0 kernel: cfil_service_inject_queue:4472 CFIL: sosend() failed 22
The issue seems to be rooted in the built-in Application Firewall, as disabling it “fixes” the issue. It doesn’t seem to matter that the process is on the “allow” list.
We’re using Gradle 7.6.4, 8.0.2 and 8.14.1 in various repositories, so the version doesn’t seem to matter, neither does which repo we use.
The most reliable way to reproduce is to run two Gradle builds at the same time or very quickly after each other.
We would really appreciate a fix for this as it really negatively affects the developer experience. I've raised FB19916240 for this.
Many thanks,
We’ve noticed an issue where after running a network extension, if the phone’s language is changed the Locale.preferredLanguages array is not updated and still returns the old array. It only returns the updated array when the app is reinstalled or the phone is restarted. This is unlike the app itself where using the same Locale.preferredLanguages API immediately returns the updated array.
We think this issue is also the cause of notifications that are sent by the network extension being in the previous language as long as the app isn’t reinstalled or the phone is restarted, despite our Localizable file having localised strings for the new language.
Feedback ID: FB20086051
The feedback report includes a sample project with steps on how to reproduce the issue.
We currently supporting proxy app with Tunnel.appEx and PacketTunnelProvider.
Some users report about constant error "The VPN session failed because an internal error occurred." on VPN start (which fails rapidly).
This error occur mostly after user updated app with active VPN.
Rebooting device solves the problem and it doesnt come again, but it is still very frustrating.
I can provide any required info about app setup to solve this issue if you need. Thanks
We have an application which is written in Swift, which activates Transparent Proxy network extension.
Our Transparent Proxy module is a system extension, which is exposing an app proxy provider interface (We are using NETransparentProxyProvider class and in extension’s Info.plist we use com.apple.networkextension.app-proxy key.)
We are using JAMF MDM profile for installing our transparent proxy in customer environment. We are using VPN payload(https://developer.apple.com/documentation/devicemanagement/vpn) for this network system extension.
This payload does not have any field for order.
As per https://developer.apple.com/documentation/devicemanagement/vpn/transparentproxy-data.dictionary documentation there is another payload for TransparentProxy and we could create a Transparent Proxy profile using iMazingProfile Editor.
Noticed that, if we add the Order attribute to the VPN/TransparentProxy payload, while installing the extension, the save to preferences fails with "Error in saving TP configuration in updateOnDemandRule permission denied" error.
Can we use this Order field to ordering the installed Transparent Proxy extension in a machine?
Customer devices will likely have other Transparent Proxy network extensions as well. We want to allow the Customer to control the order in which each Transparent Proxy network extension receives the network traffic.
How can we set the order of the Transparent proxy extension that can be deployed using MDM profile with VPN/TransparentProxy payload?
Attached the TransparentProxy payload profile for the reference.
DGWebProxy_TransparentProxy_iMazing
Topic:
App & System Services
SubTopic:
Networking
Tags:
Network Extension
System Extensions
Device Management
We use as content filter in our app to monitor flows, we gather data about the flow and block flows deemed suspicious.
Our content filter is activated/deactivated by a UI app but the flows are reported via XPC to a separate daemon process for analysis.
As of macOS 15, we are seeing cases where flows are missing or flows are not received at all by the content filter. The behaviour is not consistent, some devices seem to receive flows normally but others don't. It appears Intel devices are much less prone to showing the problem, whereas Arm devices routinely exhibit missing flows.
On macOS 14 or earlier, there is no sign of missing flows.
Testing on earlier beta versions of macOS 15 did not appear to show the problem, however I can't rule out if issue was present but it wasn't spotted.
Experimenting with simple examples of using a content filter (e.g. QNE2FilterMac) does not appear to reproduce the issue.
Questions,
What has changed between macOS 14 and 15 that could be the cause of the lack of flows?
Is our approach to using an app activated content filter reporting to a daemon connected via XPC unsupported?