Post not yet marked as solved
Can NSXPCInterface work with non-void return type?
The official document says, "All messages must be 'void' return type." (Reference)
However, in the file provider sample code of wwdc21, it uses it with non-void return type.
(Reference)
I wondered whether it can or can not be used with non-void return type?
Is the answer changed after swift support for async/await?
Post not yet marked as solved
how to obtain information about transmission errors such as overrun, framing, parity, and
break signals?
I have an app with the following simple architecture:
Main App: A regular macOS app bundle with UI that allows users to customize settings of the app
Helper: Another macOS app bundle with no UI (LSUIElement=1 in Info.plist) that is packaged inside the main app in the LoginItems directory doing the core tasks of the app in the background
My requirements are:
Distribution via the MAS (=sandbox enabled for both targets)
Both apps should be able to communicate via XPC
The main app should be closable by the user at any time, should not keep running after being closed, whereas the helper app should as it performs actions for which it needs to be kept running in the background
Launch-on-login of the helper app should not (and according to 2.4.5 (iii) of the ASRG must not) happen automatically w/o user consent and therefore I assume should always be a checkbox optional to the user
For sharing settings changed by the user in the main app with the helper too, I've added the Application Group capability to both targets to allow usage of a common user defaults suite.
While that works fine, there's the requirement that from within the main app I'd also need to request information and call a method from the background process (bidirectional communication) which is where I'm currently stuck.
I understand that an XPC Service (.xpc) would not be suitable for the helper here because it is automatically terminated when the parent app dies and may also not be suitable for my use cases as the helper needs to be able to request Screen Capture permissions from the user and I doubt this is possible for XPC bundles. I also understand that an XPC service which utilizes a mach-service XPC listener will only work in a sandboxed environment through the use of Service Management's SMLoginItemSetEnabled() API.
My main issue here is that the mandatory requirement to leave the option to launch the helper on login open to the user conflicts with the requirement of being able to communicate with the helper via XPC any time the main app is open, regardless of user choices.
If there wasn't the requirement to sandbox both apps, I would solve this issue with a launchd user agent that is kept alive but only runs at load if the user checked the launch-on-login box in the Settings of the main app. With sandbox enabled though, I'm currently launching the helper app manually if launch-on-login is disabled and let the Service Management API handle the lifecycle if it is enabled. For the first case, I haven't been able to establish an XPC connection w/o calling SMLoginItemSetEnabled() and I assume that is by design.
Is there something obvious I've missed here as I kinda feel like this is a typical app setup many other 3rd party devs are having as well?
Post not yet marked as solved
I built an app which hosts a CMIOExtension. The app works, and it can activate the extension. The extension loads in e.g. Photo Booth and shows the expected video (a white horizontal line which moves down the picture).
I have a couple of questions about this though.
The sample Camera Extension is built with a CMIOExtension dictionary with just one entry, CMIOExtensionMachServiceName which is $(TeamIdentifierPrefix)$(PRODUCT_BUNDLE_IDENTIFIER)
This Mach service name won't work though. When attempting to activate the extension, sysextd says that the extensions has an invalid mach service name or is not signed, the value must be prefixed with one of the App Groups in the entitlement.
So in order to get the sample extension to activate from my app, I have to change its CMIOExtensionMachServiceName to
<my team ID>.com.mycompany.my-app-group.<myextensionname>
Is this to be expected?
The template CMIOExtension generates its own video using a timer. My app is intended to capture video from a source, filter that video, then feed it to the CMIOExtension, somehow. The template creates an app group called "$(TeamIdentifierPrefix)com.example.app-group", which suggests that it might be possible to use XPC to send frames from the app to the extension.
However, I've been unable to do so. I've used
NSXPCConnection * connection = [[NSXPCConnection alloc] initWithMachServiceName:, using the CMIOExtensionMachServiceName with no options and with the NSXPCConnectionPrivileged option. I've tried NSXPCConnection * connection = [[NSXPCConnection alloc] initWithServiceName: using the extension's bundle identifier. In all cases when I send the first message I get an error in the remote object proxy's handler:
Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named <whatever name I try> was invalidated: failed at lookup with error 3 - No such process."
According to the "Daemons and Services Programming Guide" an XPC service should have a CFBundlePackageType of XPC!, but a CMIOExtension is of type SYSX. It can't be both.
Does the CMIOExtension loading apparatus cook up a synthetic name for the XPC service, and if so, what is it? If none, how is one expected to get pixel buffers into the camera extension?
Post not yet marked as solved
How can I exchange information easily and securely between 2 apps on macOS?
1 of the app will infrequently request a short amount of data from the other one.
Here are the options that I can see:
DistributedNotificationCenter : very easy to implement. However, the notifications are broadcast to any apps that wants to listen to it, and apple's documentation clearly states that it's not secure. I would ideally like a mechanism that is as simple as this, but with a secure communication between 2 aps
Apple Events. I am not sure how to make an app respond to apple event. And I think it would be the same problem : any other app could talk to these 2 apps and get information from them. I ideally want this to be more secure.
XPC, this seems overly complex for what I want to do, as my understanding is that this essentially involves creating a third process that will regulate communication.
Implementing IPC via sockets. It seems reasonable I think, as I can probably secure the communication better. However it feels over-enigneered to set up sockets that always listen for incoming connections, etc
Am I missing a simple mechanism on macOS that could help me in that use case?
Or am I looking at things incorrectly for one of these options?
Thanks!
Post not yet marked as solved
Hi,
We are building an sandbox enabled app which contains
1. One launch daemon
2. One launch agent
3. System extension which is contained in launch agent
The launch daemon is outside of the sandbox. The launch agent and system extension is inside the sandbox.
The launch agent is in good communicating with system daemon already. But recently the use case I am meeting is to comunnication between launch agent, launch daemon and systen extension daemon.
1. Launch agent sends request to launch daemon
2. launch daemon sends response to launch agent
And
1. System extension sends request to launch daemon
2. Launch daemon sends response to system extension
I have read some articles on the forum and understand that we can use machServices to make the XPC connection fulfilled in launch daemon.
And we can use com.apple.security.temporary-exception.mach-lookup.global-name to eliminate the sandbox limitation between the daemon and agents.
But when we do experiment, it always return
Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.*****.******" UserInfo={NSDebugDescription=connection to service named com.****.*****}
I understand that the suggested debug method is making anonymous listener in the same process. But that looks like more for XPC service. I am not sure how to debug
in the launchd. Is there any suggestion?
BTW, the daemon is mainly implemented in C++ and the agent is in swift. So I use NSXPCConnection on both sides. I am wondering if it is the best fit for our purpose.
Is there any good example that I can follow?
Post not yet marked as solved
Previously discussed in beta:https://forums.developer.apple.com/message/330295This process stops responding every day it seems, I'm running 10.14.3 (18D109)When the process hangs, its Open Files and Ports include the following:txt
/Library/Preferences/Logging/.plist-cache.ZP6RP0OT
txt
/private/var/db/timezone/tz/2018i.1.0/icutz/icutz44l.dat
txt
/usr/share/icu/icudt62l.dat
txt
/private/var/folders/35/dgpwsg457w17gs77hssnrbnw0000gn/0/com.apple.LaunchServices-231-v2.csstoreThose are not open when the service is running (before it hangs)Would like to know how frequently this hangs for everyone else and get steps to troubleshoot if possible.
Post not yet marked as solved
I discovered that an app I downloaded for a desktop clock had been starting at login automatically. When I changed that selection so it wasn't starting at login, I started getting this error. When I changed it back to "start at login" I stopped getting this error. I hope this is helpful.
Post not yet marked as solved
This is new Catalina behavior. The file access error described below never happened on Mojave and High Sierra.My sandboxed Mac App store app includes a sandboxed XPC helper service in its app bundle.The XPC helper service has the standard entitlements: com.apple.security.app-sandbox and com.apple.security.inheritThe host app creates a document file in its own sandbox container's Caches directory. After the save operation completes,it invokes a method on the XPC service, sending the document's URL. That method on the XPC service tries to open and read the document file at that URL.Error Received: The file couldn’t be opened because you don’t have permission to view it. Permission denied.So then I tried an experiment where the user would select a folder for the XPC service to put files using NSSavePanel.The document was then written there by the host app.XPC service could not open the file either. The file couldn’t be opened because you don’t have permission to view it. Permission denied.In both instances, the XPC service did not "inherit" the sandbox state of its host app. This violates the com.apple.security.inherit entitlement.The radar report is: FB7450619
Post not yet marked as solved
XPC is the preferred inter-process communication (IPC) mechanism on Apple platforms. XPC has two APIs:
The high-level NSXPCConnection API, for Objective-C and Swift
The low-level C API, which, while callable from all languages, works best with C-based languages
General:
DevForums tag: XPC
NSXPCConnection class documentation
XPC C API documentation
XPC has extensive man pages — For the C API, start with the xpc man page; this is the original source for the XPC C API documentation and still contains tidbits that you can’t find elsewhere. Also read the xpcservice.plist man page, which documents the property list format used by XPC services.
Daemons and Services Programming Guide archived documentation
Technote 2083 Daemons and Agents — It hasn’t been updated in… well… decades, but it’s still remarkably relevant.
TN3113 Testing and Debugging XPC Code With an Anonymous Listener
Related tags include:
Inter-process communication, for other IPC mechanisms
Service Management, for installing and uninstalling Service Management login items, launchd agents, and launchd daemons
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Post not yet marked as solved
I thought Swift wasn't supposed to get them, which is part of the reason why I chose to use it for my network extension. But we're getting crashes occasionally, that look like:
Thread 4 Crashed:: Dispatch queue: com.apple.NSXPCConnection.user.endpoint
0 com.kithrup.MyApp.NExt 0x102c4ffe2 MyExt.sendData(_:data:completion:) + 610
1 com.kithrup.MyApp.NExt 0x102c5091f @objc MyExt.sendData(_:data:completion:) + 255
2 Foundation 0x7ff81ef97490 __NSXPCCONNECTION_IS_CALLING_OUT_TO_EXPORTED_OBJECT_S3__ + 10
3 Foundation 0x7ff81ef3fa1f -[NSXPCConnection _decodeAndInvokeMessageWithEvent:flags:] + 2322
4 Foundation 0x7ff81eef641e message_handler + 206
5 libxpc.dylib 0x7ff81de24b6c _xpc_connection_call_event_handler + 56
6 libxpc.dylib 0x7ff81de23947 _xpc_connection_mach_event + 1382
7 libdispatch.dylib 0x7ff81df2e3b1 _dispatch_client_callout4 + 9
8 libdispatch.dylib 0x7ff81df47041 _dispatch_mach_msg_invoke + 445
9 libdispatch.dylib 0x7ff81df341cd _dispatch_lane_serial_drain + 342
10 libdispatch.dylib 0x7ff81df47b77 _dispatch_mach_invoke + 484
11 libdispatch.dylib 0x7ff81df341cd _dispatch_lane_serial_drain + 342
12 libdispatch.dylib 0x7ff81df34e30 _dispatch_lane_invoke + 417
13 libdispatch.dylib 0x7ff81df3eeee _dispatch_workloop_worker_thread + 753
14 libsystem_pthread.dylib 0x7ff81e0e1fd0 _pthread_wqthread + 326
The XPC method is func sendData(_: UUID, data: Data?, completion: @escaping (_: Error?) -> Void)
It's crashing on address 0x10, so pretty clearly a NULL-dereference.
Since this is happening in my extension, it's in Swift (as I said above), so I have no idea what could be NULL without the compiler yelling at me first.
Is it better to
Create an NSXPCConnection, keep it around, and create proxies using that as needed, or
Create an NSXPCConnection, create a proxy off of it, and then close the connection when done?
Post not yet marked as solved
We see warnings like this logged by our processes using XPC:
(Foundation) [com.apple.runtime-issues:Foundation] *** -[NSXPCDecoder validateAllowedClass:forKey:]: NSSecureCoding allowed classes list contains [NSObject class], which bypasses security by allowing any Objective-C class to be implicitly decoded. Consider reducing the scope of allowed classes during decoding by listing only the classes you expect to decode, or a more specific base class than NSObject. This will become an error in the future. Allowed class list: {(
"'NSObject' (0x7ff844ee0d88) [/usr/lib]"
)}
As far as we can see, there is no explicit NSObject in allowed classes for any XPC connection. Where does this list and NSObject come from?
Post marked as Apple Recommended
Quinn, you've often suggested that to validate the other side of an XPC connection, we should use the audit token. But that's not available from the XPC object, whereas the PID is. So everyone uses the PID.
While looking for something completely unrelated, I found this in the SecCode.h file
OSStatus SecCodeCreateWithXPCMessage(xpc_object_t message, SecCSFlags flags,
SecCodeRef * __nonnull CF_RETURNS_RETAINED target);
Would this be the preferred way to do this now? At least from 11.0 and up.
Like I said, I was looking for something completely unrelated and found this and don't have the cycles right now to try it. But it looks promising from the description and I wanted to check in with you about it in case you can say yes or no before I get a chance to test it.
Thanks
Post not yet marked as solved
I'm trying to send an IOSurfaceRef across an NSXPCConnection on osx 10.13 and I'm having trouble with the solution that was provided in the forum thread "Efficiently sending data from an XPC process to the host application." https://developer.apple.com/forums/thread/126716 From that thread:
> However, that specific problem got resolved on 10.12 where we introduced a new Objective-C
IOSurface
object, and that object is transportable directly over
NSXPCConnection
. So double yay!
But it doesn’t seem to work. I have a very simple service protocol that includes
(void)sendFrame:(IOSurfaceRef)frame;
along with some basic NSString sending methods that successfully transfer across my NSXPCConnection. I have a valid (non-NULL) IOSurface in my app that I send to my helper app with sendFrame, and when the call is executed in the helper, the resulting frame is always NULL.
On the other hand, I’ve also tried creating an IOSurface with the (deprecated) kIOSurfaceIsGlobal property and sending the IOSurface’s ID instead with:
(void)sendFrameID:(uint32_t)frameID;
and
[_service sendFrameID:IOSurfaceGetID(surface)];
And on the helper app side, I look up the IO to get an IOSurfaceRef:
IOSurfaceRef frame = IOSurfaceLookup(frameID);
and it works correctly – I get a valid IOSurface which I can display and see the same pixel contents in both the app and the helper.
So what is meant by the new IOSurface object in 10.12 is “transportable directly” over NSXPCConnection? How is it supposed to work? I’m specifically interested in no-copy transfer. Thanks!
Post not yet marked as solved
I've configured an item and placeholder in NSFileProviderExtension iOS extension, and an XPC service in the provider (based on the template for XPC service for Mac, but as part of the NSFileProviderExtension
When connecting to the service from the app using code example in getFileProviderServicesForItem I am getting an error straight in the completion handler of that function:
Error Domain=NSCocoaErrorDomain Code=4097 "Error while sending identifierForItemAtURL:completionHandler:" UserInfo={NSDebugDescription=Error while sending identifierForItemAtURL:completionHandler:, NSUnderlyingError=0x2833640c0 {Error Domain=NSCocoaErrorDomain Code=4097 "connection from pid 30324 on anonymousListener or serviceListener" UserInfo={NSDebugDescription=connection from pid 30324 on anonymousListener or serviceListener}}}
Could you maybe suggest what I am missing? Or, is there an example somewhere of the FileProvider extension with the service being called from the app?
Code:
File Provider service definition: https://github.com/simplex-chat/simplex-chat/blob/af3dcc4a9a9b24751bf9d74af67cf8e7d119597a/apps/ios/SimpleX%20Service/SimpleXFPService.swift
Application code that calls the service: https://github.com/simplex-chat/simplex-chat/blob/af3dcc4a9a9b24751bf9d74af67cf8e7d119597a/apps/ios/Shared/FPService.swift
Thank you!
Post not yet marked as solved
I have an application which is doing screen recording, now I move the screen recording feature to a standalone native XPC module for better performance due to some reason that the app is tied an old lib which cannot generate native code for M1 (Intel only).
My question is that, this new xpc module is belong to the App (demanded by the app), if I give the screen recording permission to the app, will the xpc screen scraping module be granted to the permission?
Right now looks like it is not after I granted the application with the screen recording permission since display stream won't produce the frame data.
Post not yet marked as solved
In my project I have a host application and a husk application.
What I want to do is, every time the user launches a new view in the host application, I want to create one more dock icon by launching another instance of husk application. Then the husk application behaves like it is the view itself by monitoring the event of click/quit and send them to the host application through XPC.
The XPC tutorial tells me an XPC service embedded in an application is invisible to the processes outside the bundle. To communicate between two foreground applications it seems that I need to create a third helperTool/agent/daemon which venders a Mach/XPC service.
But I wonder if I can put husk application inside the bundle of the hose application. So they can directly connect to the XPC service which is also embedded in the same bundle.
If the answer is no, maybe NSDistributedNotificationCenter is much better and simpler in my scenario?
Post not yet marked as solved
Hello
We are developing our own iOS Network Extensions-based VPN and it has an HTTP proxy in the VPN.
In addition, we also use PAC (Proxy auto-configuration) script to configure what kind of HTTP/HTTPS traffic should route to our proxy in the VPN.
However, we get this kind of message "Received XPC error Connection invalid for message type 3 kCFNetworkAgentXPCMessageTypePACQuery" randomly on iOS 15.5.
We have not been aware of any weird behavior of iOS based on the error message. We are afraid of this error message is caused by our VPN solution.
Is there any suggestion that should consider or follow to fix this error?
Post not yet marked as solved
I am trying to figure out how to programatically install a per-user launchd agent - I have an executable Swift script I wrote and I need macOS to enforce it always be running. I found the SMJobBless sample code which I could play with to see how this works, but it hasn't been updated since it was last built with Xcode 4.6. As you can imagine it doesn't compile in Xcode 10. I was able to get it to build by upgrading to the recommended project settings, increasing the deployment target, and selecting my team for the two targets. Following the ReadMe I need to run ./SMJobBlessUtil.py setreq to configure the Info.plists appropriately. These instructions are out of date but eskimo was kind enough to provide updated instructions here to find the .app url. But when I do this and run the command I receive the following output:MacBook:SMJobBless Jordan$ ./SMJobBlessUtil.py setreq /Users/Jordan/Library/Developer/Xcode/DerivedData/SMJobBless-dffakkidazmiowcishyrborysygm/Build/Products/Debug/SMJobBlessApp.app SMJobBlessApp/SMJobBlessApp-Info.plist SMJobBlessHelper/SMJobBlessHelper-Info.plist
Traceback (most recent call last):
File "./SMJobBlessUtil.py", line 424, in
main()
File "./SMJobBlessUtil.py", line 418, in main
setreq(appArgs[1], appArgs[2], appArgs[3:])
File "./SMJobBlessUtil.py", line 360, in setreq
appToolDict[bundleID] = toolNameToReqMap[bundleID]
KeyError: '$(PRODUCT_BUNDLE_IDENTIFIER)'It would seem this python script isn't able to work with the newer project structures, not surprisingly. I wasn't able to find any other information on how to accomplish this task in the modern days. So could you please explain how to go about this? 🙂I have an executable .swift file and a .plist that works when loaded from ~/Library/LaunchAgents/ ready to be added to an existing Xcode project. Thanks!