Run periodic taks in background after app kill or quits MacOS

I am an iOS developer and I have developed an app that runs a periodic background task using Background Modes, I want to implement the same feature in the MacOS version of this app, as I am new to the MacOS development, I am facing some issue regarding implementation of this feature.

I have used NSBackgroundActivityScheduler to schedule a periodic activity, which works fine, when the app is running or is in the dock. But I failed to achieve the same result , when I quit the application. I want to run that task even after the application terminates or quits.

 
func startBackgroundTask() {  
          let activity =  NSBackgroundActivityScheduler.init(identifier:"com.abc.xyz")  
          DispatchQueue.main.async { 
               self.activity.invalidate() 
               self.activity.interval = 60 
               self.activity.repeats = true 
               self.activity.qualityOfService = QualityOfService.background 
               self.activity.schedule() { (completion: NSBackgroundActivityScheduler.CompletionHandler) in 
               print("background task scheduled") 
               // Perform the activity 
               NotificationManager.sharedManager().showNotification(informativeText: "Next notification will come after 1 minute") 
               //perform operation over here... 
               completion(NSBackgroundActivityScheduler.Result.finished) 
              }
 }

I have researched various options regarding this , like XPC , LaunchAgent , LoginItems , Process etc. but I am confused which option to go with. As on apple developer forum they have used XPC with LoginItems, but I got stuck when I tried to implement it.


Can anyone guide me , how to achieve this, any tutorials ,video , sample will be helpfull.

I am confused which option to go with.

I agree that this is confusing. There’s a long history of doing this sort of thing on the Mac, so it’s hard to know which is the best option. The most critical factor is your deployment strategy. Are you deploying via the Mac App Store? Or out of the store, using Developer ID?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Hi, We will distribute the app through App Store, basically I have to update my database with some data and even have to access the keychain, even after eh GUI quits. I have implemented the NSBackgroundActivityScheduler so far and wanted to just call it, even after the app quits.


So far I have implemented the LaunchAgent, but I am unable to call the main applications method from the launchAgent. It is possible to call a particular method of the main application from the LaunchAgent.?

The only approach that’s compatible with the App Store is a sandboxed login item, as installed by

SMLoginItemSetEnabled
. That login item can be a normal app but in most cases you also need IPC between your app and your login item and you can do that using XPC, as illustrated by the AppSandboxLoginItemXPCDemo sample code.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for your suggestion and help, as the sample provided to me is in objC, can you please provide me same sample on swift?. As I am new to the macOS developement and have worked only on swift so far. So its difficult for me to get any idea from this sample,.

can you please provide me same sample on swift?

I don’t have a Swift version of that project handy.

Is your primary focus the

SMLoginItemSetEnabled
call? Or the XPC stuff? Because the former is very easy to do from Swift:
import ServiceManagement

let success = SMLoginItemSetEnabled("xxx" as NSString, true)

In contrast, running an XPC connection from Swift is a bit tricky. If you have specific questions about that I’d be happy to answer them.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks in advance, My primary focus is to implement the XPC service, as I was able to call the SMLoginItemSetEnabled.


I have programatically copied the .plist in the launchAgents folder present in the user library. There I have implemented a NSBackgroundActivityScheduler which repeats after a fixed duration .


Now I want to access the core data of main target from the target that is being invoked using LaunchAgent.

Is this possible through XPC only or is there any other way to do so.?


What I want now is to access the files of the main target from another target.Can you help me in this?

My primary focus is to implement the XPC service …

Yeah, I thought that might be the case.

I have programatically copied the

.plist
in the
LaunchAgents
folder present in the user library.

I’m confused. If you use

SMLoginItemSetEnabled
then you don’t need a launchd agent at all. Moreover, if you’re planning to deploy via the Mac App Store using a launchd agent is not an option.

In terms of app/login item communication:

  • A login item installed via

    SMLoginItemSetEnabled
    is able to vend an XPC service, which is the primary thrust of the AppSandboxLoginItemXPCDemo sample code.
  • In addition, if you want to share files specifically, your login item and your app can both adopt a shared app group, which gives you a shared container, which you can both read and write. You can get a URL for that container by calling

    -[NSFileManager containerURLForSecurityApplicationGroupIdentifier:]
    .

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I'm distributing my application via the app store and I'd like to run a scheduled (periodic) background job that can run even when the application is quit as long as it is installed. Looking at some documentation surrounding everything you mentioned above it seems like the only way to have a scheduled job is via cron or launchd.


Only other thing I need is to be able to run the process within a shared group or with access to the shared groups user defaults to read and write.


I'm wondering, is there a way to meet those specs?

I'm distributing my application via the app store and I'd like to run a scheduled (periodic) background job that can run even when the application is quit as long as it is installed.

If you’re distributing via the Mac App Store then your only option for running when the app is quit is to install a login item via

SMLoginItemSetEnabled
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Run periodic taks in background after app kill or quits MacOS
 
 
Q