I have a network call that can sometimes take longer than 30 seconds and user might sometimes background the app after waiting a bit (think like a image generation done on a server which takes a while). I want to make sure that I have exhausted all the options available to provide the best possible solution for the user
(1) Use beginBackgroundTask. The downside to this is that I'm only given about 30 seconds or so, and if it takes longer, the call just get killed.
(2) Use URLSessionConfiguration.background. The upside is that this can take as long as it needs but it seems to be delegated to the system, and you never know when it will run? What if the user stays in the foreground and now the user will not know when the call will even begin (determined by the OS)
(3) Use BGProcessingTask. Again problem is that we cant control when the task is run (which in this case we want it to be immediately).
So really none of the options really is ideal. Are there other options?
What I would like ideally is
The call should start immediately upon user request
The call should go on indefinitely when the app stays in foreground
The call should go on for an extended period (like 2 minutes) if the user puts the app in background
If the call is completed in the background, have a way for the app to retrieve the result when the user brings the app back in the foreground
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.
Post
Replies
Boosts
Views
Activity
I am building a NEPacketTunnelProvider, and in its configuration I set a SecIdentity persistent reference. That reference is passed to the tunnel provider but when I try to use it there, I get an errSecInteractionNotAllowed error. The private key for that identity is protected by .userPresence. If I remove the protection, the network extension can access the identity and the private key.
Is there any way that a VPN network extension can use a keychain item protected by .userPresence?
The documentation for the defaultPath property of NEProvider is as follows:
This NWPath object contains information about which physical network interface will be used by connections opened by the Network Extension provider. You can determine when this physical interface changes by observing this property using KVO.
However, I have noticed that it is deprecated as of iOS 18.
Is there any existing replacement for this functionality since it has been deprecated, or is a new replacement on the horizon? This is very useful for network extensions in order to detect changes to the network, for instance when moving from WiFi to mobile data.
Hello ,
I have obtained three strings from the server: ca (the root certificate), cert (the client certificate), and privateKey (the private key) for authentication between the iOS client and server. I have successfully used ca for server authentication.
However, I am having trouble generating an NSURLCredential from the cert and privateKey strings for client authentication. Can anyone guide me on how to convert these strings into an NSURLCredential? Any example code would be greatly appreciated!
Thank you for your help!
最近服务器做了防重放功能,发现iOS有很多命中重放错误,因为我们的请求使用了UUID签名,排除了算法问题
经过排查发现iOS在请求过程中,如果网络发生变化,例如开启和断开vpn,或者开启和关闭WIFI,就会导致系统把正在进行的请求多次重放,这会导致从App的感知来看,请求和响应都只调用了一次,但是服务端却收到了多次
具体操作步骤:
1、开启抓包工具,例如wireshark
2、使用demo代码发送请求(先开启慢速网络,不然速度太快来不及操作):
3、不等请求完成,关闭wifi,这时会切换到蜂窝数据
4、等待请求完成后,通过日志可以看出请求的发送和响应都只进行了一次,但是抓包工具可以看到请求被发送了2次
demo如下:
// Create a URLSession with the default configuration
NSURLSession *defaultSession = [NSURLSession sharedSession];
// Setup the request to the URL
NSTimeInterval ms = [NSDate.date timeIntervalSinceReferenceDate] * 1000;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://static.fusionbank.com/resource/20240930/8f54352194ac8beecbd5d3f5842b27bb.png?_t=%f",ms]];
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
urlRequest.timeoutInterval = 20;
// Create dataTask
NSLog(@"--- request start");
dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"--- request finish %@", [error localizedDescription]);
// Handle your response here
[self.loadingView stopAnimating];
if (data) {
UIImage* img = [UIImage imageWithData:data];
self.imageView.image = img;
}
});
}];
// Fire the request
[dataTask resume];
日志如下:
111.log
抓包工具显示请求发了2次:
请求和响应情况:
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!
Our app is developed for iOS, but some users also run it on macOS (as an iOS app via Apple Silicon). The app requires local network permission, which works perfectly on iOS. Previously, the connection also worked fine on macOS, but since the recent macOS update, the app can no longer connect to our device.
Additionally, our app on macOS doesn't prompt for local network permission at all, whereas it does on iOS. Is this a known issue with iOS apps running on macOS? Has anyone else experienced this problem, or is there a workaround?
Any help would be appreciated!
Hey all
so I’m just looking to normalize my ifconfig loadout. Essentially I have many interfaces and as many as 25-50 interfaces on my device.
special clauses:
-i may not factory reset the device including all data because AppleID phone number and password have been lost
-i have access to blink shell for a llimited number of days
-I have had permission denied in every way accessing the device via other shells and have no desire to do this via SSH ; simply put i think that if my phone is set up like this; THERE MUST be SOME way to get these interfaces flags down AT LEAST. And possibly in theory I should be able to even UNINSTALL these many, many interfaces!!
reaching out here seems to be the brightest idea, because of the scope of this task
i realize I am not a fully stacked developer and have some desire to be one but realistically I wont be one
so hopefully my task is clear
-remove interfaces from ifconfig -a ‘s list of enummerated network interfaces. Even flags down will do.
thank you for not deleting my thread please move it if possible I do have a copy
My company has a server that supports ticket-based TLS session resumption (per RFC 5077).
We have done Wireshark captures that show that our iOS client app, which uses URLSession for REST and WebSocket connections to the server, is not sending the TLS "session_ticket" extension in the Client Hello package that necessary to enable ticket-based resumption with the server.
Is it expected that URLSession does not support ticket-based TLS session resumption?
If "yes", is there any way to tell URLSession to enable ticket-based session resumption? the lower-level API set_protocol_options_set_tls_tickets_enabled() hints that the overall TLS / HTTP stack on IOS does support ticket-based resumption, but I can't see how to use that low-level API with URLSession.
I can provide (lots) more technical details if necessary, but hopefully this is enough context to determine whether ticket-based TLS resumption is supported with URLSession.
Any tips / clarifications would be greatly appreciated.
I'm coding resumable uploads using iOS 17's URLSession's uploadTask(withResumeData:. This function returns a non-Optional URLSessionUploadTask and does not throw. In cases where the system determines the resumeData is no longer valid, how do I detect that (so I can create a new URLSessionUploadTask from scratch)?
I'm doing this for background uploads, so it's all URLSessionDelegate apis, but what are the failure modes, and what Error types and Codes would we get specially?
Obviously, I expect the resume data is no longer usable or necessary when get a server success i.e. in the 2xx range. Does the resume data also become invalid for other server responses, like 4xx's? or 5xx's?.
I expect the resume data usually shouldn't become invalid when getting URLError's like .networkConnectionLost, since that's like half the point of having the feature in the first place, to resume after the a broken network connection. But I do expect that if the resumeData is invalid, then I should be able to reach the server and get a server response, so in that case what Code would we get?
I'm assuming the system is caching our upload file somewhere, and the resume data somehow makes a reference to it, so does that file get optimized away at some point in time when left untouched, and need us to start a fresh upload? We are also saving the file for potential future re-uploads, until we get certain assurances of completion from our backend, but I am just wondering on which logic branches I need to determine that the resumeData I thought I could use is no longer usable.
I want to connect my iOS App with a MQTT Server via a Kotlin Multiplatform XCFramework.
This Framework uses the library KMQTT to connect to our MQTT Server. As you can see Here KMQTT uses the default POSIX commands to connect to a socket. This setup works great on Android, not so much for iOS:
When connecting to a IPv6 Address iOS devices get the POSIX Error 47, this was "fixed" by only using IPv4
more importantly: On ~50% of devices, when connecting to the socket they get the POSIX Error 1 (EPERM). The devices are iPhone 13, 14 Pro and a 15 and they all use either iOS 17 or iOS 18. When trying to open the ip via Safari they can connect. This problem seems to come from the Provider, as when i open a Hotspot from a device that doesn't work, all connected iOS Devices also don't work and when another device that works opens a hotspot and the not-working device connects to it, this device works.
Do you guys have any idea, why this error is thrown?
macOS 15 has added a new "Local Network" permission under Security & Privacy.
I had a bug in my app that led to a crash when the user denied this permission. Now I've fixed it and would like to verify that it all works fine.
The problem is: I need to remove my app from the settings so that macOS will show the prompt again (e.g. to verify that my custom message appears correctly).
Usually, sudo tccutil reset All would do the trick. But not for this permission! The apps do not get cleared with this command.
So, there's two issues:
tccutil should remove it but doesn't.
How can I remove this settings?
Update
I had a look at the "TCC.db" (see https://www.rainforestqa.com/blog/macos-tcc-db-deep-dive), and it seems to me that the Local Network permission isn't even managed by the TCC system, as it doesn't appear in it. This is odd.
I have a macOS app with Network Extension. It requests VPN permission with the code like this:
self.tunnelManager = [NETunnelProviderManager new];
NETunnelProviderProtocol *protocol = [NETunnelProviderProtocol new];
protocol.providerBundleIdentifier = @"com.myapp.macos.tunnelprovider";
self.tunnelManager.protocolConfiguration = protocol;
[self.tunnelManager setOnDemandRules:nil];
[self.tunnelManager setOnDemandEnabled:NO];
[self.tunnelManager setEnabled:YES];
[self.tunnelManager saveToPreferencesWithCompletionHandler:^(NSError * _Nullable saveError) {}];
A lot of my app users are businesses and they would like to have pre-install VPN config. We currently do it like this:
<array>
<dict>
<key>PayloadDisplayName</key>
<string>MyAppName</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>UserDefinedName</key>
<string>MyAppName</string>
<key>VPN</key>
<dict>
<key>AuthenticationMethod</key>
<string>Password</string>
<key>ProviderBundleIdentifier</key>
<string>com.myapp.macos.tunnelprovider</string>
<key>ProviderDesignatedRequirement</key>
<string>anchor apple generic and identifier "com.myapp.macos.tunnelprovider" and (certificate leaf[field.1.2.3] /* exists */ or certificate 1[field.1.2.3] /* exists */ and certificate leaf[field.1.2.3] /* exists */ and certificate leaf[subject.OU] = "123")</string>
<key>RemoteAddress</key>
<string/>
</dict>
<key>VPNSubType</key>
<string>com.myapp.macos</string>
<key>VPNType</key>
<string>VPN</string>
</dict>
</array>
Now, if the users installs my app first and allows the VPN permission, then MDM will set the profile above to the user, the user will end up with two VPN profiles in settings. They will be called "My App" and "My App 1"
At first we thought it's harmless, but users with two VPN profiles sometimes have app update issues, where after update the newer version of client fails to communicate with the older version of tunnel, it cannot even tell it to quit. The tunnel must be force-quit by the user in this case.
We suspect two profiles to be the reason for that. Is there a way to make sure duplicate VPN profiles do not happen?
Hello, I have a question about sending data in QUIC DATAGRAM.
Regarding sending data in QUIC DATAGRAM, when I create a NWConnectionGroup and then use the send method of that group to send data in sequence, quite often I get an Optional(POSIXErrorCode(rawValue: 89): Operation canceled) error.
A little Thread.sleep between sends improves the situation somewhat, but the above error still occurs.
Also, since I want to send the frame data of the video in this communication process, adding a wait will drastically reduce performance and make the speed impractical.
However, if send is executed continuously without adding weights, the above error will occur 80% of the time or more.
Is it necessary to send while monitoring some status when sending?
In communication using QUIC Stream, when connecting to the server with NWConnection and sending with its send method, the above error does not occur even if send is executed without wait, and data can be transferred with good performance.
I am trying to use DATAGRAM communication to further increase throughput, but I am not having much success, and there is not much information on DATAGRAM communication.
Thank you in advance for your help.
I'm trying to troubleshoot what is going on with my app. The app works just fine when the user is logged in. It's able to post data to my REST API just fine. But when the app goes in to the background, the BGAppRefreshTask fires off just fine, but it's unable to post its data. There payload is super small a two keys and two short strings and thats it.
I've tried searching on kCFStreamErrorCodeKey -2103 and ErrorDomainKey 4 but not much comes up.
Here is my error with the URL string altered...
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_kCFStreamErrorCodeKey=-2103, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <3126EFA1-00D3-4423-A31B-D40AB900292D>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <3126EFA1-00D3-4423-A31B-D40AB900292D>.<1>" ), NSLocalizedDescription=The request timed out., NSErrorFailingURLStringKey=https://my.example.com/myapi/v1/device, NSErrorFailingURLKey=https://my.example.com/myapi/v1/device, _kCFStreamErrorDomainKey=4}
There is a problem with the Apple local network setting api, iOS18 system, you turn off the local network permissions of the APP, uninstall the APP, and then re-install, the local network permissions even if opened, there is no effect, only restart the phone is useful
We are developing an iOS app and are using Firebase's Auth module. During IPv6 network testing, we found that the app fails when calling Apple's login authorization in an IPv6 environment.
After investigation, we confirmed that the following two API calls:
https://gateway.icloud.com.cn:443/ckdatabase/api/client/record/save
https://gsa.apple.com/grandslam/GsService2
remain in a pending state.
We tested gateway.icloud.com.cn and gsa.apple.com and found that these two domains do not support IPv6 DNS.
What we would like to understand is whether these two domains truly do not support IPv6 DNS, and how we can implement Apple's login authorization in an IPv6 environment.
I have two applications (MinimServer and MinimWatch) that run on macOS. Both use the local network.
On Sequoia, starting MinimWatch for the very first time after installing Sequoia shows a prompt for permission to access the local network. If the user agrees, an enabled entry for MinimWatch appears in the Privacy &amp;amp; Security &amp;gt; Local Network section as expected.
If MinimServer is then started for the very first time, there is no prompt and the existing Local Network entry for MinimWatch now controls local network access for both MinimWatch and MinimServer.
If ths above order is reversed (start MinimServer first after installing Sequoia and then start MinimWatch), Local Network shows a single entry for MinimServer which controls network access for both MinimServer and MinimWatch.
It appears there is a false positive match when the second application is started. Sequoia finds the Local Network entry for the first application and incorrectly idenfies this as matching the second application.
Both applications are written in Java and have a similar internal structure. The app packages contain some identical files but the following files are different:
The bundle executable in the MacOS folder
Other executables in the MacOS folder launched by the bundle executable
The Info.plist keys CFBundleName, CFBundleIdentifier, CFBundleExecutable, CFBundleIconFile and JVMMainJarName
What might be the similarity between these app packages that is causing Sequoia to incorrectly identify one of these applications as being the other application?
I want to download some large files on watchOS and I found Apple Music app is able to download songs in background and pause downloading depending on battery life. Does there any way to do the same thing in my own app? After users choose to download, keep the downloading task in background and pause/resume on demand.
Hi,
Goal:
I want to change VPN configuration when app is closed and user joins unsecure wifi. (a wifi without a password).
Possible solution.
With help of an Hotspot helper I can listen the wifi changes when app is closed and if above criteria matches, execute code. (Start a new VPN Tunnel / change VPN configuration).
Questions.
Is this allowed.
Can we get hotspot helper entitlement for this kind of usage.
Is there other way to do this?