I upgraded my Mac to Sequoia 15.4.1 an i hat to upgrade XCode to Version 16.3.
I access a MQTT Broker by an sending an
mosquitto_sub
request to the Broker.
Now its no longer possible the request fails
i granted Network permission to my App
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
Howdy,
I've been developing a packet tunnel extension meant to run on iOS and MacOS. For development I'm using xcodegen + xcodebuild to assemble a bunch of swift and rust code together.
I'm moving from direct TUN device management on Mac to shipping a Network Extension (appex). With that move I noticed that on some mac laptops NE fails to start completely, whilst on others everything works fine.
I'm using CODE_SIGN_STYLE: Automatic, Apple IDs are within the same team, all devices are registered as dev devices. Signing dev certificates, managed by xcode.
Some suspicious logs:
(NetworkExtension) [com.apple.networkextension:] Signature check failed: code failed to satisfy specified code requirement(s)
...
(NetworkExtension) [com.apple.networkextension:] Provider is not signed with a Developer ID certificate
What could be the issue? Where those inconsistencies across devices might come from?
I have written an App which extracts data, over WiFi, from an instrument that creates its own WiFi Hotspot.
The instrument provides no internet connection. The iPad version of this App is connects fine and is assigned an IP address by DHCP server running on a MicroChip RN171 wifi module.
iOS assigns an obscure IP address on a completely different subnet. I understand this is iOS' way of "Complaining" that is wasn't assigned an IP address.
Consequently in the case of the iPhone I am forced to manually assign an IP address for the iPhone, the mask and the gateway. Only then is the connection successful.
Anyone know why the iPhone won't talk DHCP to a WiFi module not connected to the internet? Are there perhaps some parameters that I need to adjust on either the iPhone or WiFi module?
We have observed an internet access issue after the device enters idle mode on iOS 26 beta 9. Although the Ivanti Secure Access Client appears connected, users are unable to access any resources (internet or intranet) after unlocking the device from idle. When we check the log socket connection looks not disrupted, packets are tunnelled but no resource access. Split tunnel enabled and proxy PAC configured. This was observed on both iOS and iPadOS 26 beta.
Steps to reproduce:
Connecting to the internet, launching the Ivanti client, locking the device, and then unlocking it after a brief period of idle. The issue occurs when the VPN remains connected but no resources are accessible.
Hello Everyone,
I am currently using macOS 15.5 and XCode 16.4.
I am using the following code to send/receive multicast packets on multicast group ff02::1 and port 49153 using Apple NF's NWConnectionGroup.
import Network
import Foundation
// Creating a mutlicast group endpoint
let multicastIPv6GroupEndpoint: NWEndpoint = NWEndpoint.hostPort(host: NWEndpoint.Host.ipv6(IPv6Address("ff02::1")!), port: NWEndpoint.Port("49153")!)
do {
let multicastGroupDescriptor: NWMulticastGroup = try NWMulticastGroup (for: [multicastIPv6GroupEndpoint])
let multicastConnectionGroupDescriptor = NWConnectionGroup (with: multicastGroupDescriptor, using: .udp)
multicastConnectionGroupDescriptor.stateUpdateHandler = { state in
print ("🕰️ Connection Group state: \(state)")
if state == .ready {
multicastConnectionGroupDescriptor.send (content: "👋🏻 Hello from the Mac 💻".data (using: .utf8)) { err in
print ("➡️ Now, I am trying to send some messages.")
if let err = err {
print ("💥 Error sending multicast message: \(err)")
} else {
print ("🌚 Initial multicast message sent")
}
}
}
}
multicastConnectionGroupDescriptor.setReceiveHandler { message, content, isComplete in
if let content = content, let messageString = String (data: content, encoding: .utf8) {
print ("⬅️ Received message: \(messageString)")
}
}
multicastConnectionGroupDescriptor.start (queue: .global())
} catch {
print ("💥 Error while creating Multicast Group: \(error)")
}
RunLoop.main.run()
I am able to successfully create a NWConnectionGroup without any warnings/errors.
The issue occurs when the stateUpdateHandler's callback gets invoked.
It first gives me this warning:
nw_listener_socket_inbox_create_socket IPV6_LEAVE_GROUP ff02::1.49153 failed [49: Can't assign requested address
But then it shows me that the state is ready:
🕰️ Connection Group state: ready
After this, when the send is performed, it gives me a bunch of errros:
nw_endpoint_flow_failed_with_error [C1 ff02::1.49153 waiting parent-flow (unsatisfied (Local network prohibited), interface: en0[802.11], ipv4, ipv6, uses wifi)] already failing, returning
nw_socket_connect [C1:1] connectx(7, [srcif=0, srcaddr=::.62838, dstaddr=ff02::1.49153], SAE_ASSOCID_ANY, 0, NULL, 0, NULL, SAE_CONNID_ANY) failed: [48: Address already in use]
nw_socket_connect [C1:1] connectx failed (fd 7) [48: Address already in use]
nw_socket_connect connectx failed [48: Address already in use]
nw_endpoint_flow_failed_with_error [C1 ff02::1.49153 in_progress socket-flow (satisfied (Path is satisfied), interface: en0[802.11], ipv4, ipv6, dns, uses wifi)] already failing, returning
There is no other background process running on the same port. I tried using different ports as well as multicast groups but the same error persists.
The same code works fine for an IPv4 multicast group.
I have following questions:
Why am I getting these errors specifically for IPv6 multicast group but not for IPv4 multicast group?
Are there any configurations that needed to be done in order to get this working?
I have a custom VPN app that uses NETunnelProviderManager to install a VPN Profile if one is not already installed. On previous iOS versions this would open the VPN Settings and ask for either the PIN, FaceID or TouchID and install the profile. With iOS 26 beta5 it opens the VPN Settings and stops.
Is this a bug in iOS 26? Have there been changes to NETunnelProviderManager for iOS 26 that I'm not aware of?
FYI we do the samething on macOS 26 beta5 and that works as expected.
Hi! My project has the Local Push Connectivity entitlement for a feature we have requiring us to send low-latency critical notifications over a local, private Wi-Fi network.
We have our NEAppPushProvider creating a SSE connection using the Network framework with our hardware running a server. The server sends a keep-alive message every second. On an iPhone 16 with iOS 18+, the connection is reliable and remains stable for hours, regardless of whether the iOS app is in the foreground, background, or killed.
One of our QA engineers has been testing on an iPhone 13 running iOS 16, and has notice shortly after locking the phone, specifically when not connected to power the device seems to turn off the Wi-Fi radio. So when the server sends a notification, it is not received. About 30s later, it seems to be back on. This happens on regular intervals.
When looking at our log data, the provider does seem to be getting stopped, then restarted shortly after. The reason code is NEProviderStopReasonNoNetworkAvailable, which further validates that the network is getting dropped by the device in regular intervals.
My questions are:
Were there possibly silent changes to the framework between iOS versions that could be the reason we're seeing inconsistent behavior?
Is there a connection type we could use, instead of SSE, that would prevent the device from disconnecting and reconnecting to the Wi-Fi network?
Is there an alternative approach to allow us to maintain a persistent network connection with the extension or app?
Topic:
App & System Services
SubTopic:
Networking
Tags:
Extensions
Network
User Notifications
Network Extension
I filed FB19631435 about this just now. Basically: starting with 15.6, we've had reports (internally and outternally) that after some period of time, networking fails so badly that it can't even acquire a DHCP lease, and the system needs to be rebooted to fix this. The systems in question all have at least 2 VPN applications installed; ours is a transparent proxy provider, and the affected system also had Crowdstrike's Falcon installed. A customer system reported seemingly identical failures on their systems; they don't have Crowdstrike, but they do have Cyberhaven's.
Has anyone else seen somethng like this? Since it seems to involve three different networking extensions, I'm assuming it's due to an interaction between them, not a bug in any individual one. But what do I know? 😄
Hello eveybody,Currently I'm working on an app which connects to a device. During testing I encounter an internal error of NEHotspotConfigurationErrorDomain. See the log snippet:Domain=NEHotspotConfigurationErrorDomain Code=8 "internal error." UserInfo={NSLocalizedDescription=internal error.}This error appears randomly. In one day I encountered it three times. The only solution I can think of is catching this error somehow and then telling the user to restart the device.After this error appears, the wifi functionality of iOS in all third party apps seems to be broken. Only restarting helps as far as I know. Also there seems to be nothing we as app developers can do about it. Therefor I wonder if there is some way to prevent this error somehow? The only solution I can think of is catching this error somehow and then telling the user to restart the device.Also since there is not much information about this error on the web, it would be really nice if someone can clarify whats going on with this error.Regards.
Greetings,
I would like to understand this URLCache behavior for two different requests to the same end point but with a different header value. Here is a code with comment explaining the behavior.
// Create a request to for a url.
let url = URL(string: "https://<my url>?f=json")!
var request = URLRequest(url: url)
// Set custom header with a value.
request.setValue("myvalue", forHTTPHeaderField: "CustomField")
// Send request to get the response.
let (data, response) = try await URLSession.shared.data(for: request)
print("data: \(String(describing: String(data: data, encoding: .utf8)))")
print("response: \(response)")
// Create second request to the same url but with different value of custom header field.
var request2 = URLRequest(url: url)
request2.setValue("newvalue", forHTTPHeaderField: "CustomField")
// Check the URL cache for second request and it returns the response
// of the first request even though the second request has different header value.
let cachedResponse = URLCache.shared.cachedResponse(for: request2)
print("cachedResponse: \(cachedResponse?.response)")
Is this a bug in URLCache that request headers are not matched while returning the response?
Is this an expected behavior? If yes, why?
we use the api as
NEHotspotConfigurationManager.shared.apply(hotspotConfig)
to join a wifi, but we find that in in iphone 17+, some user report the time to join wifi is very slow
the full code as
let hotspotConfig = NEHotspotConfiguration(ssid: sSSID, passphrase: sPassword, isWEP: false)
hotspotConfig.joinOnce = bJoinOnce
if #available(iOS 13.0, *) {
hotspotConfig.hidden = true
}
NEHotspotConfigurationManager.shared.apply(hotspotConfig) { [weak self] (error) in
guard let self else {
return
}
if let error = error {
log.i("connectSSID Error while configuring WiFi: \(error.localizedDescription)")
if error.localizedDescription.contains("already associated") {
log.i("connectSSID Already connected to this WiFi.")
result(["status": 0])
} else {
result(["status": 0])
}
} else {
log.i("connectSSID Successfully connected to WiFi network \(sSSID)")
result(["status": 1])
}
}
Normally it might only take 5-10 seconds, but on the iPhone 17+ it might take 20-30 seconds.
I'm working on two Swift applications which are using QUIC in Network.framework for communication, one serve as the listener (server) and the other serve as the client so that they can exchange data, both the server and the client app are running under the same LAN, the problem I met is that when client try to connect to the server, the connection will fail due to boring SSL, couple questions:
Since both the server app and client app are running under the same LAN, do they need TLS certificate?
If it does, will self-signed certificate P12 work? I might distribute the app in App Store or in signed/notarized dmg or pkg to our users.
If I need a public certificate and self signed wouldn't work, since they are just pair of apps w/o fixed dns domain etc, Is there any public certificate only for standalone application, not for the fixed web domain?
I'm trying to use ThreadNetwork API to manage TheradNetworks on device (following this documentation: https://developer.apple.com/documentation/threadnetwork/), but while some functions on THClient work (such as getPreferedNetwork), most don't (storeCredentials, retrieveAllCredentials). When calling these functions I get the following warning/error:
Client: -[THClient getConnectionEntitlementValidity]_block_invoke - Error:
-[THClient storeCredentialsForBorderAgent:activeOperationalDataSet:completion:]_block_invoke:701: - Error: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service with pid 414 named com.apple.ThreadNetwork.xpc was invalidated from this process." UserInfo={NSDebugDescription=The connection to service with pid 414 named com.apple.ThreadNetwork.xpc was invalidated from this process.}
Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service with pid 414 named com.apple.ThreadNetwork.xpc was invalidated from this process." UserInfo={NSDebugDescription=The connection to service with pid 414 named com.apple.ThreadNetwork.xpc was invalidated from this process.}
Failed to store Thread credentials: Couldn’t communicate with a helper application.
STEPS TO REPRODUCE
Create new project
Add Thread Network capability via Xcode UI (com.apple.developer.networking.manage-thread-network-credentials)
Trigger storeCredentials
let extendedMacData = "9483C451DC3E".hexadecimal
let tlvHex = "0e080000000000010000000300001035060004001fffe002083c66f0dc9ef53f1c0708fdb360c72874da9905104094dce45388fd3d3426e992cbf0697b030d474c2d5332302d6e65773030310102250b04106c9f919a4da9b213764fc83f849381080c0402a0f7f8".hexadecimal
// Initialize the THClient
let thClient = THClient()
// Store the credentials
await thClient.storeCredentials(forBorderAgent: extendedMacData!, activeOperationalDataSet: tlvHex!) { error in
if let error = error {
print(error)
print("Failed to store Thread credentials: \(error.localizedDescription)")
} else {
print("Successfully stored Thread credentials")
}
}
NOTES:
I tried with first calling getPreferedNetwork to initiate network permission dialog
Tried adding meshcop to bojur services
Tried with different release and debug build configurations
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?
Our application has initiated an NSURLSession data task, and we have received an initiation ID. However, Application not received callback on the subsequent activity: the task has not been requested, has not timed out, and no error callback has been received.
[06/17 09:29:40:559][ 0x282a7d8c0] Requested TaskIdentifier 120
2025-06-17 09:29:40.623337 +0530 nsurlsessiond SUBMITTING: com.apple.CFNetwork-cc-166-373-Task .<120>:A71666 default
2025-06-17 09:29:40.631280 +0530 dasd Submitted Activity: com.apple.CFNetwork-cc-166-373-Task .<120>:A71666 at priority 10 default
Seen couple of rejection with for CPUUsagePolicy and MemoryPressurePolicy
2025-06-17 09:29:40.989360 +0530 dasd com.apple.CFNetwork-cc-166-373-Task .<120>:A71666:[
{name: CPUUsagePolicy, policyWeight: 5.000, response: {Decision: Must Not Proceed, Score: 0.00, Rationale: [{[Max allowed CPU Usage level]: Required:90.00, Observed:95.00},]}}
{name: MemoryPressurePolicy, policyWeight: 5.000, response: {Decision: Must Not Proceed, Score: 0.00, Rationale: [{[memoryPressure]: Required:1.00, Observed:2.00},]}}
], FinalDecision: Must Not Proceed} default
2025-06-17 10:55:22.500277 +0530 dasd com.apple.CFNetwork-cc-166-373-Task .<120>:A71666:[
{name: MemoryPressurePolicy, policyWeight: 5.000, response: {Decision: Must Not Proceed, Score: 0.00, Rationale: [{[memoryPressure]: Required:1.00, Observed:2.00},]}}
], FinalDecision: Must Not Proceed} default
And more an hour later then it throws with an error BUT NEVER indicated the same to client
2025-06-17 10:55:27.426549 +0530 WAVE PTX Task .<120> is for <>.<>.<120> default
2025-06-17 10:55:27.776951 +0530 nsurlsessiond Task .<120> summary for task failure {transaction_duration_ms=5147145, response_status=-1, connection=0, reused=1, request_start_ms=0, request_duration_ms=0, response_start_ms=0, response_duration_ms=0, request_bytes=0, response_bytes=0, cache_hit=false} default
2025-06-17 10:55:27.777096 +0530 nsurlsessiond NDSession <714296D7-20F9-4A0A-8C31-71FB67F39A56> Task .<120> for client will be retried after error Error Domain=_nsurlsessiondErrorDomain Code=6 UserInfo={NSErrorFailingURLStringKey=, NSErrorFailingURLKey=, _NSURLErrorRelatedURLSessionTaskErrorKey=, _NSURLErrorFailingURLSessionTaskErrorKey=} - code: 6 default
Then It got resumed and says successful but never got any callback on the same to client
2025-06-17 10:55:28.877245 +0530 nsurlsessiond NDSession <714296D7-20F9-4A0A-8C31-71FB67F39A56> Task .<120> resuming default
2025-06-17 10:55:55.225456 +0530 nsurlsessiond Task .<120> received response, status 401 content K default
2025-06-17 10:55:55.250371 +0530 nsurlsessiond Task .<120> finished successfully default
Please refer feedback for diagnose logs:
https://feedbackassistant.apple.com/feedback/18173303
We are developing an iOS application that is interacting with HTTP APIs that requires us to put a unique UUID (a nonce) as an header on every request (obviously there's more than that, but that's irrilevant to the question here).
If the same nonce is sent on two subsequent requests the server returns a 412 error. We should avoid generating this kind of errors as, if repeated, they may be flagged as a malicious activity by the HTTP APIs.
We are using URLSession.shared.dataTaskPublisher(for: request) to call the HTTP APIs with request being generated with the unique nonce as an header.
On our field tests we are seeing a few cases of the same HTTP request (same nonce) being repeated a few seconds on after the other.
Our code has some retry logic only on 401 errors, but that involves a token refresh, and this is not what we are seeing from logs.
We were able to replicate this behaviour on our own device using Network Link Conditioner with very bad performance, with XCode's Network inspector attached we can be certain that two HTTP requests with identical headers are actually made automatically, the first request has an "End Reason" of "Retry", the second is "Success" with Status 412.
Our questions are:
can we disable this behaviour?
can we provide a new request for the retry (so that we can update headers)?
Thanks,
Francesco
When the machine connects to the network cable through the Thunderbolt interface using the docking station, if the Network Extension shown in the following code is running at this time, after unplugging and reinserting the docking station, the machine will not be able to obtain a valid IP address through DHCP until the system is restarted.
@interface MyTransparentProxyProvider : NETransparentProxyProvider
@end
@implementation MyTransparentProxyProvider
- (void)startProxyWithOptions:(NSDictionary *)options completionHandler:(void (^)(NSError *))completionHandler
{
NETransparentProxyNetworkSettings *objSettings = [[NETransparentProxyNetworkSettings alloc] initWithTunnelRemoteAddress:@"127.0.0.1"];
// included rules
NENetworkRule *objIncludedNetworkRule = [[NENetworkRule alloc] initWithRemoteNetwork:nil
remotePrefix:0
localNetwork:nil
localPrefix:0
protocol:NENetworkRuleProtocolAny
direction:NETrafficDirectionOutbound];
NSMutableArray<NENetworkRule *> *arrIncludedNetworkRules = [NSMutableArray array];
[arrIncludedNetworkRules addObject:objIncludedNetworkRule];
objSettings.includedNetworkRules = arrIncludedNetworkRules;
// apply
[self setTunnelNetworkSettings:objSettings completionHandler:
^(NSError * _Nullable error)
{
// TODO
}
];
if (completionHandler != nil)
completionHandler(nil);
}
- (BOOL)handleNewFlow:(NEAppProxyFlow *)flow
{
return NO;
}
@end
This problem will not occur if the IP of the DNS server or all UDP ports 53 are excluded in the Network Extension.
@interface MyTransparentProxyProvider : NETransparentProxyProvider
@end
@implementation MyTransparentProxyProvider
- (void)startProxyWithOptions:(NSDictionary *)options completionHandler:(void (^)(NSError *))completionHandler
{
NETransparentProxyNetworkSettings *objSettings = [[NETransparentProxyNetworkSettings alloc] initWithTunnelRemoteAddress:@"127.0.0.1"];
// included rules
NENetworkRule *objIncludedNetworkRule = [[NENetworkRule alloc] initWithRemoteNetwork:nil
remotePrefix:0
localNetwork:nil
localPrefix:0
protocol:NENetworkRuleProtocolAny
direction:NETrafficDirectionOutbound];
NSMutableArray<NENetworkRule *> *arrIncludedNetworkRules = [NSMutableArray array];
[arrIncludedNetworkRules addObject:objIncludedNetworkRule];
// excluded rules
NENetworkRule *objExcludedNetworkRule = [[NENetworkRule alloc] initWithRemoteNetwork:[NWHostEndpoint endpointWithHostname:@"" port:@(53).stringValue]
remotePrefix:0
localNetwork:nil
localPrefix:0
protocol:NENetworkRuleProtocolUDP
direction:NETrafficDirectionOutbound];
NSMutableArray<NENetworkRule *> *arrExcludedNetworkRules = [NSMutableArray array];
[arrExcludedNetworkRules addObject:objExcludedNetworkRule];
objSettings.includedNetworkRules = arrIncludedNetworkRules;
objSettings.excludedNetworkRules = arrExcludedNetworkRules;
// apply
[self setTunnelNetworkSettings:objSettings completionHandler:
^(NSError * _Nullable error)
{
// TODO
}
];
if (completionHandler != nil)
completionHandler(nil);
}
- (BOOL)handleNewFlow:(NEAppProxyFlow *)flow
{
return NO;
}
@end
Is MyTransparentProxyProvider in what place do wrong? To handle the connection on port 53, it is necessary to add the implementation of NEDNSProxyProvider?
In -[MyTransparentProxyProvider handleNewFlow:] how to reverse DNS? getnameinfo() doesn't work, it returns EAI_NONAME.
When I try to implement the new Background Task options in the same way as they show in the WWDC video (on watchOS) likes this:
let config = URLSessionConfiguration.background(withIdentifier: "SESSION_ID")
config.sessionSendsLaunchEvents = true
let session = URLSession(configuration: config)
let response = await withTaskCancellationHandler {
try? await session.data(for: request)
} onCancel: {
let task = session.downloadTask(with: request))
task.resume()
}
I'm receiving the following error:
Terminating app due to uncaught exception 'NSGenericException', reason: 'Completion handler blocks are not supported in background sessions. Use a delegate instead.'
Did I forget something?
(iOS 17.3)
I'm using the Apple supplied iOS sample project "ConfiguringAWiFiAccessoryToJoinTheUsersNetwork" as a base to write an App to configure an existing WiFi device using the NEHotspotConfiguration API's. I have almost everything working, and can join the network and send a packet to the device to configure it. I know that it is working as the device responds properly to what I send it. But I am not able to receive the response back from the device to the packet sent. (Only need 1 packet sent and 1 packet received)
However. If I run a packet sniffer on the phone before running my test App, then I do get a response. No packet sniffer running, no response.
When I do a debugDescription on the NWConnection after it reaches ".ready", I notice that when the sniffer is running I'm using loopback lo0:
[C1 connected 192.168.4.1:80 tcp, url: http://192.168.4.1:80, attribution: developer, path satisfied (Path is satisfied), viable, interface: lo0]
and I get a packet response in the NWConnection receiveMessage callback.
But with no sniffer running, I get interface en0:
[C1 connected 192.168.4.1:80 tcp, url: http://192.168.4.1:80, attribution: developer, path satisfied (Path is satisfied), viable, interface: en0[802.11], ipv4, dns, uses wifi]
and there is no callback to the receiveMessage handler and the NWconnection eventually times out.
The interface used seems to be the only difference that I can see when I have a sniffer running. Any ideas as to why I can't see a response in "normal" operation?
For years our iOS apps have experienced a networking problem, which blocks them connecting to our servers via their API endpoint domains.
How can we recover after the scenario described below?
Using 3rd party error logging solutions, which have different endpoint domains, we can record the error:
NSUnderlyingError": Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, _kCFNetworkCFStreamSSLErrorOriginalValue=-9816, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9816, _NSURLErrorNWPathKey=satisfied (Path is satisfied), viable, interface: pdp_ip0[lte], ipv4, dns, expensive, uses cell}, "_NSURLErrorFailingURLSessionTaskErrorKey": LocalDataTask <DEDBFA4D-810D-4438-A6A0-95E3B9668B9E>.<308>, "_kCFStreamErrorDomainKey": 3, "_NSURLErrorRelatedURLSessionTaskErrorKey": <__NSSingleObjectArrayI 0x301f82e60>(
LocalDataTask <DEDBFA4D-810D-4438-A6A0-95E3B9668B9E>.<308>
)
"NSLocalizedDescription": An SSL error has occurred and a secure connection to the server cannot be made., "NSLocalizedRecoverySuggestion": Would you like to connect to the server anyway?
-9816 is the "server closed session with no notification" error based on comments in CoreFoundation source files. Subsequent API endpoint calls to the same domain return the same error.
The SSL error occurs most prevalently after a server outage. However, despite our best efforts, we have been unable to replicate triggering the problem for development purposes via experiments with our server.
When the error occurs the users report that:
Fully closing (i.e. not just sending to background) and reopening the app does NOT clear connectivity to our server being blocked.
Problem seems more prevalent when using mobile/cell data.
Switching from mobile/cell data to WIFI resolves the connection problem and then switching back to mobile/cell data shows the problem again. So the underlying problem is not cleared.
All other apps on the same device and mobile/cell data or WIFI connection, like Safari, have no problems connecting to the Internet.
Deleting and reinstalling, or updating (when an update is available) resolves the problem.
Or after waiting a few days the problem seems to resolve itself.
The last two point above suggest that something is persisted/cached in the app preventing it from connecting properly with subsequent network attempts.
Notes:
We have one shared instance of the URLSession in the app for its networking because we are aware of the perils of multiple URLSession instances.
We recently added conditions to call the URLSession await reset() method when detecting the SLL errors before repeating the request. It is debatable whether this reduces the problem as we still see logged cases with the subsequent requests hitting the same -9816 error.
URLSession configuration:
let config = URLSessionConfiguration.default
config.timeoutIntervalForResource = 22
config.timeoutIntervalForRequest = 20
config.requestCachePolicy = .reloadIgnoringLocalCacheData
config.urlCache = nil