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

Unsandboxed XPCService launches sandboxed child processes
I have an application, it has main process and some child processes. As we want those child processes to have their own minimum sandbox privilege, not inheriting from parent process, we plan to use XPCService which uses a NSTask to launch those child processes, so those child processes can have its own sandbox privilege. We plan to deliver the application to Mac App Store, so process mode is: the sandboxed main process builds connections to the unsandboxed XPCService, the unsandboxed XPCService launch those sandboxed child processes. Can this process mode pass the Mac App Store rules? I see, there is a rule that all processes must be sandboxed, including XPCService. But I tested locally, the Application downloaded from Mac apple store also launches unsandboxed XPCService, like OneDrive. Do you have any suggestions for my application scenario, sandboxed child processes having its own privilege not inheriting from parent?
4
0
724
Apr ’24
What are the reasons for an application to be launched from the background?
Our application has seen a surge in the volume of background launches starting from April and May, and we want to know under what circumstances the application can be launched from the background. First, here's how I determined background launches: we analyze user logs and append UIApplication.appState to each line of log, finding that every log from the start to the end of user sessions has an appState of UIApplicationStateBackground. By checking the "ActivePrewarm" in main() and printing the launch options from application:didFinishLaunchingWithOptions:, we found several scenarios for background launches: launchOptions has a value with the key UIApplicationLaunchOptionsRemoteNotificationKey. launchOptions has no value and there is no "ActivePrewarm." launchOptions has no value but has "ActivePrewarm." I would like to know: Under what circumstances will notifications trigger a background launch (I cannot replicate this locally)? Under what circumstances does an application launch in the background and trigger application:didFinishLaunchingWithOptions: but without any launch options? I hope informations below can provide some insights. Regarding "ActivePrewarm," I've read various questions and answers in the Apple Developer Forums, such as this thread, which states that "ActivePrewarm" does not trigger application:didFinishLaunchingWithOptions: but occurs due to certain behaviors in the application. I would like to know what behaviors may cause this background launch, as there is no information in the launch options, or how I can identify what behaviors triggered it. Specifically, based on that same thread, I've tried to gather more information using runningboardd, and I've currently identified two special cases: When I restart my phone and unlock it after a short period, there is information: <RBSDomainAttribute| domain:"com.apple.dasd" name:"DYLDLaunch" sourceEnvironment:"(null)"> ]> Every day, at intervals of a few hours, there is information: <RBSDomainAttribute| domain:"com.apple.dasd" name:"DYLDLaunch" sourceEnvironment:"(null)"> ]> Then, the following similar information follows: 12:15:56.047625+0800 runningboardd Executing launch request for app<{my_bundle_id}((null))> (DAS Prewarm launch) 12:15:56.050311+0800 runningboardd Creating and launching job for: app<{my_bundle_id}((null))> 12:15:56.050333+0800 runningboardd _mutateContextIfNeeded called for {my_bundle_id} 12:15:56.080560+0800 runningboardd app<{my_bundle_id}((null))>: -[RBPersonaManager personaForIdentity:context:personaUID:personaUniqueString:] required 0.000954 ms (wallclock); resolved to {1000, 39E408CF-2E67-4DB0-BF73-CFC5792285CD} 12:15:56.080632+0800 runningboardd 'app<{my_bundle_id}(39E408CF-2E67-4DB0-BF73-CFC5792285CD)>' Skipping container path lookup because containerization was prevented (<RBSLaunchContext: 0xcd8cc9180>) 12:15:56.080939+0800 runningboardd 'app<{my_bundle_id}(39E408CF-2E67-4DB0-BF73-CFC5792285CD)>' Constructed job description: <dictionary: 0xcd8aa2a00> { count = 19, transaction: 0, voucher = 0x0, contents = *** } 12:15:56.084839+0800 runningboardd [app<{my_bundle_id}((null))>:1649] Memory Limits: active 4096 inactive 4096 <private> 12:15:56.084861+0800 runningboardd [app<{my_bundle_id}((null))>:1649] This process will be managed. 12:15:56.084882+0800 runningboardd Now tracking process: [app<{my_bundle_id}((null))>:1649] 12:15:56.084928+0800 runningboardd Calculated state for app<{my_bundle_id}((null))>: running-active (role: Background) (endowments: (null)) 12:15:56.086762+0800 runningboardd Using default underlying assertion for app: [app<{my_bundle_id}((null))>:1649] 12:15:56.086977+0800 runningboardd Acquiring assertion targeting [app<{my_bundle_id}((null))>:1649] from originator [app<{my_bundle_id}((null))>:1649] with description <RBSAssertionDescriptor| "RB Underlying Assertion" ID:33-33-23101 target:1649 attributes:[ <RBSDomainAttribute| domain:"com.apple.underlying" name:"defaultUnderlyingAppAssertion" sourceEnvironment:"(null)">, <RBSAcquisitionCompletionAttribute| policy:AfterApplication> ]> 12:15:56.087203+0800 runningboardd Assertion 33-33-23101 (target:[app<{my_bundle_id}((null))>:1649]) will be created as active 12:15:56.087946+0800 runningboardd [app<{my_bundle_id}((null))>:1649] reported to RB as running 12:15:56.088053+0800 runningboardd Calculated state for app<{my_bundle_id}((null))>: running-active (role: Background) (endowments: (null)) 12:15:56.088114+0800 runningboardd [app<{my_bundle_id}((null))>:1649] Set jetsam priority to 0 [0] flag[1] 12:15:56.088136+0800 runningboardd [app<{my_bundle_id}((null))>:1649] Resuming task. 12:15:56.088211+0800 runningboardd [app<{my_bundle_id}((null))>:1649] Set darwin role to: Background 12:15:56.088449+0800 runningboardd [app<{my_bundle_id}((null))>:1649] set Memory Limits to Hard Inactive (4096) 12:15:56.089314+0800 runningboardd Successfully acquired underlying assertion for [app<{my_bundle_id}((null))>:1649] 12:15:56.589755+0800 runningboardd Invalidating assertion 33-76-23100 (target:app<{my_bundle_id}((null))>) from originator [osservice<com.apple.dasd>:76] 12:15:56.590332+0800 runningboardd Removed last relative-start-date-defining assertion for process app<{my_bundle_id}((null))> 12:15:56.593760+0800 runningboardd [app<{my_bundle_id}((null))>:1649] Suspending task. 12:15:56.594120+0800 runningboardd Calculated state for app<{my_bundle_id}((null))>: running-suspended (role: None) (endowments: (null)) From these logs, I understand that the system is accelerating the launch speed of the application. But the time interval between these two logs below is very short, which suggests that the prewarm is executed just before main, and then the process is suspended. Is this understanding correct? 12:15:56.089314+0800 runningboardd Successfully acquired underlying assertion ... 12:15:56.589755+0800 runningboardd Invalidating assertion ... Regarding "DAS DYLD3 Closure Generation," I speculate that after a user restarts their phone, the system uses DYLD3 to prepare closures for frequently used applications, allowing for faster application launches. Is this assumption correct?
5
0
338
Oct ’24
Is it guaranteed that tasks in DispatchQueue.global() will not discard when switching back to the app later, assuming the app was not terminated
Let's say I queue some tasks on DispatchQueue.global() and then switch to another app or locking screen for a while. The app was not terminated but stayed in the background. Is there a chance that some tasks queued but not yet start could be discarded, even if the app hasn’t been terminated, after switching to another app or locking the screen for a while?
2
0
285
Nov ’24
iOS 18.1 崩溃问题
我这边用了几台机器升级iOS 18.1并没有测试出来问题,但是审核员测试出来了问题,并将崩溃报告发给了我。 以下是审核员发给我的的测试环境及崩溃报告: Device type: iPad Air (5th generation) OS version: iOS 18.1 崩溃报告如下: Thread 0 name: Dispatch queue: com.apple.main-thread Thread 0 Crashed: 0 libobjc.A.dylib 0x196ae7c38 objc_msgSend + 56 1 UIKitCore 0x19bf9c0f4 -[UIView bounds] + 32 2 UIKitCore 0x19c14e15c -[UIScrollView _didEndDirectManipulationWithScrubbingDirection:] + 108 3 UIKitCore 0x19d4cd3e8 -[UIScrollView _stopScrollingNotify:pin:tramplingAnimationDependentFlags:] + 108 4 UIKitCore 0x19d4cd548 -[UIScrollView _stopScrollingAndZoomingAnimationsPinningToContentViewport:tramplingAnimationDependentFlags:] + 52 5 UIKitCore 0x19c385a28 -[UIScrollView dealloc] + 88 6 libsystem_blocks.dylib 0x221c29860 bool HelperBase::disposeCapture<(HelperBase::BlockCaptureKind)3>(unsigned int, unsigned char*) + 68 7 libsystem_blocks.dylib 0x221c29570 HelperBase::destroyBlock(Block_layout*, bool, unsigned char*) + 160 8 libsystem_blocks.dylib 0x221c29030 _call_dispose_helpers_excp + 72 9 libsystem_blocks.dylib 0x221c28fcc _Block_release + 256 10 libdispatch.dylib 0x1a14fe0d0 _dispatch_client_callout + 20 11 libdispatch.dylib 0x1a150c9e0 _dispatch_main_queue_drain + 980 12 libdispatch.dylib 0x1a150c5fc _dispatch_main_queue_callback_4CF + 44 13 CoreFoundation 0x1997fc204 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 16 14 CoreFoundation 0x1997f9440 __CFRunLoopRun + 1996 15 CoreFoundation 0x1997f8830 CFRunLoopRunSpecific + 588 16 GraphicsServices 0x1e57d81c4 GSEventRunModal + 164 17 UIKitCore 0x19c35eeb0 -[UIApplication _run] + 816 18 UIKitCore 0x19c40d5b4 UIApplicationMain + 340 19 BXT 0x104d90090 0x104aa4000 + 3063952 20 dyld 0x1bf1e6ec8 start + 2724 Thread 1: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 2: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 3: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 4 name: com.apple.uikit.eventfetch-thread Thread 4: 0 libsystem_kernel.dylib 0x1e9bba688 mach_msg2_trap + 8 1 libsystem_kernel.dylib 0x1e9bbdd98 mach_msg2_internal + 80 2 libsystem_kernel.dylib 0x1e9bbdcb0 mach_msg_overwrite + 424 3 libsystem_kernel.dylib 0x1e9bbdafc mach_msg + 24 4 CoreFoundation 0x1997f9a84 __CFRunLoopServiceMachPort + 160 5 CoreFoundation 0x1997f9130 __CFRunLoopRun + 1212 6 CoreFoundation 0x1997f8830 CFRunLoopRunSpecific + 588 7 Foundation 0x1984a0500 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212 8 Foundation 0x1984a0350 -[NSRunLoop(NSRunLoop) runUntilDate:] + 64 9 UIKitCore 0x19c372358 -[UIEventFetcher threadMain] + 420 10 Foundation 0x1984b16c8 NSThread__start + 724 11 libsystem_pthread.dylib 0x221c3137c _pthread_start + 136 12 libsystem_pthread.dylib 0x221c2c494 thread_start + 8 Thread 5: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 6: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 7: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 8: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 9: 0 libsystem_pthread.dylib 0x221c2c480 start_wqthread + 0 Thread 10 name: JavaScriptCore libpas scavenger Thread 10: 0 libsystem_kernel.dylib 0x1e9bbff90 __psynch_cvwait + 8 1 libsystem_pthread.dylib 0x221c2ea50 _pthread_cond_wait + 1204 2 JavaScriptCore 0x1b156aca4 scavenger_thread_main + 1512 3 libsystem_pthread.dylib 0x221c3137c _pthread_start + 136 4 libsystem_pthread.dylib 0x221c2c494 thread_start + 8 Thread 11 name: WebThread Thread 11: 0 libsystem_kernel.dylib 0x1e9bba688 mach_msg2_trap + 8 1 libsystem_kernel.dylib 0x1e9bbdd98 mach_msg2_internal + 80 2 libsystem_kernel.dylib 0x1e9bbdcb0 mach_msg_overwrite + 424 3 libsystem_kernel.dylib 0x1e9bbdafc mach_msg + 24 4 CoreFoundation 0x1997f9a84 __CFRunLoopServiceMachPort + 160 5 CoreFoundation 0x1997f9130 __CFRunLoopRun + 1212 6 CoreFoundation 0x1997f8830 CFRunLoopRunSpecific + 588 7 WebCore 0x1ad46bb18 RunWebThread(void*) + 780 8 libsystem_pthread.dylib 0x221c3137c _pthread_start + 136 9 libsystem_pthread.dylib 0x221c2c494 thread_start + 8 Thread 0 crashed with ARM Thread State (64-bit): x0: 0x00000003029b1840 x1: 0x0000000208981838 x2: 0x0000000000000000 x3: 0x0000000000000000 x4: 0x0000000000000001 x5: 0x00000f0300000000 x6: 0x0000000000000002 x7: 0x0000000000000000 x8: 0x00000000000000a0 x9: 0x0000000208981838 x10: 0x00000000024b036c x11: 0x00000000024b036c x12: 0x0000000000000000 x13: 0x00000000024b036c x14: 0x00000003029b1bc0 x15: 0x00000003029b1bc0 x16: 0x00000003029b1bc0 x17: 0x0000000205f46018 x18: 0x0000000000000000 x19: 0x0000000136841400 x20: 0x00000001fd5f4588 x21: 0xffffffffffffffff x22: 0x00000000000006d8 x23: 0x0000000136841ad8 x24: 0x0000000000000000 x25: 0x00000001fd5969e0 x26: 0x00000003032b7640 x27: 0x000000000000000f x28: 0x0000000000000000 fp: 0x000000016b35a4e0 lr: 0x000000019bf9c0f4 sp: 0x000000016b35a4e0 pc: 0x0000000196ae7c38 cpsr: 0x20001000 far: 0x00000000024b036c esr: 0x92000006 (Data Abort) byte read Translation fault
1
0
310
Nov ’24
DispatchSemaphore freeze
I'm calling the following function in a SwiftUI View modifier in Xcode 16.1: nonisolated function f -> CGFloat { let semaphore = DispatchSemaphore(value: 0) var a: CGFloat = 0 DispatchQueue.main.async { a = ... semaphore.signal() } semaphore.wait() return a } The app freezes, and code in the main queue is never executed.
2
0
261
Oct ’24
Background sync
I am developing an application usinh native apps, where the app needs to continuously sync data (such as daily tasks and orders) even when offline or running in the background. However, on iOS, the background sync stops after 30 seconds, limiting the functionality. The Background Sync API and Service Workers seem restricted on iOS, causing syncing to fail when the app is in the background or offline. What is the best way to ensure continuous background synchronization on iOS? Additionally, what is the most efficient data storage approach for managing offline capabilities and syncing smoothly when the network is unstable and for the background sync?
1
0
225
Oct ’24
AsyncStream stops dispatching
Hello I'm a beginner to Swift Concurrency and have run into an issue with AsyncStream. I've run into a situation that causes an observing of a for loop to receiving a values from an AsyncStream. At the bottom is the code that you can copy it into a Swift Playground and run. The code is supposed to mock a system that has a service going through a filter to read and write to a connection. Here is a log of the prints 🙈🫴 setupRTFAsyncWrites Start ⬅️ Pretend to write 0 ➡️ Pretend to read 0 feed into filter 0 yield write data 1 🙈🫴 setupRTFAsyncWrites: write(1 bytes) ⬅️🙈🫴 Async Event: dataToDevice: 1 bytes ⬅️ Pretend to write 1 ➡️ Pretend to read 1 feed into filter 1 yield write data 2 // here our for loop should have picked up the value sent down the continuation. But instead it just sits here. Sample that can go into a playground //: A UIKit based Playground for presenting user interface import SwiftUI import PlaygroundSupport import Combine import CommonCrypto import Foundation class TestConnection { var didRead: ((Data) -&gt; ()) = { _ in } var count = 0 init() { } func write(data: Data) { // pretend we sent this to the BT device print("⬅️ Pretend to write \(count)") Task { try await Task.sleep(ms: 200) print("➡️ Pretend to read \(self.count)") self.count += 1 // pretend this is a response from the device self.didRead(Data([0x00])) } } } enum TestEvent: Sendable { /// ask some one to write this to the device case write(Data) /// the filter is done case handshakeDone } class TestFilter { var eventsStream: AsyncStream&lt;TestEvent&gt; var continuation: AsyncStream&lt;TestEvent&gt;.Continuation private var count = 0 init() { (self.eventsStream, self.continuation) = AsyncStream&lt;TestEvent&gt;.makeStream(bufferingPolicy: .unbounded) } func feed(data: Data) { print("\tfeed into filter \(count)") count += 1 if count &gt; 5 { print("\t✅ handshake done") self.continuation.yield(.handshakeDone) return } Task { // data delivered to us by a bluetooth device // pretend it takes time to process this and then we return with a request to write back to the connection try await Task.sleep(ms: 200) print("\tyield write data \(self.count)") // pretend this is a response from the device let result = self.continuation.yield(.write(Data([0x11]))) } } /// gives the first request to fire to the device for the handshaking sequence func start() -&gt; Data { return Data([0x00]) } } // Here we facilitate communication between the filter and the connection class TestService { private let filter: TestFilter var task: Task&lt;(), Never&gt;? let testConn: TestConnection init(filter: TestFilter) { self.filter = filter self.testConn = TestConnection() self.testConn.didRead = { [weak self] data in self?.filter.feed(data: data) } self.task = Task { [weak self] () in await self?.setupAsyncWrites() } } func setupAsyncWrites() async { print("🙈🫴 setupRTFAsyncWrites Start") for await event in self.filter.eventsStream { print("\t\t🙈🫴 setupRTFAsyncWrites: \(event)") guard case .write(let data) = event else { print("\t\t🙈🫴 NOT data to device: \(event)") continue } print("\t\t⬅️🙈🫴 Async Event: dataToDevice: \(data)") self.testConn.write(data: data) } // for // This shouldn't end assertionFailure("This should not end") } public func handshake() async { let data = self.filter.start() self.testConn.write(data: data) await self.waitForHandshakedone() } private func waitForHandshakedone() async { for await event in self.filter.eventsStream { if case .handshakeDone = event { break } continue } } } Task { let service = TestService(filter: TestFilter()) await service.handshake() print("Done") } /* This is what happens: 🙈🫴 setupRTFAsyncWrites Start ⬅️ Pretend to write 0 ➡️ Pretend to read 0 feed into filter 0 yield write data 1 🙈🫴 setupRTFAsyncWrites: write(1 bytes) ⬅️🙈🫴 Async Event: dataToDevice: 1 bytes ⬅️ Pretend to write 1 ➡️ Pretend to read 1 feed into filter 1 yield write data 2 // It just stops here, the `for` loop in setupAsyncWrites() should have picked up the event sent down the continuation after "yield write data 2" // It should say 🙈🫴 setupRTFAsyncWrites: write(1 bytes) ⬅️🙈🫴 Async Event: dataToDevice: 1 bytes */ extension Task&lt;Never, Never&gt; { public static func sleep(ms duration: UInt64) async throws { try await Task.sleep(nanoseconds: 1_000_000 * duration) } }
1
0
271
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
395
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
349
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.
2
0
310
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
322
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
370
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
348
Oct ’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
284
Oct ’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
498
Sep ’24
Big Sur - LaunchAgents - Load error 5: input/output error
Hi all, I am having a mysterious problem trying to load a user LaunchAgent under Big Sur - It is the .plist of gniemetz's automount.sh  https://github.com/gniemetz/automount for mounting SMB shares via pwd access from the Keychain - Placed the .sh into /usr/local/bin, chmod 644 and chown user:staff Placed the LaunchAgent .plist into ~/Library/LaunchAgents (created LaunchAgents it as it didn't exist), same chmod/chown. drwxr-xr-x&amp;amp;#9;&amp;amp;#9;3&amp;amp;#9; users&amp;amp;#9;&amp;amp;#9; 96 Nov&amp;amp;#9;1 22:13 LaunchAgents ~/Library/LaunchAgentsrw-r--r--&amp;amp;#9;&amp;amp;#9;1&amp;amp;#9; users&amp;amp;#9; 1038 Nov&amp;amp;#9;1 22:13 it.niemetz.automount.plist /usr/local drwxr-xr-x&amp;amp;#9;&amp;amp;#9;4 root&amp;amp;#9;&amp;amp;#9;wheel&amp;amp;#9;&amp;amp;#9;128 Nov&amp;amp;#9;1 21:52 bin /usr/local/binrwxr-xr-x&amp;amp;#9;&amp;amp;#9;1 root&amp;amp;#9;&amp;amp;#9;wheel&amp;amp;#9;30310 Oct 29 21:58 automount.sh then the following: Load failed: 5: Input/output error For the life of me, I cannot find anywhere what this means... launchctl start ~/Library/LaunchAgents/it.niemetz.automount.plist completes with no errors, syntax also parses OK /Users//Library/LaunchAgents/it.niemetz.automount.plist: OK I have added Terminal and /bin/bash to Full Disk Access under Security... Launching the script manually as /usr/local/bin/automount.sh works fine. Console shows system.log shows this when load -w is run: 00:27:14 mac-mini-Big-Sur com.apple.xpc.launchd[1] (com.apple.xpc.launchd.user.domain.1000002.100006.Aqua): entering bootstrap mode Nov&amp;amp;#9;3 00:27:14 mac-mini-Big-Sur com.apple.xpc.launchd[1] (com.apple.xpc.launchd.user.domain.1000002.100006.Aqua): exiting bootstrap mode For easy reference the .plist is pasted at the end - Anyone seen this error before? Thanks! ++ Label it.niemetz.automount LimitLoadToSessionType Aqua RunAtLoad WatchPaths /etc/resolv.conf /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist /Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist ProgramArguments /usr/local/bin/automount.sh --mountall
20
2
36k
Nov ’20