OS debug logs not visible in console when macOS is closed

Overview

  • When the macOS app is closed, the os logs (debug) logs are not visible in the Console app.
  • However even when the iOS app is closed / killed, the os logs (debug) logs are visible in the Console app.

What I have tried

  • Console app menu Action > Include Debug Messages is checked
  • Searched by subsystem
  • Created a macOS app from the archive by choosing selecting Debugging option

Note

  • OS debug logs are visible when the macOS app is open

Questions

  1. How can I make macOS debug logs visible in the Console app when the Mac app is closed?
  2. Should I be searching by some other fields?
  3. Or is there any other alternative / workaround this because I need to debug this scenario when app is closed?
Answered by DTS Engineer in 898190022
This is a macOS native app.

OK.

In general, macOS will not launch apps in the background in response to a silent push. That’s because macOS has a very different app model than iOS. Specifically, macOS makes it clear to the user which apps are running, in both the Dock and the app switcher. If macOS launched apps in the background like iOS does, that’d be very jarring for users.

Keep in mind that macOS’s app model is a lot more flexible than iOS’s. So you don’t need to be launched in the background by a silent push because you can just run indefinitely in the background. You can do that from your main app, but you can also do it from a background-only or UI element app that you install using SMAppService.

Share and Enjoy

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

I’d like to clarify the actual problem here. Lemme explain how I tested this, and you can then highlight where I went wrong.

Here’s what I did today:

  1. Using Xcode 26.6 on macOS 26.5.2, I created a new project from the macOS > App template.
  2. I updated ContentView.swift to log some stuff at the .debug level. I’ve included the full code below.
  3. I built the app using Xcode.
  4. I launched Console and started a search for the com.example.apple-samplecode.Test838090 subsystem.
  5. I launched my app from the Finder.
  6. I clicked the Test button twice.
  7. In Console I see the two log entries.
  8. I then quit the app.
  9. I still see the log entries.
  10. I launched the app again.
  11. I clicked the Test button five times. This causes the app to log and then immediately terminate.
  12. In Console I see all five log entries.

This all seems pretty reasonable to me, so I’m curious how this is different from your setup.

Share and Enjoy

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


import SwiftUI
import os.log

// subsystem:com.example.apple-samplecode.Test838090
let log = Logger(subsystem: "com.example.apple-samplecode.Test838090", category: "app")

struct ContentView: View {
    @State var counter = 0
    var body: some View {
        VStack {
            Button("Test") {
                log.debug("Hello Cruel World!, counter: \(counter)")
                counter += 1
                if counter >= 5 {
                    _Exit(0)
                }
            }
        }
        .padding()
    }
}

#Preview {
    ContentView()
}

Thanks Quinn @DTS Engineer, It was my fault I should have been more clear about my scenario.

My Scenario

Explanation

  • My macOS app is fully closed
  • I don't tap on the macOS app icon
  • The macOS app listens to (silent notifications, no UI notification) remote notifications for data update.
  • When the macOS app receives this notification, the app is woken up however no UI is presented (as expected) and calls application(_:didReceiveRemoteNotification:)

Summary

  • For macOS app the debug logs inside application(_:didReceiveRemoteNotification:) are not called when app is closed and is woken by silent notifications.
  • I know the macOS app is woken up because the data refresh happens, just that that the logs are not visible in the console.
  • However for iOS app the debug logs inside application(_:didReceiveRemoteNotification) async -> UIBackgroundFetchResult are visible in the console app.

Is this a native macOS app? Specifically, in Xcode, in the General tab of the target editor, does the Supported Destinations > Mac entry say “Mac”? Or do you see “Mac (Mac Catalyst)” or “Mac (Designed for iPad)”?

Share and Enjoy

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

@DTS Engineer

  • This is a macOS native app.
  • To be specific it is a Multiplatform app, so it is a macOS app and not a Mac catalyst app.
Accepted Answer
This is a macOS native app.

OK.

In general, macOS will not launch apps in the background in response to a silent push. That’s because macOS has a very different app model than iOS. Specifically, macOS makes it clear to the user which apps are running, in both the Dock and the app switcher. If macOS launched apps in the background like iOS does, that’d be very jarring for users.

Keep in mind that macOS’s app model is a lot more flexible than iOS’s. So you don’t need to be launched in the background by a silent push because you can just run indefinitely in the background. You can do that from your main app, but you can also do it from a background-only or UI element app that you install using SMAppService.

Share and Enjoy

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

@DTS Engineer thank you so much!!!! I have been breaking my over this for the past few days.

Wow, that is such a clear explanation.

You are spot on, on macOS silent push (remote) notifications are not received when app is closed.

I will try to read on SMAppService, you also mentioned you can do it from the main app, are there any pointers on how to do that?

are there any pointers on how to do that?

I have links to all sorts of good stuff in Service Management Resources.

However, it’s quite possible that you’ll want to change your overall strategy here. Most folks use silent push notifications on iOS because iOS doesn’t give them any good way to run in the background. See iOS Background Execution Limits.

macOS has no such limitation, and so you might consider skipping push notifications entirely on that platform. Rather, have your background-executing code connect directly to your server and receive change notifications on that connection.

Of course, that may or may not be possible depending on how your server is set up.

There’s also a general app architecture issue. Given the iOS design, it’s common for folks to put all of their model-level code into the app itself. On macOS, however, it might make sense to split it out. So you have a background process that talks to the server and maintains your local model, and then you have a GUI app that simply acts as a UI to that model. The app would then talk to the background process via an IPC mechanism, such as XPC.

Of course, the user might not consent to you running your background process all the time, so you need some way to make this work in that case. You can do that a couple of ways:

  • Put this model maintenance code into a framework and run the code in either your app or your background process, depending on the user’s preference.
  • Keep the split, but manually launch the background process when your app launches, and manually quit it when your app quits.

Share and Enjoy

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

@DTS Engineer thank you so much. Thanks for patiently answering my questions, really appreciate it. The links are so cool, I will go through those links.

My scenario

  • I have an app which stores data using SwiftData / CloudKit automatic sync
  • It works well, except when Mac app is closed and the data from the CloudKit is not pulled into the DB on the Mac.
  • It would be nice if the widget on the Mac is updated even when the Mac app is closed. Like from a sync from an iPhone.

My problem:

  • I don't do anything for sync other than just initializing the ModelContainer and everything is taken care of.
  • The local store has its own system level tables to maintain the sync states. So I am a bit hesitant to do a separate sync in the background process (LoginItem / LaunchAgent / LaunchDaemon.

I need to read a lot on this because I am just beginning to explore this part

Questions

  • Is it feasible / advisable to have one instance of the ModelContainer created in the background process and access it in the main app for the Mac?
  • Reason for asking is because ModelContainer is the one that does all the sync magically.
  • Or is this too much of an overhead and users can open the app to keep the widget updated?

I’m gonna recommend that you start a new thread with this question. This thread was about OSLog, and I think that’s adequately resolved. Your latest question is about a bunch of other stuff — SwiftData, CloudKit, widgets, process management, and so on — and needs to be looked at by different folks.

A variety of different subtopics would make sense for this, but let’s start out with App & System Services > SwiftData and then add other relevant tags (make sure to at least add Service Management, which makes sure I’ll see it).

Share and Enjoy

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

@DTS Engineer, sure will do that, thanks once again for patiently answering.

I will open new thread as you recommended

Would you think it would be better suited under App & System Services > iCloud and then tag SwiftData, Service Management?

The reason for thinking is a lot of it is to do with the remote notification.

New thread

OS debug logs not visible in console when macOS is closed
 
 
Q