Let's say I have a Task that I want to extend into the background with beginBackgroundTask(expirationHandler:). Furthermore, I'd like to leverage cooperative cancelation of subtasks when responding to the expiration handler. Unfortunately, the expirationHandler: closure parameter is not async, so I'm unable to do something like:
actor MyTaskManagerOne {
var backgroundID = UIBackgroundTaskIdentifier.invalid
func start() {
Task {
let doTheWorkTask = Task {
await self.doTheWork()
}
backgroundID = await UIApplication.shared.beginBackgroundTask {
doTheWorkTask.cancel()
// next line: compile error, since not an async context
await doTheWorkTask.value // ensure work finishes up
// next line: generates MainActor compilation warnings despite docs allowing it
UIApplication.shared.endBackgroundTask(self.backgroundID)
}
await doTheWorkTask.value
}
}
func doTheWork() async {}
}
So instead, I think I have to do something like this. It, however, generates runtime warnings, since I'm not directly calling endBackgroundTask(_:) at the end of the expirationHandler:
actor MyTaskManagerTwo {
var backgroundID = UIBackgroundTaskIdentifier.invalid
func start() {
Task {
let doTheWorkTask = Task {
await self.doTheWork()
}
backgroundID = await UIApplication.shared.beginBackgroundTask {
doTheWorkTask.cancel()
// 1. not calling endBackgroundTask here generates runtime warnings
}
await doTheWorkTask.value
// 2. even though endBackgroundTask gets called
// here (as long as my cooperative cancellation
// implementations abort quickly in `doTheWork()`)
await UIApplication.shared.endBackgroundTask(self.backgroundID)
}
}
func doTheWork() async {}
}
As best I can tell, the MyTaskManagerTwo actor works and does not cause a watchdog termination (as long as cancellation is sufficiently fast). It is, however, producing the following runtime warning:
Background task still not ended after expiration handlers were called: <_UIBackgroundTaskInfo: 0x302753840>: taskID = 2, taskName = Called by libswift_Concurrency.dylib, from <redacted>, creationTime = 9674 (elapsed = 28). This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(_:) to avoid this.
Is the runtime warning ok to ignore in this case?
Processes & Concurrency
RSS for tagDiscover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.
Post
Replies
Boosts
Views
Activity
Good day.
I'm having problems debugging hangs. Watched the video WWDC Analyze hangs with Instruments. Apparently the main thread is blocked. It’s just not possible to analyze what exactly is blocking the flow. Please help me figure it out.
https://drive.google.com/file/d/1QvFK4y79CG0fBMrJPOrBCTuWsOaqichY/view?usp=share_link <- trace
PLATFORM AND VERSION
iOS
Development environment: Xcode 15.0, macOS 14.4.1, Objective-C
Run-time configuration: iOS 17.2.1,
DESCRIPTION OF PROBLEM
I am developing an application that uses NetworkExtension (VoIP local push function).
But iOS sometimes doesn't call didActivateAudioSession after following sequence.
Would you tell me why iOS doesn't call didActivateAudioSession ?
(I said "sometimes", but once it occurs, it will occur repeatedly)
myApp --- CXStartCallAction --->iOS
myApp <-- performStartCallAction callback --- iOS
myApp --- AVAudioSession
setCategory:
AVAudioSessionCategoryPlayAndRecord --->iOS
myApp --- AVAudioSession
setMode:
AVAudioSessionModeVoiceChat --->iOS
myApp <-- didActivateAudioSession callback ----iOS
I suspect that myApp cannot acquire an AVAudioSession if another app is already using AVAudioSession.
[QUESTION1]
Is my guess correct? Should I consider another cause?
[QUESTION2]
If my guess is correct, how can I prove if another app is already using an AVAudioSession?
This issue is based on a customer complaint, but the customer said they don't use any other apps.
Best Regards,
I have
var idleScanTimer = DispatchSource.makeTimerSource()
as a class ivar. When the object is started, I have
self.idleScanTimer.schedule(deadline: .now(), repeating: Double(5.0*60))
(and it sets an event handler, that checks some times.)
When the object is stopped, it calls self.idleScanTimer.cancel().
At some point, the object containing it is deallocated, and ... sometimes, I think, not always, it crashes:
Crashed Thread: 61 Dispatch queue: NEFlow queue
[...]
Application Specific Information:
BUG IN CLIENT OF LIBDISPATCH: Release of an inactive object
[...]
Thread 61 Crashed:: Dispatch queue: NEFlow queue
0 libdispatch.dylib 0x7ff81c1232cd _dispatch_queue_xref_dispose.cold.2 + 24
1 libdispatch.dylib 0x7ff81c0f84f6 _dispatch_queue_xref_dispose + 55
2 libdispatch.dylib 0x7ff81c0f2dec -[OS_dispatch_source _xref_dispose] + 17
3 com.kithrup.simpleprovider 0x101df5fa7 MyClass.deinit + 87
4 com.kithrup.simpleprovider 0x101dfbdbb MyClass.__deallocating_deinit + 11
5 libswiftCore.dylib 0x7ff829a63460 _swift_release_dealloc + 16
6 com.kithrup.simpleprovider 0x101e122f4 0x101de7000 + 176884
7 libswiftCore.dylib 0x7ff829a63460 _swift_release_dealloc + 16
8 libsystem_blocks.dylib 0x7ff81bfdc654 _Block_release + 130
9 libsystem_blocks.dylib 0x7ff81bfdc654 _Block_release + 130
10 libdispatch.dylib 0x7ff81c0f3317 _dispatch_client_callout + 8
11 libdispatch.dylib 0x7ff81c0f9317 _dispatch_lane_serial_drain + 672
12 libdispatch.dylib 0x7ff81c0f9dfd _dispatch_lane_invoke + 366
13 libdispatch.dylib 0x7ff81c103eee _dispatch_workloop_worker_thread + 753
14 libsystem_pthread.dylib 0x7ff81c2a7fd0 _pthread_wqthread + 326
15 libsystem_pthread.dylib 0x7ff81c2a6f57 start_wqthread + 15
I tried changing it to an optional and having the deinit call .cancel() and set it to nil, but it still crashes.
I can't figure out how to get it deallocated in a small, standalone test program.
I am creating app in which when user login i am hitting create session api and when user kill the app or not using the app i want to call delete session api. So how i can implement this feature
Hi, I am implementing a widget where I make some network calls.
I have set the timelineprovider to update on end, and I have about an hour of widgetkit entries going for each timeline.
I notice that the getTimeline function is called an arbitrary amount of times, usually between 2-5 when my widget fetches new entries for the widget.
I was under the impression that it should only call the getTimeline function once, and use the entires for all of my widgets (I 3 widgets in total, two for the lock screen and one for home screen).
Am I missing something when it comes to understanding the basic lifecycle? Anyone else having these issues? I am using XCode 15.3 and developing for iOS 17.
I'm attempting to reload a Safari Content Blocker from within a sandboxed command-line tool configured as a LaunchAgent. However, when I use SFContentBlockerManager to reload the content blocker, I encounter the error SFErrorDomain Code=1: Unavailable error.
Is it possible to reload a content blocker from a LaunchAgent? If so, how can it be done?
//
// main.swift
// BlockerUpdater
//
// Created by Sebastian Livoni on 30/06/2024.
//
import Foundation
import SafariServices
// Function to reload content blocker asynchronously
func reloadContentBlocker() async {
NSLog("Hello, World!")
do {
try await SFContentBlockerManager.reloadContentBlocker(withIdentifier: "me.livoni.blocker.dns")
NSLog("Reload complete")
} catch {
NSLog("Failed to reload content blocker: \(error.localizedDescription)")
}
}
// Main entry point for async code
@main
struct BlockerUpdater {
static func main() async {
await reloadContentBlocker()
}
}
Hello! My startup is developing a Desktop application for Windows and macOS for encrypting email in local networks.
Email encryption in sending applications is planned to be carried out using the S/MIME protocol. The private key is stored on the user's smartphone (we have a requirement from our customers), and at certain moments we simulate the work of a smart card over the WebSocket protocol. In addition, there are policies requiring constant connection of a smart card.
However, unlike Android, the user must manually launch the application each time to sign a letter. Is it possible to make sure that the WebSocket connection does not interrupt in the background? We received many negative reviews from iOS users because of this.
Or help us please, what protocol can be used for background emulation of smart card operations?
我添加了相应服务的xx.plist,并在shell脚本中使用launchctl load -w "$HOME/Library/LaunchAgents/com.xx.xx.plist"
launchctl start com.xx.xx.local 启动,脚本名称为local,当我给app加上沙盒功能之后,我使用 let installerPath = bundle.path(forResource: "local.sh", ofType: nil)
let task = Process.launchedProcess(launchPath: "/bin/bash", arguments: [installerPath!])
task.waitUntilExit()运行结果,我得到这样 的结果:Load failed: 5: Input/output error
Try running launchctl bootstrap as root for richer errors.
Unload failed: 5: Input/output error
Try running launchctl bootout as root for richer errors.
Not privileged to start service.,可以帮助我吗? 我该进行什么操作,才能让我的app正常运行?
Let's image that someone wants to use a background service to keep track of FSEvents activity, at the file level (a firehose, some might say).
I choose this example, to indicate the volume and rate of data transmission in question. I'm not creating a front-end for FSEvents data, but my background service may generate data at a similar pace. The service runs off of user defined document/s that specify the FSEvent background filtering to be applied. Those that match get stored into a database. But filters can match on almost all the data being emitted by FSEvents.
The user decides to check on the service's activity and database writes by launching a GUI that sends requests to the background service using XPC. So the GUI can request historic data from a database, but also get a real-time view of what FS events the service is busy filtering.
So it's a client-server approach, that's concerned with monitoring an event stream over XPC. I understand XPC is a request/response mechanism, and I might look into using a reverse connection here, but my main concern is one of performance. Is XPC capable of coping with such a high volume of data transmision? Could it cope with 1000s of rows of table data updates per second sent to a GUI frontend?
I know there are streaming protocol options that involve a TCP connection, but I really want to stay away from opening sockets.
When I register & schedule a Background Task on an iPad, it runs properly. Running the exact same code on an M1 MacBook Pro, though, never schedules the task. There's no error, just a failure to schedule. After scheduling and calling getPendingTaskRequests, on the iPad you can see that it has a pending task, but not on the Mac. Why would this be?
BGTaskScheduler.shared.register(forTaskWithIdentifier: taskIdentifier, using: nil) { [self] task in
print("task to run")
}
do {
try BGTaskScheduler.shared.submit(request)
BGTaskScheduler.shared.getPendingTaskRequests { [self] tasks in
print(tasks.count) //Prints 1 on iPad, prints 0 on Mac
}
} catch {
//Code never comes here.
print(error)
}
Cannot bring the Safari browser to the foreground from an iOS application while other applications can be opened the same way.
STEPS TO REPRODUCE
After executing the following code, the browser is not opened:
if let url = URL(string: "com-apple-mobilesafari-tab://"), UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url, options: [: ], completionHandler: nil)
}
How to use "iPhone Mirroing" on macOS 15,i can see this app in Finder,but i can't start it.
Attaching several crash traces:
2024-02-29_22-48-33.6864_-0600-3f948243e21b4c68d77a38d9cf1cecfdfe2c1565.crash
2024-03-04_15-00-02.9335_-0600-75000cd5acd63ba1434f2ffb3648b97259dddb88.crash
2024-03-05_08-55-47.2097_-0500-f682b25663107ad46f091d65f402f2be31f3f3c6.crash
2024-03-11_08-09-00.4057_-0400-e37d1a635d51afbb67ac38b42dd79c1718a408e8.crash
2024-03-15_16-20-22.6446_-0600-d4ebccf455e8305038ca564a39a5661a1dce6231.crash
The final code:
- (NSObject*)objectAtIndex:(NSUInteger)index {
if (index < self.count) {
return [self.embeddedArray objectAtIndex:index];
} else {
[PNDErrorReporting reportError:PNDErrorReasonTypeSafeCollectionCrashPrevented message:@"Error msg"];
return nil;
}
}
We subclass NSMutableArray to prevent potential crashes. but we encounter a new crash in our sdk for one of the clients.
Also we noticed the stack trace skipped one of the frames (stack calls) in the crash report, in which cases the stack trace wont be identical to the actual code (beside inline)?
My company builds an application using the External Accessory framework to communicate with our hardware. We have followed the documentation and example here and use the stream delegate pattern for scheduling the handling of the EASession's InputStream and OutputStream: https://developer.apple.com/library/archive/featuredarticles/ExternalAccessoryPT/Articles/Connecting.html
Our application works, however we have had some issues that cause us to doubt our implementation of the Stream handling for our EASession.
All the examples I can find for how to set up this RunLoop based implementation for managing and using the streams associated with the EASession seem to use RunLoop.current to schedule the InputStream and OutputStream. What is not clear to me is what thread the processing of these streams is actually getting scheduled upon.
We have occasionally observed our app "freezing" when our connected accessory disconnects, which makes me worry that we have our Stream processing on the main thread of the application. We want these streams to be processed on a background thread and never cause problems locking up our main thread or UI.
How exactly do we achieve this? If we are indeed supposed to only use RunLoop.current, how can we make sure we're opening the EASession and scheduling its streams on a non-main thread?
On what thread will we receive EAAccessoryDidConnect and EAAccessoryDidDisconnect notifications? Is it safe to schedule streams using RunLoop.current from that thread? What about when the app returns from the background, how are we meant to reconnect to an accessory that the iOS device is already connected to?
Hopefully someone here can help guide us and shed some light on how to achieve our desired behavior here.
I got crash report for my mobile application
private var _timedEvents: SynchronizedBarrier<[String: TimeInterval]>
private var timedEvents: [String: TimeInterval] {
get {
_timedEvents.value
}
set {
_timedEvents.value { $0 = newValue }
}
}
func time(event: String) {
let startTime = Date.now.timeIntervalSince1970
trackingQueue.async { [weak self, startTime, event] in
guard let self else { return }
var timedEvents = self.timedEvents
timedEvents[event] = startTime
self.timedEvents = timedEvents
}
}
From the report, the crash is happening at _timedEvents.value { $0 = newValue }
struct ReadWriteLock {
private let concurentQueue: DispatchQueue
init(label: String,
qos: DispatchQoS = .utility) {
let queue = DispatchQueue(label: label,
qos: qos,
attributes: .concurrent)
self.init(queue: queue)
}
init(queue: DispatchQueue) {
self.concurentQueue = queue
}
func read<T>(closure: () -> T) -> T {
concurentQueue.sync { closure() }
}
func write<T>(closure: () throws -> T) rethrows -> T {
try concurentQueue.sync(flags: .barrier) { try closure() }
}
}
struct SynchronizedBarrier<Value> {
private let lock: ReadWriteLock
private var _value: Value
init(_ value: Value,
lock: ReadWriteLock = ReadWriteLock(queue: DispatchQueue(label: "com.example.SynchronizedBarrier",
attributes: .concurrent))) {
self.lock = lock
self._value = value
}
var value: Value { lock.read { _value } }
mutating func value<T>(execute task: (inout Value) throws -> T) rethrows -> T {
try lock.write { try task(&_value) }
}
}
What could be the reason for the crash?
I have attached the crash report.
Masked.crash
CIFormat static var such as RGBA16 give concurrency warnings:
Reference to static property 'RGBA16' is not concurrency-safe because it involves shared mutable state; this is an error in Swift 6
Should all these formats be static let to suppress the warnings (future errors)?
It seems that that all the crashes are coming from the same place BUT the error is slightly different.
Attaching the code that responsible for the crash:
static NSString * const kDelimiter = @"#$@";
+ (PNDArray *)getObjectsFromData:(NSData *)data {
NSString *dataStr = [[NSString alloc] initWithData:data encoding:encoding];
dataStr = [dataStr stringByReplacingOccurrencesOfString:@"\\u0000" withString:@""];
NSArray *components = [dataStr componentsSeparatedByString:kDelimiter];
NSMutableArray *result = [NSMutableArray array];
for (NSString *jsonStr in components) {
if (jsonStr != nil && jsonStr.length != 0 && ![jsonStr hasPrefix:kBatchUUID]) {
[result addObject:jsonStr];
}
}
return [PNDArray arrayWithArray:result];
}
2024-04-16_17-15-34.1922_-0600-dfa2faecf702f23e3f6558bea986de4f62851761.crash
2024-04-24_04-56-53.4664_-0500-6b125d3d03b7e497b6be339c2abb52f29658824b.crash
2024-04-25_11-13-53.1326_-0700-bfe370be3eae8d65f465eac714905dd3d13aa665.crash
2024-05-03_11-47-36.6085_-0500-2793587e7ed1c02b0e4334bbc3aa0bd7f7a0cf3d.crash
2024-05-05_10-49-40.5969_-0700-4d86636b0877fceb8c0cdb9586ee16dfb0a9c934.crash
my macOS process is crashing when i keep my mac sleep for about 1 hour.
Under Crash Reports, Console app shows two type of file.
.diag type
.ips type
ips file doesn't shows exact line of crash as you can see below sample.
Thread 67 Crashed:
0 libsystem_kernel.dylib 0x19a4aea60 __pthread_kill + 8
1 libsystem_pthread.dylib 0x19a4e6c20 pthread_kill + 288
2 libsystem_c.dylib 0x19a3f3a30 abort + 180
3 libsystem_malloc.dylib 0x19a303dc4 malloc_vreport + 896
4 libsystem_malloc.dylib 0x19a307430 malloc_report + 64
5 libsystem_malloc.dylib 0x19a321494 find_zone_and_free + 528
6 Firewall.so 0x103c8a744 TunnelSendQueue::ResumeSend() + 460
resource.diag file sgowing warning about exceeding limit of 150 wakeups per second over 300 seconds. attached here.
reasource_consumptions_W36RNW09G.wakeups_resource_diag.txt
is this something macOS stopping app because of some resource consumptions?
How do you send an NSURL representing a new file, as returned from an NSSavePanel, to an XPC service such that the service is granted permission to create the file?
I can successfully pass an NSURL to the XPC process if the NSURL represents an existing file. This is documented in Apple's Documentation:
Share file access between processes with URL bookmarks
This involves creating bookmark date while passing 0 in as the options. However, if you try to create bookmark data for an NSURL that represents a file that is not yet created, you do not get any bookmark data back and an error is returned instead:
Error Domain=NSCocoaErrorDomain Code=260
"The file couldn’t be opened because it doesn’t exist."
Simply passing the file path to the XPC process, by way of:
xpc_dictionary_set_string(message, "file_path", url.fileSystemRepresentation);
Does not grant the XPC create/write permissions. Is there an API or trick I'm missing?
Note that the user should be allowed to save and create new files anywhere of their choosing, thus restricting URLs to only those within a group or container shared between the app and service isn't really viable.
Using the latest of everything on macOS with the xpc_session API...