Processes & Concurrency

RSS for tag

Discover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.

Concurrency Documentation

Post

Replies

Boosts

Views

Activity

Sandbox app + Parallel Process + LAN Socket (validation app store)
Hello everyone, I need help with an issue that is unclear to me. I developed an application with Unity and now I'm using xCode to distribute it both outside the App Store and on the App Store. As for the first option, no problem, I was able to build the app and upload it for validation. However, regarding the App Store, I have a problem with "App Sandbox," which seems to be mandatory in this case. My application is essentially a party game where one part functions as a desktop application and another part as a mobile application. The desktop application launches a parallel process (which I included in a group within xcode and signed with my developer ID) that makes the two parts communicate through a socket on the local network. When I enable App Sandbox, it seems that the process is not launched by the main application. I have also enabled the two options, Incoming Connection (server/client), under App Sandbox, but it still did not work. I thank you in advance for the support.Sandbox app + parallel process + LAN Socket
5
0
402
Sep ’24
Daemon needs to get user name
Years ago my daemon was since then using SCDynamicStoreCopyConsoleUser() function and now it longer works. Basically the daemon needs to know the user name of who is using the system. If I restart the daemon,after the login, it gets the user name. I tried run a shell command via my daemon ("id -F") and look likes it still picks the root as user name. So, is there a way to get the current user name using Swift? ProcessInfo.userName fails too
1
0
314
Sep ’24
XCTest to test EndpointSecurity error,ES_NEW_CLIENT_RESULT_ERR_NOT_PRIVILEGED
I tried to use XCTest to test my own project that uses EndpointSecurity, but when I created the esClient I got an error:ES_NEW_CLIENT_RESULT_ERR_NOT_PRIVILEGED, indicating that it was not root. This makes it impossible for me to do coverage tests for the ESClient application. Is there any way I can implement this ESClient test? If so, how should I use it? The project is a macOS program, if I use gcov, but I find I can't get coverage. Using __gcov_flush will indicate that there is no symbol #if !TARGET_IPHONE_SIMULATOR NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectory = [paths objectAtIndex:0]; setenv("GCOV_PREFIX", [documentsDirectory cStringUsingEncoding:NSUTF8StringEncoding], 1); setenv("GCOV_PREFIX_STRIP", "13", 1); #endif extern void __gcov_flush(void); __gcov_flush(); #endif
3
0
450
Sep ’24
Handling Main Actor-Isolated Values with `PHPhotoLibrary` in Swift 6
Hello, I’m encountering an issue with the PHPhotoLibrary API in Swift 6 and iOS 18. The code I’m using worked fine in Swift 5, but I’m now seeing the following error: Sending main actor-isolated value of type '() -> Void' with later accesses to nonisolated context risks causing data races Here is the problematic code: Button("Save to Camera Roll") { saveToCameraRoll() } ... private func saveToCameraRoll() { guard let overlayFileURL = mediaManager.getOverlayURL() else { return } Task { do { let status = await PHPhotoLibrary.requestAuthorization(for: .addOnly) guard status == .authorized else { return } try await PHPhotoLibrary.shared().performChanges({ if let creationRequest = PHAssetCreationRequest.creationRequestForAssetFromVideo(atFileURL: overlayFileURL) { creationRequest.creationDate = Date() } }) await MainActor.run { saveSuccessMessage = "Video saved to Camera Roll successfully" } } catch { print("Error saving video to Camera Roll: \(error.localizedDescription)") } } } Problem Description: The error message suggests that a main actor-isolated value of type () -> Void is being accessed in a nonisolated context, potentially leading to data races. This issue arises specifically at the call to PHPhotoLibrary.shared().performChanges. Questions: How can I address the data race issues related to main actor isolation when using PHPhotoLibrary.shared().performChanges? What changes, if any, are required to adapt this code for Swift 6 and iOS 18 while maintaining thread safety and actor isolation? Are there any recommended practices for managing main actor-isolated values in asynchronous operations to avoid data races? I appreciate any points or suggestions to resolve this issue effectively. Thank you!
1
0
786
Sep ’24
Issues with @preconcurrency and AVFoundation in Swift 6 on Xcode 16.1/iOS 18 (Worked fine in Swift 5)
Question: I'm working on a project in Xcode 16.1, using Swift 6 with iOS 18. My code is working fine in Swift 5, but I'm running into concurrency issues when upgrading to Swift 6, particularly with the @preconcurrency attribute in AVFoundation. Here is the relevant part of my code: import SwiftUI @preconcurrency import AVFoundation struct OverlayButtonBar: View { ... let audioTracks = await loadTracks(asset: asset, mediaType: .audio) ... // Tracks are extracted before crossing concurrency boundaries private func loadTracks(asset: AVAsset, mediaType: AVMediaType) async -> [AVAssetTrack] { do { return try await asset.load(.tracks).filter { $0.mediaType == mediaType } } catch { print("Error loading tracks: \(error)") return [] } } } Issues: When using @preconcurrency, I get the warning: @preconcurrency attribute on module AVFoundation has no effect. Suggested fix by Xcode is: Remove @preconcurrency. But if I remove @preconcurrency, I get both a warning and an error: Warning: Add '@preconcurrency' to treat 'Sendable'-related errors from module 'AVFoundation' as warnings. Error: Non-sendable type [AVAssetTrack] returned by implicitly asynchronous call to nonisolated function cannot cross actor boundary. (Class AVAssetTrack does not conform to the Sendable protocol (AVFoundation.AVAssetTrack)). This error comes if I attempt to directly access non-Sendable AVAssetTrack in an async context : let audioTracks = await loadTracks(asset: asset, mediaType: .audio) How can I resolve this issue while staying compliant with Swift 6 concurrency rules? Is there a recommended approach to handling non-Sendable types like AVAssetTrack in concurrency contexts? Appreciate any guidance on making this work in Swift 6, especially considering it worked fine in Swift 5. Thanks in advance!
1
0
862
Sep ’24
Apps not quitting immediately
Hello all, Recently I observed a strange behaviour on macOS. Some apps with UI, after you quit them (right click on the Dock, select Quit or select Quit from the menubar), the apps are not actually quitting immediately, but in a few seconds (including in Activity Monitor the apps are staying alive). Also, if you open the apps again fast, the same PID is kept. Not all apps do this, some of them, for example WhatsApp. I'm not referring to closing all windows, but explicitly quitting. This was not the case in the past. Is there any reason for this? Is some kind of optimisation I'm not aware of? The actual issue is that in a Swift developed app events like NSWorkspace.didLaunchApplicationNotification or NSWorkspace.didTerminateApplicationNotification are not triggered. Is there any way to tell if an app was closed, even if macOS still keeps it around for a few more seconds? Thank you.
1
0
336
Sep ’24
What is the principle behind the network filter developed through system expansion starting up with the computer's startup
I developed a network filter using system extensions and placed the system extension program in a container app. I activated the extension and enabled the network filter in the/Applications directory through the container app. After that, my container app process exited, and only the system extension program process in the/Library/SystemExtensions directory was running. After booting up and upgrading the macOS system, the system extension program will be launched, and I learned from the link below that the system extension will be launched with the system at startup: https://developer.apple.com/forums/thread/701986 . But I haven't learned from the official documentation of System Extensions and NetworkExtension why system extensions start with the system and what their principles are. Because the container app under the activation system extension/Application did not start. Has the network filter developed for system expansion been registered in the system related files or frameworks? Ensure that it will start after each startup
2
0
374
Sep ’24
Handle background task (BGProcessingTask) in terminated app state
I am having an issue with scheduling daily background task (eg: nightly) when app is in terminated app state (user forcefully terminated the app from app switcher). If the app is in suspended state, I am able to schedule a daily background task. But is there a way to wake up the app nightly and register a BGTask when user forcefully terminates the app.
1
0
303
Sep ’24
didFinishLaunchingWithOptions is called in background
Hello, Based on the application runtime logs, after switching to the background (possibly due to the user forcibly closing the application), the app sometimes restarts immediately or after several seconds and executes the didFinishLaunchingWithOptions method (at this point, UIApplicationState == UIApplicationStateBackground). The application itself has not requested background permissions, as shown in the attachment. I am puzzled about what could cause the application to restart in the background several seconds after being forcibly closed. Could you please help clarify the possible reasons for this behavior? (We have considered if it might be due to prewarming, but there is no prewarm flag during the startup.) Thank you.
3
0
302
Sep ’24
Problem with NSSound playback in XPC service
Hello, I run into an issue on Monterey (12.7.5). I have a bundled XPC service in my application which is displaying some stuff and playin sounds via NSSound. I had a problem with playback due to service priority, so I use the trick with a reply block where I send a reply block to the service and basically just retain it and never call it. This worked fine so far, but we have users, predominantly on Monterey, who are having a problem with sound playback. It's choppy and distorted when their machine is under load (where "load" often just means playing a video on YouTube in Chrome). Is there anything else I can do to get the proper priority for my xpc service so I can avoid distorted sound? Additionally the service type is Application and RunLoopType is NSRunLoop with JoinExistingSession set to true. The QoS level of main queue is 0x21 (user interactive) and I'm calling all the NSSound APIs on main queue.
3
0
392
Sep ’24
Coordination of Video Capture and Audio Engine Start in iOS Development
Question: When implementing simultaneous video capture and audio processing in an iOS app, does the order of starting these components matter, or can they be initiated in any sequence? I have an actor responsible for initiating video capture using the setCaptureMode function. In this actor, I also call startAudioEngine to begin the audio engine and register a resultObserver. While the audio engine starts successfully, I notice that the resultObserver is not invoked when startAudioEngine is called synchronously. However, it works correctly when I wrap the call in a Task. Could you please explain why the synchronous call to startAudioEngine might be blocking the invocation of the resultObserver? What would be the best practice for ensuring both components work effectively together? Additionally, if I were to avoid using Task, what approach would be required? Lastly, is the startAudioEngine effective from the start time of the video capture (00:00)? Platform: Xcode 16, Swift 6, iOS 18 References: Classifying Sounds in an Audio Stream – In my case, the analyzeAudio() method is not invoked. Setting Up a Capture Session – Here, the focus is on video capture. Classifying Sounds in an Audio File Code Snippet: (For further details. setVideoCaptureMode() surfaces the problem.) // ensures all operations happen off of the `@MainActor`. actor CaptureService { ... nonisolated private let resultsObserver1 = ResultsObserver1() ... private func setUpSession() throws { .. } ... setVideoCaptureMode() throws { captureSession.beginConfiguration() defer { captureSession.commitConfiguration() } /* -- Works fine (analyseAudio is printed) Task { self.resultsObserver1.startAudioEngine() } */ self.resultsObserver1.startAudioEngine() // Does not work - analyzeAudio not printed captureSession.sessionPreset = .high try addOutput(movieCapture.output) if isHDRVideoEnabled { setHDRVideoEnabled(true) } updateCaptureCapabilities() }
5
0
394
Sep ’24
Timer driven refresh
I have an app that needs to refresh a server whenever a Contacts record is updated. I can observe Contacts, but that only seems to work when my app is running (and in foreground, which it cannot be on iPhone if the Contacts app is being updated). I want it to process, even if my app is in background, or has been terminated (swiped away), or after a phone restart. The only way I can think of is to periodically push a notification to the app from an external server. Is there any way to run a timer that sends a notification to the app on a periodic basis? The timers you can set seem to run even if the Clock app is swiped away, or following a phone restart. Is there anything like that I could use to wake my app periodically?
1
0
231
Oct ’24
Schedule A Daily Task in MacOS Sandbox App
I am new to building apps for MacOS using SwiftUI but built apps for iOS currently in the store. I built an events app that stores a bunch of dates. The issue I have is that after X amount of time, the app needs to generate more events. In iOS I would use Background task to handle this, runs once daily etc. After much research I am pointed to using a LaunchAgents with an Embedded Helper Tool https://developer.apple.com/documentation/Xcode/embedding-a-helper-tool-in-a-sandboxed-app I am following this post: https://developer.apple.com/forums/thread/721737?answerId=739716022#739716022 I am stuck on setting up the plist file and clicking the button to try to add the launch item in simulator I get the following error: did not register, error: Error Domain=SMAppServiceErrorDomain Code=1 "Operation not permitted" UserInfo={NSLocalizedFailureReason=Operation not permitted} If this is the incorrect approach please let me know as I am stuck. Thanks.
4
0
315
Oct ’24
Is it possible for CarPlay to establish a connection with a Bluetooth Low Energy (BLE) dongle when the phone app is fully closed or not running in the background?
I’m currently developing an app that communicates with a BLE dongle. When I swipe up to close the app on my phone, both the phone app and the CarPlay app are terminated. From the CarPlay interface, I can relaunch the app. My question is: Can CarPlay establish a connection with a BLE dongle when the phone app is fully closed or not running in the background?
3
1
283
Oct ’24
How to correctly deploy bundled launchdaemons/launchagents?
I'm working on an enterprise product that's mainly a daemon (with Endpoint Security) without any GUI component. I'm looking into the update process for daemons/agents that was introduced with Ventura (Link), but I have to say that the entire process is just deeply unfun. Really can't stress this enough how unfun. Anyway... The product bundle now contains a dedicated Swift executable that calls SMAppService.register for both the daemon and agent. It registers the app in the system preferences login items menu, but I also get an error. Error registering daemon: Error Domain=SMAppServiceErrorDomain Code=1 "Operation not permitted" UserInfo={NSLocalizedFailureReason=Operation not permitted} What could be the reason? I wouldn't need to activate the items, I just need them to be added to the list, so that I can control them via launchctl. Which leads me to my next question, how can I control bundled daemons/agents via launchctl? I tried to use launchctl enable and bootstrap, just like I do with daemons under /Library/LaunchDaemons, but all I get is sudo launchctl enable system/com.identifier.daemon sudo launchctl bootstrap /Path/to/daemon/launchdplist/inside/bundle/Library/LaunchDaemons/com.blub.plist Bootstrap failed: 5: Input/output error (not super helpful error message) I'm really frustrated by the complexity of this process and all of its pitfalls.
3
0
254
Oct ’24
NSMetadataQuery threading issues
The code below is a simplified form of part of my code for my Swift Package Manager, Swift 5.6.1, PromiseKit 6.22.1, macOS command-line executable. It accepts a Mac App Store app ID as the sole argument. If the argument corresponds to an app ID for an app that was installed from the Mac App Store onto your computer, the executable obtains some information from Spotlight via a NSMetadataQuery, then prints it to stdout. I was only able to get the threading to work by calling RunLoop.main.run(). The only way I was able to allow the executable to return instead of being stuck forever on RunLoop.main.run() was to call exit(0) in the closure passed to Promise.done(). The exit(0) causes problems for testing. How can I allow the executable to exit without explicitly calling exit(0), and how can I improve the threading overall? I cannot currently use Swift Concurrency (await/async/TaskGroup) because the executable must support macOS versions that don't support Swift Concurrency. A Swift Concurrency solution variant would be useful as additional info, though, because, sometime in the future, I might be able to drop support for macOS versions older than 10.15. Thanks for any help. import Foundation import PromiseKit guard CommandLine.arguments.count > 1 else { print("Missing adamID argument") exit(1) } guard let adamID = UInt64(CommandLine.arguments[1]) else { print("adamID argument must be a UInt64") exit(2) } _ = appInfo(forAdamID: adamID) .done { appInfo in if let jsonData = try? JSONSerialization.data(withJSONObject: appInfo), let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString.replacingOccurrences(of: "\\/", with: "/")) } exit(0) } RunLoop.main.run() func appInfo(forAdamID adamID: UInt64) -> Promise<[String: Any]> { Promise { seal in let query = NSMetadataQuery() query.predicate = NSPredicate(format: "kMDItemAppStoreAdamID == %d", adamID) query.searchScopes = ["/Applications"] var observer: NSObjectProtocol? observer = NotificationCenter.default.addObserver( forName: NSNotification.Name.NSMetadataQueryDidFinishGathering, object: query, queue: .main ) { _ in query.stop() defer { if let observer { NotificationCenter.default.removeObserver(observer) } } var appInfo: [String: Any] = [:] for result in query.results { if let result = result as? NSMetadataItem { var attributes = ["kMDItemPath"] attributes.append(contentsOf: result.attributes) for attribute in attributes { let value = result.value(forAttribute: attribute) switch value { case let date as Date: appInfo[attribute] = ISO8601DateFormatter().string(from: date) default: appInfo[attribute] = value } } } } seal.fulfill(appInfo) } DispatchQueue.main.async { query.start() } } }
7
0
306
Oct ’24
Python Backend alongside MacOS Swift application
Context/Project Idea: I'm currently developing a project that consists of a macOS application using Swift and a local Python backend that executes specific tasks such as processing data. The Python backend is the core of this project, while the Swift application is a mere interface to interact with it. These two project parts should be decoupled so the user can theoretically run their own backend and connect the Swift application to it. Likewise, the user should be able to connect to the shipped backend using, e.g. curl. Current plan: My main idea is to use launchctl to launch a launchd agent which runs the Python backend. The script launching the backend will generate an API key stored in a keychain access group. The Swift application can then get that key and access the backend. The user can always get that API key from the keychain if they want to connect to it programmatically. Here are the main questions I have currently: Python Interpreter Consistency: I'm exploring options such as cx_Freeze or PyInstaller to create a standalone Python executable for better system stability. Does anyone have experience with these tools in a macOS environment, or are there other reliable alternatives worth considering? Adding a Launchd Agent to Xcode: How can I add a launchd agent to my Xcode project to manage a Python executable built with cx_Freeze or PyInstaller? What steps should I follow to ensure it functions properly? Keychain Access for Launchd Agent: Is it feasible for a launchd agent to access a Keychain access group? What configurations or permissions are necessary to implement this? Thanks in advance!
3
0
270
Oct ’24
Changes in behaviour of [SMAppService registerAndReturnError:] after Sonoma 14.4
I am using [SMAppService registerAndReturnError:] to register a launch agent from a plist bundled in the app (before the registration call a matching unregister is done via unregisterWithCompletionHandler as suggested by the docs). The non standard thing is that I am doing that in a root gui login with sudo to bootstrap my launch agent into gui/0 domain. This worked well until Sonoma 14.4 - now the call fails with: Error Domain=SMAppServiceErrorDomain Code=125 "Domain does not support specified action" UserInfo={NSLocalizedFailureReason=Domain does not support specified action} which is not really helpful. For now, i've switche to just using launchctl bootout and launchctl bootstrap to get around this, but could anyone elaborate on what has changed? My feeling is that something has changed in the logic that determines the domain - could it be that even with sudo the target domain is gui/ not gui/0 ? As far as I can see there are no ways to specify the domain from the SMAppService APIs right? Also a weird thing is that if run the code in a raw terminal in root gui it works as previously (but out of security, no thing really runs as root, everything is a launch agent under some less privileged user, and before Sonoma 14.4 sudoing with that less privileged user did work for [SMAppService registerAndReturn], now it does not, and what is also strange, doing sudo - and then sudo su also shows the same error code 125.
1
0
231
Oct ’24