Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Can we create a bundled non-interactive macOS application which uses CFRunLoop only(instead of using NSApplicationMain to run NSRunLoop)?

I am developing a macOS non-interactive macOS application which does not show any ui. i want to block main thread and do all the work on worker thread . Once done with work in worker thread, want to unblock main thread by exiting event loop to terminate application.

Because i dont want to show any UI or use any Foundation/Cocoa functionality, i am thinking of using CFRunLoop to block main thread from exiting until i finish my work in worker thread. When i tried this in a project, I am able to finish work in worker thread after block main thread using CFRunLoop.

I also want this application to be a bundled application, which can be launched by double clicking on application bundle . But when i tried it in my xcode project by launching it using double clicking on application bundle, application keeps on toggling/bouncing in the dock menu with a status "Not responding". Although i am able to complete my work in worker thread.

import Foundation

let runLoop = CFRunLoopGetCurrent()

func workerTask() {
    DispatchQueue.global().async {
        print("do its work")
        sleep(5) // do some work

        print("calling exit event loop")

        CFRunLoopStop(runLoop)
        print ("unblocking main thread")

    }
}


workerTask ()

// blocking main thread
print ("blocked main thread")
CFRunLoopRun()

print ("exit")

Why i am getting this application bouncing in doc menu behavior ? I tried by using NSApplicationMain instead of CFRunLoop in my project, in that case i didnt get this behavior .

Does NSApplicationMain does some extra work before starting NSRunLoop which i am not doing while using CFRunLoop, which is showing this toggling/Bouncing application icon in Dock menu ?

or Is this bouncing app icon issue is related to run loop i am using which is CFRunLoop ?

Note : If i dont use a bundled application and use a commandline application then i am able to do all steps in worker thread and exit main thread as i wanted after finishing my work . But i need to do all this in application which can be launched using double clicking (bundled applcation).

If not by using CFRunLoop, then how can i achive this ? - Create a application which shows no UI and do all work in worker thread while main thread is blocked. Once work is done unblock main thread and exit. And user should be able to launch application using double click the application icon.

I want to start by talking about your UI. You wrote:

launching it using double clicking on application bundle, application keeps on toggling/bouncing in the dock menu

Ignoring the bouncing for the moment, what sort of UI are you expecting to achieve here?

Generally, when a Mac user double clicks an app in the Finder, they expect the app to launch, or come to the front if it’s already running. They don’t expect the app to kinda launch and then disappear.

There are two common ways to manage non-interactive programs on the Mac:

  • Have it run entirely in the background, with no UI at all.

  • Have it run in the background but present some minimal UI, like a menu bar item or a floating window invoked by a hot key.

In both cases there has to be some way for the user to manage the program. The usual mechanism is to embed the program within a container app that has the management facility. So, your program might run in the background all the time, but the user can run the container app to install / start / stop / uninstall it.

Would that mechanism suit your product? If not, can you explain more about what you’re trying to achieve at the UI level?

Once I have a handle on what sort of UI you want, I should be able to advise you about what APIs you need to get that.

Share and Enjoy

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

Thanks for your response @DTS Engineer

In my app , i dont want to show any UI to user because user will be using this app just to do some background task like importing some data etc. So that our primary application which will be a different bundle can use that data which it may need during its launch (because of some reason it cann't get it using primary application itself). (This use can is just a example to explain what experience we want to give to user.)

In this application, we wanted to have user experience , where user can double click on app icon and launch it . And then application will do its work and close . Since we have to give double click experience to user, we need to use a bundle application.

We were using UIApplicationMain which will start a NSRunLoop to block main thread , until we finish our work on worker thread. And we were able to achive our objective using this approach.

But since we dont have to show any UI to user , we were thinking can we use CFRunLoop to block main thread. We need a event loop (blocking main thread is just one example, we may also need to listen to some events etc on event loop)

In this application, we wanted to have user experience, where user can double click on app icon and launch it. And then application will do its work and close.

There’s no good way to do this because, fundamentally, it’s not a standard Mac user experience. Whatever you do is gonna be weird. Even if the code is 100% fine, the user experience will not fit in with the rest of the platform.

A better option would be for your app to have a minimal UI. This isn’t a big ask. It’d just display a standard menu bar and a window, allowing the user to understand that it’s running, quit the app, and so on.

we may also need to listen to some events etc on event loop)

What sort of events are we talking about here?

Share and Enjoy

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

Can we create a bundled non-interactive macOS application which uses CFRunLoop only(instead of using NSApplicationMain to run NSRunLoop)?
 
 
Q