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.

Answered by DTS Engineer in 808315022

If this is entirely internal to you app, why do you need to run in the background? Let’s say your app is quit. The user can’t see your app, so they can’t tell whether it’s generated the events or not. The next time the user launches your app, you can generate any missing events.

The other case to consider is when the user doesn’t quit your app, but just deactivates it. In that case you can use a simple timer to generate the events. macOS apps continue to get execution time when they’re deactivated [1].

Alternatively, if you want to defer that work to a ‘good’ time, I recommend that you check out the NSBackgroundActivityScheduler class.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] It may be throttled in a process called App Nap, but it’ll get enough time for this task.

macOS has much more flexible background execution facilities than iOS, so it should be possible to meet your goals. I just need to get a better understanding of those goals in order to get you on the right path.

The issue I have is that after X amount of time, the app needs to generate more events.

In what context? Are you generating these events in some external database, like EventKit? Or is this entirely internal to your app?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for your response. This is entirely internal to the app. I am using SwiftData as the source. I will have a function that will get the expiring event and generate new entries, extending 3 months each time until cancelled. I need to run that function daily. Thanks.

Accepted Answer

If this is entirely internal to you app, why do you need to run in the background? Let’s say your app is quit. The user can’t see your app, so they can’t tell whether it’s generated the events or not. The next time the user launches your app, you can generate any missing events.

The other case to consider is when the user doesn’t quit your app, but just deactivates it. In that case you can use a simple timer to generate the events. macOS apps continue to get execution time when they’re deactivated [1].

Alternatively, if you want to defer that work to a ‘good’ time, I recommend that you check out the NSBackgroundActivityScheduler class.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] It may be throttled in a process called App Nap, but it’ll get enough time for this task.

Thank you! I was able to implement NSBackgroundActivityScheduler class and it is doing what I need.

Schedule A Daily Task in MacOS Sandbox App
 
 
Q