I have a process [command line cpp application] which i want to run always such as it should relaunch after a crash, after device startup etc.
I created a launchd Property List File with KeepAlive true and placed under /Library/LaunchDaemons.
Problem Statements:
I have a bash script to start and stop this process.
start using: launchctl bootstrap.
stop involve these two steps:
send SIGTERM signal and wait untill process stops after doing some cleanups
launchctl bootout [It doesn't sends SIGTERM]
during steps 1 - Process is getting stop, but also getting immediate relaunch by launchctl
during step 2 - it getting stop again.
is there a proper way so that we can disable KeepAlive temporarily so that process will not launch during step 1?
or suggest other ways to handle this?
Inter-process communication
RSS for tagShare data through Handoff, support universal links to your app's content, and display activity-based services to the user using inter-process communication.
Posts under Inter-process communication tag
18 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
In my project, i have a Swift class with a class level property of type string. Like this :
class TWSwiftString {
var pString:String!
init(_ pString: String) {
self.pString = pString
}
}
I am creating intance of this class and then creating a opaque pointer to this intance. Like this :
let str = TWSwiftString("World")
// Increasing RC by 1
strptr = Unmanaged.passRetained(str).toOpaque()
Now using this opaque pointer i want to modify the value of pString by directly operating on memory. Like this:
withUnsafeMutablePointer(to: &strptr.pString) { strPointer in
strPointer.pointee = "World"
}
Although i am able to modify pString like this and print. Lets assume i have a approach to make sure memory remains valid when it is operated on and freeing of memory is also handled somehow .
Will this approach work if i have 100s of intance of this string which are being operated in this manner ? What if the size of new value is greater than existing string value ? For this i am thinking of chunk of memory initially and then keep on increasing size of it as bigger string then this chunk comes. Does this approach seems feasible ? Any other problems i can encounter by using this approach ?
Chatgpt gave this answer :
To directly update the memory of a Swift class’s property, particularly to alter a String property, is generally discouraged due to Swift's memory safety model. However, if we want to access and modify a class property directly, the best practice is to use a property accessor, as manually altering memory could lead to undefined behavior or even crashes. Why Direct Memory Manipulation Is Risky When you attempt to manipulate memory directly, especially with Swift’s memory model, you might alter not only the value but also the memory layout of Swift’s String type, which could break things internally. The Swift compiler may store String differently based on the internal structure, so even if we manage to locate the correct memory address, directly modifying it is unreliable.
do you have any opinion around chatgpt resoponse ?
Title: SafariViewService Recurring "Hard Refresh" Issue on iOS 18.0.1
Hello,
Many of my app users are experiencing a recurring "hard refresh" issue related to SafariViewService, which appears only on iOS 18.0.1 across various iPhone models. Users on earlier iOS versions are not encountering this problem.
Our app relies on SafariViewService, and the logs show an event triggered by an EXC_GUARD exception with a termination reason from LIBXPC, causing the app to stop. Below are key details from the log report:
App Version: 4.1.2 (build 4.1.1.0)
OS Version: iPhone OS 18.0.1
Exception Type: EXC_GUARD
Subtype: GUARD_TYPE_USER
Termination Reason: LIBXPC, XPC_EXIT_REASON_FAULT
Device Model: iPhone 11 Pro Max
Process Path: [Removed]
Here’s an excerpt from the logs:
...
{"codes":"0x6000000000000007, 0x0000000000000009","reason":9,"message":"namespc 7 reason_code 0x0000000000000009","subtype":"GUARD_TYPE_USER","type":"EXC_GUARD","rawCodes":[Removed],"namespc":7},
"termination" : {"flags":518,"code":9,"namespace":"LIBXPC","indicator":"XPC_EXIT_REASON_FAULT"},
...
I would greatly appreciate any guidance on resolving this issue, particularly if there are known concerns with inter-process communication (LIBXPC) in iOS 18.0.1 or advice on how to manage the EXC_GUARD exception more effectively.
Full log details are in the attachment.
Thank you for your help!
ExcUserFault_SafariViewService-2024-10-10-102717 (1).ips
ExcUserFault_OnixWorker.Maui-2024-10-10-102718 (1).ips
Thank you for your help!
I've developed a Endpoint Security system extension, which will be installed in a container APP.
I use XPC to send message from container APP to the ES client, it works fine.
I have developed an Endpoint Security system extension that will be installed in a container app.
I utilize XPC to send messages from the container app to the ES client, and it functions properly. However, when I attempt to send messages from the ES client to the container app, it always displays an error: 'Couldn’t communicate with a helper application.'.
I have removed the sandbox capability of the container app and also employed the same app group for both the ES client and the container app. When an XPC client is connected, I use the following code in the ES client to establish two-way communication.
- (BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection {
newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(NXFileGuardXPCProtocol)];
NXFileGuardXPCService *xpcService = [NXFileGuardXPCService sharedInstance];
newConnection.exportedObject = xpcService;
// To APP container client (As remote interface)
newConnection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(NXFileGuardXPCClientProtocol)];
[newConnection activate];
self.containerAPPConnection = newConnection;
return YES;
}
But it always fails. How can I deal with this error?
When users share a file with my app I am having trouble 5-10% of the time obtaining the file meta data, specifically creation and modified time and size.
Using SwiftUI with the code below..
.onOpenURL { url in
var fileSize: Int64 = 0
var creationTime: Date = Date(timeIntervalSince1970: 0)
var modificationTime: Date = Date(timeIntervalSince1970: 0)
do {
let fileAttributes = try FileManager.default.attributesOfItem(atPath: url.path)
fileSize = fileAttributes[FileAttributeKey.size] as? Int64 ?? 0
creationTime = fileAttributes[FileAttributeKey.creationDate] as? Date ?? Date(timeIntervalSince1970: 0)
modificationTime = fileAttributes[FileAttributeKey.modificationDate] as? Date ?? Date(timeIntervalSince1970: 0)
<SNIPPED CODE no other tries though and not involving above variables>
} catch {
// quite confident I am ending up here because variables after the above code aren’t being set and there are no other try blocks,
// so FileManager.default.attributesOfItem(atPath: url.path) must be throwing….
}
<SNIPPED CODE>
To attempt to resolve this, I added in a 0.5 second wait cycle if creationTime == 0 and modificationTime == 0 , so if obtaining both metadata fails, wait 0.5 seconds and try again, try this a max of 3 times and then give up. I don’t know how often I am entering this code (didn’t instrument the app for it), but am still getting times when metadata comes back blank which means this code wasn’t successful after 3 tries.
I assume the file would only become visible and sharable with my app after it has completed being written by the original app/process. Perhaps it hasn’t finalized yet? Is there a way to detect this so I can tell the user in my share screen to wait and try again?
I am assuming that the file has finished writing though since when I read the data from the file contents, it’s good data and complete even when metadata failed.
I will be instrumenting the above code in my next app version, just hoping to fix it right now since users are emailing saying my app is broken.
Thanks!
We need to read the value for userActivity.referrerUrl when the app is accessed through a Universal Link, which when using the UIKit lifecycle we can easily do by implementing the method scene(_: UIScene, continue: NSUserActivity) in SceneDelegate and filtering for activity type of NSUserActivityTypeBrowsingWeb.
When the app uses the SwiftUI lifecycle that method doesn't get called, even though the app is correctly configured to use AppDelegate and SceneDelegate (through the @UIApplicationDelegateAdaptor wrapper). I can confirm that the setup is correct because the method scene(_: UIScene, willConnectTo: UISceneSession, options: UIScene.ConnectionOptions) in SceneDelegate is called on app launch.
The obvious SwiftUI way of achieving the same would be by using the .onContinueUserActivity(NSUserActivityTypeBrowsingWeb) modifier, but that doesn't work. Is this a bug?
Hi all,
I wonder if anyone can shed any light or tips on this.
We have our iOS app which is just for iPhone at the moment. I have some universal links that are currently working. I have added another '/mobileAppQuickLink' into the file and updated on our site in the '.well-known' folder location.
The issue I am having is, all of the links before the additional one mentioned above are working.
Steps Checked
Checked https://app-site-association.cdn-apple.com/a/v1/OUR_DOMAIN to make sure the latest AASA file is there, it is.
Checked the sysdiagnosis package logs and can see in the 'swcutil_show.txt' that only the original three are there for the app and not the final one.
Reinstalled the app multiple time to bring down the AASA, no luck.
Wiped a device and reset, downloaded the app again, no luck.
The code below is the AASA file with our app ID redacted. I have triple checked these and they haven't changed from the previous.
"applinks": {
"details": [
{
"appIDs": [
"A646R8---.com.REDACTED.REDACTED"
],
"components": [
{
"#": "no_universal_links",
"exclude": true,
"comment": "Matches any URL with a fragment that equals no_universal_links and instructs the system not to open it as a universal link."
},
{
"/": "/client/*",
"comment": "Matches any URL with a path that starts with /client/."
},
{
"/": "/files/*",
"comment": "Matches any URL with a path that starts with /files/."
},
{
"/": "/signingRequests/*",
"comment": "Matches any URL with a path that starts with /signingRequests/."
},
{
"/": "/mobileAppQuickLink" //MISSING ON DEVICE
}
]
}
]
},
"webcredentials": {
"apps": [
"A646R8----com.REDACTED.REDACTED"
]
}
}
Below is a copy of one of the 'swcutil_show.txt' from a device.
App ID: A646R8----.com.REDACTED.REDACTED
App Version: 1.1.70
App PI: <LSPersistentIdentifier 0x88c027a80> { v = 0, t = 0x8, u = 0x548, db = 514601C3-79C8-47C6-A178-B09AF5C-----, {length = 8, bytes = 0x4805000000000000} }
Domain: *.portal.staging.REDACTED.REDACTED
Patterns: {"#":"no_universal_links","exclude":true}, {"/":"/client/*"}, {"/":"/files/*"}, {"/":"/signingRequests/*"}
User Approval: unspecified
Site/Fmwk Approval: approved
Flags:
Last Checked: 2024-08-04 09:44:07 +0000
Next Check: 2024-08-09 09:39:26 +0000
Does anyone know of any reason this could be? It looks like the devices maybe getting a cached version.
I want to share a Transferable (JSON-encoded) data struct from some HostApp with an Extension of my ContainingApp, and get a different Transferable (also JSON-encoded) data struct back on success.
Since I want to present my ContainingApp's AppIcon in the sharing sheet to make it easy for the user to find it, I started building a Sharing Extension and not an Action Extension.
AFAIK the difference is only in the presentation (Sharing Extension: Icon+name of the ContainingApp vs Action Extension: simple b/w system icon plus a string describing the action (e.g. "Copy", "Save to Files")), and the data flow is identical. Please correct me if I'm wrong.
I added the Sharing Extension to my ContainingApp (which are both in the same app group so they can use a shared container to exchange data).
The (real) HostApp is from a different company we are collaborating with, and thus is not in our app group.
Once everything runs I will add a tailored NSExtensionActivationRule to make sure our Sharing Extension is only shown to our partner's HostApp. Currently I am still using TRUEPREDICATE.
The goal is that after the user tapped the "Continue with ContainingApp" (Share-)button in the HostApp, iOS will only show my ContainingApp icon and nothing else, since that's the only useful choice for the user.
Side Question 1: The best user experience would be if the HostApp could directly present our extension when the user tapped the "Continue with ContainingApp"-button, without the user needing to choose it manually in the Share-sheet, but I guess this is not possible for privacy/security reasons, right?
In the debugger of the HostApp I see this error:
Type "com.myapp.shareInput" was expected to be exported in the Info.plist of Host.app, but it was imported instead.
Library: UniformTypeIdentifiers | Subsystem: com.apple.runtime-issues | Category: Type Declaration Issues
but I definitely want to define and export both ShareInput and ShareResult as UTExportedTypeDeclarations in my extension, and all 3rd-party apps (like this demo HostApp) using my extension need to import them.
Side Question 2: Can I just ignore this error? And tell the 3rd-party app developers they also can ignore it?
After the user tapped on the ContainingApp icon in the sharing dialog, my Sharing Extension will show its dialog, presenting the shared item it got from the HostApp, and let the user edit the text.
When the user taps the "Save"-button in my extension, it creates a ShareResult struct to send back to the HostApp, and dismisses the sheet.
This (kinda) works when I share plain text with the Text button in my HostApp.
My ContainingApp icon is shown together with Mail, Messages, and other apps that can process plain text; with shortcuts to persons and devices (AirDrop targets) in the line above, and with actions (Copy, New Quick Note, Save to Files, Save to Citator, Certificat, Airdrop) below.
When I choose my ContainingApp, the extension runs and shows the text it got.
("Kinda" because I am still struggling to send data back. See below...)
So the principal operation works...
Side Question 3: In the HostApp, can I use ShareLink() to present the Share-sheet and receive the result struct or do I always need to
activityViewController!.completionWithItemsHandler = completionHandler
windowScene.keyWindow?.rootViewController?.present(activityViewController!, animated: true, completion: nil)
and process the result in the completionHandler?
If returning (any) data from the extension is possible with ShareLink() also, then how? I didn't find any sample showing this...
I implemented the ShareLink() anyway (and ignore the result part for the moment).
When I try to share a ShareInput struct with the ShareLink button, the same persons are sorted differently, there are less app icons (9 instead of 13), and less actions (only 3: New Quick Note, Save to Files, AirDrop):
Note that while the preview correctly shows the preview text provided ("shareInput"), the preview image left of it is blank (instead of arrowshape.right.fill):
let preview = SharePreview("shareInput", image: Image(systemName: "arrowshape.right.fill"))
When I choose my ContainingApp, the extension runs ...
On iOS17, I see that indeed my ShareInput data arrived in my extension:
❗️itemProvider=<NSItemProvider: 0x301b1c460> {types = (
"com.myapp.shareInput"
)}
Library: ShareExtension | Subsystem: com.myapp.containingdemo.ShareExtensionDemo | Category: ShareSheet
However, on iOS 16 it doesn't work:
Host[8615:634470] [Type Declaration Issues] Type "com.myapp.shareInput" was expected to be exported in the Info.plist of Host.app, but it was imported instead.
Host[8615:634462] [ShareSheet] Couldn't load file URL for Collaboration Item Provider:<NSItemProvider: 0x280f49180> {types = (
"com.myapp.shareInput"
)} : (null)
That error is shown before I choose the ContainingApp to share with.
When I do that, I get:
ShareExtension[8774:636786] [ShareSheet] ❗️itemProvider=<NSItemProvider: 0x28243a300> {types = (
"dyn.age8u",
"public.file-url"
)}
which clearly shows the ShareInput struct was not transferred to the extension.
But since I don't know how to transfer the ShareResult back to the HostApp when using a ShareLink, I cannot continue this approach anyway.
When I try to share a ShareInput struct with the JSON button (using present(activityViewController)), I see (both on iOS 16 and iOS 17):
My extension (rather, the ContainingApp's icon) is not shown as Sharing target (even though it still has TRUEPREDICATE), which means that my code didn't manage to pack the ShareInput struct for the activityViewController - and thus it doesn't know what to share.
I did the same as with the plainText item before:
let shareInput = ShareInput(inputStr: "ShareInput as JSON")
let preview = SharePreview("shareInput", image: Image(systemName: "arrowshape.right.fill"))
VStack(spacing: 25.0) {
Text("HostApp!")
ShareButton(title: "Text", shareItems: [ItemSource(dataToShare: "sharing some text")])
ShareButton(title: "JSON", shareItems: [ItemSource(dataToShare: shareInput)])
ShareLink("ShareLink", item: shareInput, preview: preview)
}
(I will continue in the next posting)
Hello,
As of iOS 17, the keyboard app runs in a different process. I was wondering if there is a way to access the UIView of the keyboard app or if there is a way to subscribe to touch events done on the keyboard (especially during the trackpad mode).
By trackpad mode I mean when the user long presses on space and then can move in the keyboard area (that turns into a trackpad) to move the caret in a text.
Either Objective C or SwiftUI is fine.
Thanks!
I am working on an App and I am in the process of adding Syphon support.
Syphon uses CFMessagePort for IPC and passing of FrameBuffer data (MTLTexture) between apps - and is widely used in the professional video app and video production space.
What I have noticed is that when the App is built as a Sandbox app, during the Syphon initialization, I see the following error message in the log:
*** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x8703, name = 'info.v002.Syphon.D2499DBD-93AE-4CEA-B21F-FF356DCC069D'
See /usr/include/servers/bootstrap_defs.h for the error codes.
Syphon uses the "info.v002.Syphon.UUID" naming convention to identify IPC Syphon servers, so I don't think I can use the App Groups naming convention for Sandbox support.
I have a very simple example app on github that publishes SpriteKit frames as a Syphon Server. To see the issue, simply enable App Sandbox for the build, and run the app. You should see the error message in the log and no data appears in any Syphon Client (I use Syphon Recorder for testing - available at syphon.github . io
I am looking for other options to enable CFMessagePorts on a Sandbox App.
Hi
There is a critical code section between the app and its app extensions that needs to be synchronized and done atomically.
What would be a suitable solution to achieve locking and synchronization between app’s processes? Is there a way to share memory or an operation queue between the app and its app extensions?
Thank you
Hi,
I have two iOS apps in the same app group. Now App 1 wants to execute a method in App 2 via IPC:
App 1 -> call method test() via IPC on App 2 -> App 2 returns the result to App 1.
Is this possible?
Regards,
I have used
[[NSDistributedNotificationCenter defaultCenter] addObserver
in process AA to listen notification from other process BB, It works fine.
But when make the observer process AA as a launch daemon (which is started by launchd), It found below difference.
If run process BB as root privilege, AA can not receive notification posted by BB.
If make process BB as a launch daemon, AA can receive notification posted by BB.
What was happened in above difference, It can not find any document about this, Thanks.
We have app and notification extension both loading an agent lib to access the same files with read/write/delete operations. To avoid app and notification extension access the file simultaneously, we use boost::interprocess::file_lock when app enters foreground and notification extension didReceive notifications. If extension failed to grab file lock, it will skip loading agent and returns. If app failed to grab file lock, it will start a timer to keep trying while UI will display spinner. Sometimes we saw crash report from our app with:
Exception Type: EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: RUNNINGBOARD 3735883980
Triggered by Thread: 0
The code 3735883980 indicate "deadlock" - The operating system terminated the app because it held on to a file lock or SQLite database lock during suspension.
In sysdiagnose, we also see "[osservice<com.apple.InputUI>:1496] check if suspended process is holding locks" in runningboardd process. Does it mean that our app fail to unlock?
We did lock when app enters foreground and unlock when app goes to background. Is there anything we did wrong?
@implementation FileLock
-(id)init
{
self = [super init];
if (nil != self)
{
// Find empty lock file, created if it doesn't exist.
FILE *file = fopen(lockFile.c_str(), "a");
if (file)
{
fclose(file);
}
m_lock = boost::make_shared<boost::interprocess::file_lock>(lockFile.c_str());
}
return self;
}
-(BOOL)lock
{
return m_lock->try_lock();
}
-(void)unlock
{
return m_lock->unlock();
}
@end
func applicationDidBecomeActive(_ application: UIApplication)
{
if !bFileLockAcquired
{
if fileLock.lock()
{
bFileLockAcquired = true
// load agent
}
else
{
lockTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { _ in
DispatchQueue.main.async {
if fileLock.lock()
{
self.lockTimer?.invalidate()
self.lockTimer = nil
bFileLockAcquired = true
// load agent
}
}
})
}
}
func applicationDidEnterBackground(_ application: UIApplication)
{
self.lockTimer?.invalidate()
self.lockTimer = nil
fileLock.unlock()
bFileLockAcquired = false
}
My goal is to create a communication mechanism between the UI test runner and my app. That way I can tell the app to display specific data (without laboriously going through the UI steps of getting the app into that state) and also read the values stored as a result of simulated user actions.
So, what are the best options for that kind of IPC? So far I have tried NWListener and friends, but it looks like I'd have to add entitlements to my app, which I'd rather avoid since this is only for testing. Can I have the app listening for some kind of IPC connection without requiring entitlements?
Hello,
we are currently working on a plan to migrate our app suite from Developer ID binaries inside a simple pkg installer to macOS app store distribution.
The reason we are using an installer is that there are multiple binaries inside that communicate via XPC and we need to install the respective launchd plist in /Library/LaunchDaemons and /Library/LaunchAgents:
1 root daemon
1 agent that has minimal UI and lives in the system menu bar
1 embedded command line utility in user agent
1 embedded FileProvider extension in user agent
1 embedded Action Extension in user agent
1 agent that only does OAuth stuff
Looking through Updating helper executables from earlier versions of macOS I can install the root daemon with SMAppService.daemon(plistName:) and the OAuth helper with SMAppService.agent(plistName:). For the main application I only found SMAppService.mainApp which does not accept a property list configuration. Therefore, I have no place to put my MachServices array and so the File Provider extension, the Action Extension, and the embedded command line utility have no way to talk to the user agent.
Currently, XPC is used in between these processes:
user agent -> root daemon
command line utility -> user agent
action extension -> user agent
file provider extension -> user agent
user agent -> file provider extension: that already works through NSFileProviderServicing
I know app-to-app communication only works through launchd for security reasons, but these applications are all part of the same app group (except the root daemon obviously).
My question is what is the proper way of starting the user agent so XPC from other binaries just work ™️?
Any input is much appreciated!
I'm trying to use task_for_pid in a project but I keep getting error code 5 signaling some kind of signing error. Even with this script I cant seem to get it to work.
#include <mach/mach_types.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/mach_traps.h>
#include <stdio.h>
int main(int argc, const char * argv[]) {
task_t task;
pid_t pid = argc >= 2 ? atoi(argv[1]) : 1;
kern_return_t error = task_for_pid(mach_task_self(), pid, &task);
printf("%d -> %x [%d - %s]\n", pid, task, error, mach_error_string(error));
return error;
}
I've tried signing my executables using codesign and also tried building with Xcode with the "Debugging Tool" box checked under hardened runtime. My Info.plist file includes the SecTaskAccess key with the values "allowed" and "debug." Hoping someone can point me towards what I'm missing here. Thanks!
I have successfully implemented Universal Links so that a visitor to specific URLs on our site is redirected to one of our apps. It all works well. Alarmingly well, in that it all worked perfectly first time. (I blame the documentation).
A question I can't find specifically addressed in the documentation is: what if we have two apps that can both handle a given link? This is in fact our situation.
In most cases users will have one or other of the apps installed. The correct behaviour would then be to direct the user to the installed app.
In some cases the user will have both apps installed. In that case the ideal behaviour would be to direct the user to what we have defined to be the "main" app.
It looks to me as if it is possible to two apps in an apple-app-site-association file, but not having found this in the documentation, I wonder: has anyone on here actually tried this? Did it work as expected?