When my app enter to background, I start a background task, and when Expiration happens, I end my background task. The code likes below:
backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
if (backgroundTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
backgroundTask = UIBackgroundTaskInvalid;
[self cancel];
}
});
}];
When the breakpoint is triggered at the endBackgroundTask line, I also get the following log:
[BackgroundTask] Background task still not ended after expiration handlers were called: <UIBackgroundTaskInfo: 0x282d7ab40>: taskID = 36, taskName = Called by MyApp, from MyMethod, creationTime = 892832 (elapsed = 26). This app will likely be terminated by the system. Call UIApplication.endBackgroundTask(:) to avoid this.
The log don't appear every time, so why is that? Is there something wrong with my code?
Processes & Concurrency
RSS for tagDiscover how the operating system manages multiple applications and processes simultaneously, ensuring smooth multitasking performance.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm a developer using Lazarus Pascal, so converting ObjC and Swift comes with its challenges.
I'm trying to figure how to properly use SMAppService to add my application as a login item for the App Store.
I have learned that the old method (< macOS 13) uses a helper tool, included in the app bundle, which calls the now deprecated SMLoginItemSetEnabled. Now this is already quite a pain to deal with if you're not using XCode, not to mention converting the headers being rather complicated when you're not experienced with doing this.
The "new" method (as of macOS 13) is using SMAppService.
Can anyone explain how to use this? The documentation (for me anyway) is a not very clear about that and neither are examples that can be found all over the Internet.
My main question is:
Can I now use the SMAppService functions to add/remove a login item straight in my application, or is a helper tool still required?
I am trying to create an app bundle with an xpc service. The main app creates a keychain item, and attempts to share (keychain access groups) with the xpc service it includes in its bundle. However, the xpc service always encounters a 'user interaction not allowed' error regardless of how I create the keychain item. kSecAttrAccessiblei is set to kSecAttrAccessibleWhenUnlockedThisDeviceOnly, the keychain access group is set for both the main app and the xpc service and in the provisioning profile. I've tried signing and notarizing.
Is it ever possible for an xpc service to access the keychain? This all on macos 15.5.
Hi, I'm working on an application on MacOS. It contains a port-forward feature on TCP protocol.
This application has no UI, but a local HTTP server where user can access to configure this application.
I found that my application always exit for unknown purpose after running in backgruond for minutes. I think this is about MacOS's background process controlling.
Source codes and PKG installers are here: https://github.com/burningtnt/Terracotta/actions/runs/16494390417
Hi there,
I'm trying to work on an architecture where one app exposes an API (Extension Host) that other apps can plugin to. I've been reading all I can from the docs and whatever I can find online. It seemed like iOS26 added the ability to do such a thing (at least in early builds).
Is that the case?
Has the functionality been walked back such that extensions can only be loaded in iOS from within the single app bundle?
My use case is the following:
I'm working on an agent app that desires to have 3rd party developers add functionality (think how MCP servers add functionality to LLMs). The 3rd party plugins would be provided in their own app bundles vetted by the AppStore review team, of course, and would only provide hooks, basically, the main app can use to execute functions or get state.
This is the best thread I found on the topic, and the subtext is that it needs to be in the same bundle. https://developer.apple.com/forums/thread/803896?answerId=865314022#865314022
Let's say for the moment that this isn't possible using ExtensionKit. What's the best way to achieve this? Our current best alternative idea is a hidded WebKit window that runs JS/WASM but that's so hackish.
Please let me know, thanks!
Hello,
I have a question about a edge case scenario.
Before that some info on my project-
I have a launchdaemon that carries out some business logic, it also has XPC listener (built using C APIs).
Question-
Can there be a situation when the daemon is up and running but the XPC listener is down(due to some error or crash)? If yes then do I need to handle it in my code or launchd will handle it?
when the daemon is stopped or shut down, how do I stop the XPC listener? After getting listener object from xpc_connection_create_mach_service should I just call xpc_connection_cancel followed by a call to xpc_release?
Thanks!
K
The following code worked as expected on iOS 26 RC, but it no longer works on the official release of iOS 26.
Is there something I need to change in order to make it work on the official version?
Registration
BGTaskScheduler.shared.register(
forTaskWithIdentifier: taskIdentifier,
using: nil
) { task in
//////////////////////////////////////////////////////////////////////
// This closure is not called on the official release of iOS 26
//////////////////////////////////////////////////////////////////////
let task = task as! BGContinuedProcessingTask
var shouldContinue = true
task.expirationHandler = {
shouldContinue = false
}
task.progress.totalUnitCount = 100
task.progress.completedUnitCount = 0
while shouldContinue {
sleep(1)
task.progress.completedUnitCount += 1
task.updateTitle("\(task.progress.completedUnitCount) / \(task.progress.totalUnitCount)", subtitle: "any subtitle")
if task.progress.completedUnitCount == task.progress.totalUnitCount {
break
}
}
let completed = task.progress.completedUnitCount >= task.progress.totalUnitCount
if completed {
task.updateTitle("Completed", subtitle: "")
}
task.setTaskCompleted(success: completed)
}
Request
let request = BGContinuedProcessingTaskRequest(
identifier: taskIdentifier,
title: "any title",
subtitle: "any subtitle",
)
request.strategy = .queue
try BGTaskScheduler.shared.submit(request)
Sample project code:
https://github.com/HikaruSato/ExampleBackgroundProcess
I'm troubleshooting a crash I do not understand.
I have a queue called DataQueue which never has anything dispatched to it - it's the sample buffer delegate of an AVCaptureVideoDataOutput. It can call DispatchQueue.main.sync to do some work on the main thread.
It works fine no matter what we test, but has some crashes in the field that I need to fix. Here's it crashing:
AppleCameraDataDelegate.dataQueue
0 libsystem_kernel.dylib 0x7bdc __ulock_wait + 8
1 libdispatch.dylib 0x4a80 _dlock_wait + 52
2 libdispatch.dylib 0x486c _dispatch_thread_event_wait_slow$VARIANT$mp + 52
3 libdispatch.dylib 0x113d8 __DISPATCH_WAIT_FOR_QUEUE__ + 332
4 libdispatch.dylib 0x10ff0 _dispatch_sync_f_slow + 140
The main thread isn't doing something I asked it to, but appears to be busy:
Thread
0 libsystem_kernel.dylib 0x71a4 __psynch_cvwait + 8
1 libsystem_pthread.dylib 0x7fd8 _pthread_cond_wait$VARIANT$mp + 1232
2 grpc 0x2cb670 gpr_cv_wait + 131 (sync.cc:131)
3 grpc 0x119688 grpc_core::Executor::ThreadMain(void*) + 225 (executor.cc:225)
4 grpc 0x2e023c grpc_core::(anonymous namespace)::ThreadInternalsPosix::ThreadInternalsPosix(char const*, void (*)(void*), void*, bool*, grpc_core::Thread::Options const&)::'lambda'(void*)::__invoke(void*) + 146 (thd.cc:146)
5 libsystem_pthread.dylib 0x482c _pthread_start + 104
6 libsystem_pthread.dylib 0xcd8 thread_start + 8
Can anyone help me understand why this is a crash?
Started a new X-Code Project after updating to 26.0.1 and realized that I get an error when trying to mark a class as ObservableObject => "Class XYZ does not conform to Protocol 'ObservableObject'.
Strange behaviour, because at old projects the code is working even though the build options are the same and other settings like iOS version in Target are the same.
There must be something chaged under the hood of XCode? I have to import Combine now, before I could write my class, e.g. CoreData Datamanager: ObservableObject only using CoreData.
We are building a 'server' application that can either run as a daemon or can run in background without showing any GUI. Basically, the end user can either configure this to run as a daemon so that it can be tied to the user's session or will launch the process which user will start and quit as needed.
I wanted to understand what is the recommended mechanism for such an application from Apple -
Should this application be built as a macOS Bundle ? Apple documentation also says that we should not daemonize the process by calling fork. Hence if we create a unix-style executable, will I not need to fork to make it run in a detached state when I launch the executable via double-click ? [Reference Link]
Is it fine to have an application on macOS which is a bundle but does not show any UI when launched by double click on the app-icon or via 'open'? While we have been able to achieve this by using NSApplicationMain and not showing the UI, was wondering if using CFRunLoop is best for this case as it is a non-gui application.
If we can get the right documentation link or recommendations on how we should build such an application which can run in a non-gui mode and also in a daemonized manner, it will help us.
Should the application be always built as a macos bundle or should it be a unix-style executable to support both the cases - by the same application/product and how should we look at the distribution of such applications.
Our app will launch automatically in the background,Doubt is the result of background fetch ,so we cancel the background modes setting of the background fetch,but we still can see the performFetchWithCompletionHandler method called when app launch in the background。Background launch will cause some bugs in our app. We don't want the app to start in the background. We hope to get help
I have an app for macOS that is built using Mac Catalyst. I need to perform some background processing. I'm using BGProcessingTaskRequest to schedule the request. I have also integrated CKSyncEngine so I need that to be able to perform its normal background processing.
On iOS, when the user leaves the app, I can see a log message that the request was scheduled and a bit later I see log messages coming from the actual background task code.
On macOS I ran the app from Xcode. I then quit the app (Cmd-q). I can see the log message that the request was scheduled. But the actual task is never run. In my test, I ran my app on a MacBook Pro running macOS 26.0. When I quit the app, I checked the log file in the app sandbox and saw the message that the task was scheduled. About 20 minutes later I closed the lid on the MacBook Pro for the night. I did not power down, it just went to sleep. Roughly 10 hours later I opened the lid on the MacBook Pro, logged in, and checked the log file. It had not been updated since quitting the app. I should also mention that the laptop was not plugged in at all during this period.
My question is, does a Mac Catalyst app support background processing after the user quits the app? If so, how is it enabled?
The documentation for BGProcessingTaskRequest and BGProcessingTask show they are supported under Mac Catalyst, but I couldn't find any documentation in the Background Tasks section that mentioned anything specific to setup for Mac Catalyst.
Running the Settings app and going to General -> Login Items & Extension, I do not see my app under the App Background Activity section. Does it need to be listed there? If so, what steps are needed to get it there?
If this is all documented somewhere, I'd appreciate a link since I was not able to find anything specific to making this work under Mac Catalyst.
Topic:
App & System Services
SubTopic:
Processes & Concurrency
Tags:
CloudKit
macOS
Mac Catalyst
Background Tasks
Hello,
I'm experiencing an issue with my app where it's being terminated by the system with a watchdog violation during back-to-back messaging operations. I've analyzed the crash logs but would appreciate additional insights on optimizing my approach. I'd appreciate any insights on how to resolve this problem.
Crash Details:
Exception Type: EXC_CRASH (SIGKILL)
Termination Reason: FRONTBOARD with code 0x8BADF00D
Error: "scene-update watchdog transgression: app exhausted real time allowance of 10.00 seconds"
Reproduction Steps:
User A initiates back-to-back messages to other User
User A's UI becomes unresponsive and eventually the app crashes.
Stack Trace Analysis:
The crash occurs on the main thread, which appears to be blocked waiting for a condition in the keyboard handling system. The thread is stuck in [UIKeyboardTaskQueue _lockWhenReadyForMainThread] and related methods, suggesting an issue with keyboard-related operations during the messaging process.
Crash Tag
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: FRONTBOARD 2343432205
<RBSTerminateContext| domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: app<com.msikodiak.eptt(AD934F8A-DF57-4B75-BE73-8CF1A9A8F856)>:301 exhausted real (wall clock) time allowance of 10.00 seconds
ProcessVisibility: Foreground
ProcessState: Running
WatchdogEvent: scene-update
WatchdogVisibility: Background
WatchdogCPUStatistics: (
"Elapsed total CPU time (seconds): 6.390 (user 3.640, system 2.750), 11% CPU",
"Elapsed application CPU time (seconds): 0.020, 0% CPU"
)
ThermalInfo: (
"Thermal Level: 0",
"Thermal State: nominal"
) reportType:CrashLog maxTerminationResistance:Interactive>
Triggered by Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x1e773d438 __psynch_cvwait + 8
1 libsystem_pthread.dylib 0x2210bc328 _pthread_cond_wait + 1028
2 Foundation 0x1957d8a64 -[NSCondition waitUntilDate:] + 132
3 Foundation 0x1957d8888 -[NSConditionLock lockWhenCondition:beforeDate:] + 80
4 UIKitCore 0x1998f1238 -[UIKeyboardTaskQueue _lockWhenReadyForMainThread] + 456
5 UIKitCore 0x19a3d775c __59-[UIKeyboardImpl updateAutocorrectPrompt:executionContext:]_block_invoke_9 + 28
6 UIKitCore 0x19986b084 -[UIKeyboardTaskQueue lockWhenReadyForMainThread] + 168
7 UIKitCore 0x19a3f2994 -[UIKeyboardTaskQueue waitUntilTaskIsFinished:] + 148
8 UIKitCore 0x19a3f2ac4 -[UIKeyboardTaskQueue performSingleTask:breadcrumb:] + 132
9 UIKitCore 0x199e2f7e4 -[_UIKeyboardStateManager updateForChangedSelection] + 144
10 UIKitCore 0x199e24200 -[_UIKeyboardStateManager invalidateTextEntryContextForTextInput:] + 92
11 WebKit 0x1ad52fa54 WebKit::PageClientImpl::didProgrammaticallyClearFocusedElement(WebCore::ElementContext&&) + 40
12 WebKit 0x1ad55adcc WebKit::WebPageProxy::didProgrammaticallyClearFocusedElement(WebCore::ElementContext&&) + 136
13 WebKit 0x1acec74e8 WebKit::WebPageProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 18604
14 WebKit 0x1acd21184 IPC::MessageReceiverMap::dispatchMessage(IPC::Connection&, IPC::Decoder&) + 236
15 WebKit 0x1ace449b8 WebKit::WebProcessProxy::dispatchMessage(IPC::Connection&, IPC::Decoder&) + 40
16 WebKit 0x1ace44228 WebKit::WebProcessProxy::didReceiveMessage(IPC::Connection&, IPC::Decoder&) + 1764
17 WebKit 0x1acd1e904 IPC::Connection::dispatchMessage(WTF::UniqueRef<IPC::Decoder>) + 268
18 WebKit 0x1acd1e478 IPC::Connection::dispatchIncomingMessages() + 576
19 JavaScriptCore 0x1ae386b8c WTF::RunLoop::performWork() + 524
20 JavaScriptCore 0x1ae386960 WTF::RunLoop::performWork(void*) + 36
21 CoreFoundation 0x196badce4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
22 CoreFoundation 0x196badc78 __CFRunLoopDoSource0 + 172
23 CoreFoundation 0x196bac9fc __CFRunLoopDoSources0 + 232
24 CoreFoundation 0x196babc3c __CFRunLoopRun + 840
25 CoreFoundation 0x196bd0700 CFRunLoopRunSpecific + 572
26 GraphicsServices 0x1e3711190 GSEventRunModal + 168
27 UIKitCore 0x1997ee240 -[UIApplication _run] + 816
28 UIKitCore 0x1997ec470 UIApplicationMain + 336
29 Telstra PTT 0x1004d30c8 main + 56
30 dyld 0x1bd5d3ad8 start + 5964
Hi,
I have a sandboxed app with a bundled sandboxed XPC service. When it’s launched, the XPC service registers a repeating XPC activity with the system. The activity’s handler block does get called regularly like I’d expect, but it stops being called once the main app terminates.
What’s the recommended way to fix this issue? Could I have a bundled XPC service double as a launch agent, or would that cause other problems?
For some reason, after invoking an unrelated dlclose() call to unload any .dylib that had previously been loaded via dlopen(..., RTLD_NOW), the subsequent call to task_info(mach_task_self(), TASK_DYLD_INFO, ...) syscall returns unexpected structure in dyld_uuid_info image_infos->uuidArray, that, while it seems to represent an array of struct dyld_uuid_info elements, there is only 1 such element (dyld_all_image_infos *infos->uuidArrayCount == 1) and the app crashes when trying to access dyld_uuid_info image->imageLoadAddress->magic, as image->imageLoadAddress doesn't seem to represent a valid struct mach_header structure address (although it looks like a normal pointer within the process address space. What does it point to?).
This reproduces on macOS 15.4.1 (24E263)
Could you please confirm that this is a bug in the specified OS build, or point to incorrect usage of the task_info() API?
Attaching the C++ file that reproduces the issue to this email message
It needs to be built on macOS 15.4.1 (24E263) via Xcode or just a command line clang++ compiler. It may crash or return garbage, depending on memory layout, but on this macOS build it doesn’t return a correct feedfacf magic number for the struct mach_header structure.
Thank you
Feedback Assistant reference: FB18431345
//On `macOS 15.4.1 (24E263)` create a C++ application (for example, in Xcode), with the following contents. Note, that this application should crash on this macOS build. It will not crash, however, if you either:
//1. Comment out `dlclose()` call
//2. Change the order of the `performDlOpenDlClose()` and `performTaskInfoSyscall()` functions calls (first performTaskInfoSyscall() then performDlOpenDlClose()).
#include <iostream>
#include <dlfcn.h>
#include <mach/mach.h>
#include <mach-o/dyld_images.h>
#include <mach-o/loader.h>
void performDlOpenDlClose() {
printf("dlopen/dlclose function\n");
printf("Note: please adjust the path below to any real dylib on your system, if the path below doesn't exist!\n");
std::string path = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libswiftDemangle.dylib";
printf("Dylib to open: %s\n", path.c_str());
void* handle = ::dlopen(path.c_str(), RTLD_NOW);
if(handle) {
::dlclose(handle);
} else {
printf("Error: %s\n", dlerror());
}
}
void performTaskInfoSyscall() {
printf("Making a task_info() syscall\n");
printf("\033[34mSource File: %s\033[0m\n", __FILE__);
task_t task = mach_task_self();
struct task_dyld_info dyld_info;
mach_msg_type_number_t size = TASK_DYLD_INFO_COUNT;
kern_return_t kr = task_info(task, TASK_DYLD_INFO, (task_info_t)&dyld_info, &size);
if (kr != KERN_SUCCESS) {
fprintf(stderr, "task_info failed: %s\n", mach_error_string(kr));
}
const struct dyld_all_image_infos* infos =
(const struct dyld_all_image_infos*)dyld_info.all_image_info_addr;
printf("version: %d, infos->infoArrayCount: %d\n", infos->version, infos->infoArrayCount);
for(uint32_t i=0; i<infos->infoArrayCount; i++) {
dyld_image_info image = infos->infoArray[i];
const struct mach_header* header = image.imageLoadAddress;
printf("%d ", i);
printf("%p ", (void*)image.imageLoadAddress);
printf("(%x) ", header->magic);
printf("%s\n", image.imageFilePath);
fflush(stdout);
}
printf("\n\n");
printf("infos->uuidArrayCount: %lu\n", infos->uuidArrayCount);
for(uint32_t i=0; i<infos->uuidArrayCount; i++) {
dyld_uuid_info image = infos->uuidArray[i];
const struct mach_header* header = image.imageLoadAddress;
printf("%d ", i);
printf("%p ", (void*)image.imageLoadAddress);
printf("(%x)\n", header->magic);
fflush(stdout);
}
printf("task_info() syscall result processing is completed\n\n");
}
int main(int argc, const char * argv[]) {
performDlOpenDlClose();
performTaskInfoSyscall();
return 0;
}
I have an app that uses background audio recording. From what others say, I have enabled the audio background mode to keep the audio session active, and this worked. But when submitting the app to the app store, the app was rejected because the audio background mode is only supposed to be used for audio playback.
How do I create this background mode while following Apple's guidelines?
when we use raise in GCD, the signal handler is executed asynchronously, whereas in pthread, it is executed synchronously as expected.
example:
#include <Foundation/Foundation.h>
#include <pthread/pthread.h>
static void HandleSignal(int sigNum, siginfo_t* signalInfo, void* userContext) {
printf("handle signal %d\n", sigNum);
printf("begin sleep\n");
sleep(3);
printf("end sleep\n");
}
void InstallSignal(void) {
static const int g_fatalSignals[] =
{
SIGABRT,
SIGBUS,
SIGFPE,
SIGILL,
SIGPIPE,
SIGSEGV,
SIGSYS,
SIGTRAP,
};
int fatalSignalsCount = sizeof(g_fatalSignals) / sizeof(int);
struct sigaction action = {{0}};
action.sa_flags = SA_SIGINFO | SA_ONSTACK;
#if defined(__LP64__)
action.sa_flags |= SA_64REGSET;
#endif
sigemptyset(&action.sa_mask);
action.sa_sigaction = &HandleSignal;
struct sigaction pre_sa;
for(int i = 0; i < fatalSignalsCount; i++) {
int sigResult = sigaction(g_fatalSignals[i], &action, &pre_sa);
}
}
void* RaiseAbort(void *userdata) {
raise(SIGABRT);
printf("signal handler has finished\n");
return NULL;
}
int main(int argc, const char * argv[]) {
InstallSignal();
dispatch_async(dispatch_get_global_queue(0, 0), ^{
raise(SIGABRT);
// abort(); // abort() is ok
RaiseAbort(nullptr);
});
// pthread is ok
// pthread_t tid;
// int ret = pthread_create(&tid, NULL, RaiseAbort, NULL);
// if (ret != 0) {
// fprintf(stderr, "create thread failed\n");
// return EXIT_FAILURE;
// }
[[NSRunLoop mainRunLoop] run];
return 0;
}
console log:
signal handler has finished
handle signal 6
begin sleep
end sleep
Hello,
I have a few questions regarding the documentation here:
Can this method described in the article be built with Xcode 26 and run on iOS 26? Or is it restricted to run only on iOS 26, since AppExtensionPoint appears to be available starting from iOS 26?
Does this approach allow two apps under the same Team ID to communicate with each other?
Does this approach also allow two apps under different Team IDs to communicate with each other?
Is it mandatory to implement EXAppExtensionBrowserViewController and obtain user consent before using this method to exchange information?
In our implementation, we followed the documentation. Inside EXAppExtensionBrowserViewController, we were able to see the Generic Extension from another app and enabled the permission.
However, we still get the following error:
Failed to connect: Error Domain=NABUExtensionConnector Code=1
"No matching extension found"
UserInfo={NSLocalizedDescription=No matching extension found}
Could someone clarify whether this is expected behavior, or if we are missing an additional configuration step?
Thanks in advance!
What’s the recommended way to recursively walk through a directory tree using File Coordination? From what I understand, coordinating a read of a directory only performs a “shallow” lock; this would mean that I’d need to implement the recursive walk myself rather than use FileManager.enumerator(at:includingPropertiesForKeys:options:errorHandler:) plus a single NSFileCoordinator.coordinate(with:queue:byAccessor:) call.
I’m trying to extract information from all files of a particular type, so I think using NSFileCoordinator.ReadingOptions.immediatelyAvailableMetadataOnly on each file before acquiring a full read lock on it (if it’s the right file type) would make sense. Am I on the right track?
Hello,
https://developer.apple.com/forums/thread/802443
https://developer.apple.com/documentation/servicemanagement/updating-helper-executables-from-earlier-versions-of-macos
https://developer.apple.com/documentation/ServiceManagement/updating-your-app-package-installer-to-use-the-new-service-management-api#Run-the-sample-launch-agent
Read these.
Earlier we had a setup with SMJobBless, now we have migrated to SMAppService.
Everything is working fine, the new API seems easier to manage, but we are having issues with updating the daemon.
I was wondering, what is the right process for updating a daemon from app side?
What we are doing so far:
App asks daemon for version
If version is lower than expected:
daemon.unregister(), wait a second and daemon.register() again.
The why?
We have noticed that unregistering/registering multiple times, of same daemon, can cause the daemon to stop working as expected. The daemon toggle in Mac Settings -> Login Items & Extensions can be on or off, but the app can still pickup daemon running, but no daemon running in Activity monitor. Registration/unregistration can start failing and nothing helps to resolve this, only reseting with sfltool resetbtm and a restart seems to does the job. This is usually noticeable for test users, testing same daemon version with different app builds.
In production app, we also increase the bundle version of daemon in plist, in test apps we - don't.
I haven't found any sources of how the update of pre-bundled app daemon should work.
Initial idea is register/unregister, but from what I have observed, this seems to mess up after multiple registrations.
I have a theory, that sending the daemon a command to kill itself after app update, would load the latest daemon.
Also, I haven't observed for daemon, with different build versions to update automatically.
What is the right way to update a daemon with SMAppService setup?
Thank you in advance.