XPC is a a low-level (libSystem) interprocess communication mechanism that is based on serialized property lists.

XPC Documentation

Pinned Posts

Posts under XPC tag

48 Posts
Sort by:
Post marked as solved
9 Replies
5.2k Views
Hello,Technical Note TN2151 describes the 0xdead10cc exception:> The exception code 0xdead10cc indicates that an application has been terminated by the OS because it held on to a file lock or sqlite database lock during suspension. If your application is performing operations on a locked file or sqlite database at suspension time, it must request additional background execution time to complete those operations and relinquish the lock before suspending.This is all pretty clear. After the additional background execution time has expired, all SQLite accesses that create a lock create a risk for sudden termination. An application which wants to avoid 0xdead10cc has thus to actively prevent such accesses... until the application wakes up from the suspended state. My questions are all about the end of this critical lapse of time in the app's life cycle.Eventually, the application may become active, and this clearly marks the end of the 0xdead10cc danger. This moment is notified by UIApplicationWillEnterForegroundNotification. After this notification is posted, it becomes possible again to access an SQLite database without risking any 0xdead10cc exception, until the next UIApplicationDidEnterBackgroundNotification, and the next notification of additional background execution time expiration.But what about cases when the application leaves the suspended state and reenters the background state? This may happen due to the various background modes supported by iOS.First question: Is there one way to be notified of this transition from suspended to background state, regardless of the reason for this background wake-up (core location, VoIP, background fetch, etc.) ?Second question: Is it then possible to start another request for additional background execution time and be reliably notified when accessing the SQLite database creates a 0xdead10cc threat again?Third question: do you have any other advice regarding 0xdead10cc prevention?For the context, I'm the author of GRDB, and I'm looking for a way to package 0xdead10cc prevention in a way that reduces to a minimum the amount of code users have to write in order to protect their app from this exception. Ideally, it would be reduced to a simple boolean flag targetted at users who store their database in an App Group container.Thank you very much!
Posted
by
Post not yet marked as solved
4 Replies
2.1k Views
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!
Posted
by
Post marked as solved
6 Replies
1.7k Views
Hello, I'm trying to get my app to communicate with a FinderSync extension using XPC. In my app, I run the listener: _xpcListener = [[NSXPCListener alloc] initWithMachServiceName:_serviceName]; _xpcListener.delegate = self; [_xpcListener resume]; Where _serviceName="a.b.c.d.e.f" In Info.plist of the app bundle, I have: keyMachServices/key dict keya.b.c.d.e.f/key true/ /dict In the FinderSync ext, I try to connect to the XPC service: _xpcConnection = [[NSXPCConnection alloc] initWithMachServiceName:_serviceName options:0]; ... [_xpcConnection resume]; It works in debug, but not when the app is installed. In this case, _xpcConnection.invalidationHandler is called. The FinderSync ext belongs to the app bundle. The .entitlements of the App: ?xml version="1.0" encoding="UTF-8"? !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "..." plist version="1.0" dict keycom.apple.security.application-groups/key array stringa.b.c.d.e/string /array /dict /plist The .entitlements of the FinderSync: ?xml version="1.0" encoding="UTF-8"? !DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "..." plist version="1.0" dict keycom.apple.security.app-sandbox/key true/ keycom.apple.security.application-groups/key array stringa.b.c.d.e/string /array /dict /plist The app is notorized: % spctl --assess -vvvv /Applications/myApp.app                 /Applications/myApp.app: accepted source=Notarized Developer ID origin=Developer ID Application: ... In the Console, just after the start of the listener, there is this error (3 times) for myApp process: Trust evaluate failure: [leaf TemporalValidity] So I checked its certificates, but they are valid: % codesign -dvvvv --extract-certificates /Applications/myApp.app % openssl x509 -inform DER -in codesign0 -text ... Validity       Not Before: Jun 22 11:59:25 2020 GMT       Not After : Jun 23 11:59:25 2025 GMT .. % openssl x509 -inform DER -in codesign1 -text ... Validity       Not Before: Feb 1 22:12:15 2012 GMT       Not After : Feb 1 22:12:15 2027 GMT ... % openssl x509 -inform DER -in codesign2 -text ... Validity       Not Before: Apr 25 21:40:36 2006 GMT       Not After : Feb 9 21:40:36 2035 GMT ... The computer date is Ok: % date Thu Apr 8 09:20:44 CEST 2021 In the console, there is also this error for tccd process: Prompting policy for hardened runtime; service: kTCCServiceAppleEvents requires entitlement com.apple.security.automation.apple-events but it is missing for accessing={identifier=a.b.c.d.e, pid=12245, auid=501, euid=501, binary_path=/Applications/myApp.app/Contents/PlugIns/Extension.appex/Contents/MacOS/Extension}, requesting={identifier=com.apple.appleeventsd, pid=328, auid=55, euid=55, binary_path=/System/Library/CoreServices/appleeventsd}, I tried to add this com.apple.security.automation.apple-events entitlement to App and ext, but it didn't fix the problem. How can I debug this issue? Thank you.
Posted
by
Post marked as Apple Recommended
5k Views
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
Posted
by
Post not yet marked as solved
9 Replies
2.5k Views
Hi! I'm looking for some insight and guidance on using the Foundation.Process type with a PTY (Psuedo Terminal) so that the subprocess can accept input and behave as if it was running via a terminal. The reason for needing a PTY is that for programs like ssh or in my case (xcodes) which ask for user input including passwords, running these via Foundation.Process does not display the prompts to the user as the output is usually buffered (this works fine in the Xcode debugger console but when running via a real terminal that is buffered the prompts are never displayed in the terminal) Looking at other threads it seems like correct approach here is create a PTY and use the filehandles to attach to the Process. While I've got this to work to the point where prompts are now shown, I cant seem to figure out how to pass input back to the process as these are being controlled by the PTY. Here is my Process setup: let process = Process() // Setup the process with path, args, etc... // Setup the PTY handles var parentDescriptor: Int32 = 0 var childDescriptor: Int32 = 0 guard Darwin.openpty(&parentDescriptor, &childDescriptor, nil, nil, nil) != -1 else {   fatalError("Failed to spawn PTY") } parentHandle = FileHandle(fileDescriptor: parentDescriptor, closeOnDealloc: true) childHandle = FileHandle(fileDescriptor: childDescriptor, closeOnDealloc: true) process.standardInput = childHandle process.standardOutput = childHandle process.standardError = childHandle With this setup I then read the parent handle and output any result it gets (such as the input prompts): parentHandle?.readabilityHandler = { handle in   guard let line = String(data: handle.availableData, encoding: .utf8), !line.isEmpty else {     return   }   logger.notice("\(line)") } When process.run() is executed the program runs and I can see it asks for Apple ID: input in my terminal, however, when typing input into the terminal the process does not seem to react to this input. I've tried forwarding the FileHandle.standardInput: FileHandle.standardInput.readabilityHandler = { handle in   parentHandle?.write(handle.availableData) } But this doesn't seem to work either. What is the recommended way to setup a PTY with Foundation.Process for executing arbitrary programs and having them behave as if they were being run in a terminal context? Most of the resources I found online are about other languages and I'd like to stick with Foundation.Process vs. doing anything custom in C/C++ if possible as it just makes it easier to reason about / maintain. The resources for Swift on this topic are very lacking and I've checked out some open source projects that claim to do this but most require manually sending input to the PTY handle vs. accepting them from the user in a terminal. Any insight / help is very much appreciated!
Posted
by
Post not yet marked as solved
7 Replies
4.5k Views
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?
Posted
by
Post marked as Apple Recommended
6.4k Views
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?
Posted
by
Post not yet marked as solved
0 Replies
1.4k Views
XPC is the preferred inter-process communication (IPC) mechanism on Apple platforms. XPC has three APIs: The high-level NSXPCConnection API, for Objective-C and Swift The low-level Swift API, introduced with macOS 14 The low-level C API, which, while callable from all languages, works best with C-based languages General: DevForums tag: XPC Creating XPC services documentation NSXPCConnection class documentation Low-level API documentation XPC has extensive man pages — For the low-level API, start with the xpc man page; this is the original source for the XPC C API documentation and still contains titbits 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 WWDC 2012 Session 241 Cocoa Interprocess Communication with XPC — This is no longer available from the Apple Developer website )-: 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 XPC and App-to-App Communication DevForums post Validating Signature Of XPC Process DevForums post 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"
Posted
by
Post not yet marked as solved
2 Replies
1.4k Views
Hello, I'm working on an app that offers a VPN tunnel (NEPacketTunnelProvider) meant to be released both in Developer ID builds and App Store builds. I've implemented an IPC mechanism using IPCConnection from the filtering network traffic example code. For the system extension it works fine. For the app extension, I just can't connect to the mach service. In both cases the app is not sandboxed, but the extension is. I'm trying to figure out how to troubleshoot the issue. The plist file for the system extension has this key: <key>NetworkExtension</key> <dict> <key>NEMachServiceName</key> <string>$(TeamIdentifierPrefix)com.company.system.extension.bundle.id</string> <key>NEProviderClasses</key> <dict> <key>com.apple.networkextension.packet-tunnel</key> <string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string> </dict> </dict> Would the app network extension use the same NetworkExtension dictionary with a NEMachServiceName key for the mach service name? Any hints to help me debug this issue? I've tried using launchctl list to see if the mach service is up, but I'm not exactly sure what's a good way to use it. I've considered using sendProviderMessage to communicate with the tunnel from the main App, but the problem is that sometimes NEVPNManager.shared.connection as? NETunnelProviderSession is just nil (due to the cast), and I'm not sure why that's the case.
Posted
by
Post not yet marked as solved
4 Replies
4.8k Views
Hello everyone, With the MacOS update to Venture 13.2, I get the following error message when closing a MacOS app in xCode: [client] No error handler for XPC error: Connection invalid Today I set up a brand new MacOS system which has nothing more installed as except for MacOS Venture 13.2 and xCode 14.2 (14C18). The error already occurs when I start an app that only contains template code. I also started the app without xCode and then closed it through the menu. Then I do not receive an error message. With the Ventura version 13.1 on an AirBook with M1, the problem did not exist. On my Intel iMac, the error causes the iMac to no longer start normally. Thank you very much for your support.
Posted
by
Post not yet marked as solved
1 Replies
990 Views
I am working as an iOS Developer since 2 years. I am getting log on console like: [MADService] Client XPC connection invalidated sometimes. I am unable to get when and for what reason i am getting this. need some help. Thank you
Posted
by
Post not yet marked as solved
5 Replies
800 Views
Hello! I'm new here, and probably this will sound weird but, I'm trying to write a C++ program using an XPC service to attempt to communicate with a macOS app I'm developing in Swift. At the macOS app side I think I'm successfully registering and connecting to the service, as launchd reports the following in its log: 2023-05-31 17:20:21.898621 (pid/15637 [On Air]) <Notice>: Service stub created for com.ruieduardolopes.onaird-join At the C++ side I'm trying to get a simple example working, as follows, but currently without any success... #include <xpc/xpc.h> int main(int argc, const char* argv[]) { xpc_connection_t conn = xpc_connection_create_mach_service("com.ruieduardolopes.onaird.join", NULL, 0); xpc_object_t message = xpc_dictionary_create(NULL, NULL, 0); xpc_connection_set_event_handler(conn, ^(xpc_object_t object) {}); xpc_connection_resume(conn); xpc_dictionary_set_string(message, "SS", "AAAAAA\n"); xpc_connection_send_message_with_reply(conn, message, dispatch_get_main_queue(), ^(xpc_object_t object) {}); return (EXIT_SUCCESS); } I get the following error in the logs: 2023-05-31 17:27:45.636894 (system/com.ruieduardolopes.onaird) <Notice>: internal event: WILL_SPAWN, code = 0 2023-05-31 17:27:45.636903 (system/com.ruieduardolopes.onaird) <Notice>: service state: spawn scheduled 2023-05-31 17:27:45.636904 (system/com.ruieduardolopes.onaird) <Notice>: service state: spawning 2023-05-31 17:27:45.637017 (system/com.ruieduardolopes.onaird) <Notice>: launching: ipc (mach) 2023-05-31 17:27:45.637256 (system/com.ruieduardolopes.onaird [15908]) <Notice>: xpcproxy spawned with pid 15908 2023-05-31 17:27:45.637264 (system/com.ruieduardolopes.onaird [15908]) <Notice>: internal event: SPAWNED, code = 0 2023-05-31 17:27:45.637265 (system/com.ruieduardolopes.onaird [15908]) <Notice>: service state: xpcproxy 2023-05-31 17:27:45.637269 (system/com.ruieduardolopes.onaird [15908]) <Notice>: internal event: SOURCE_ATTACH, code = 0 2023-05-31 17:27:45.648927 (system/com.ruieduardolopes.onaird [15908]) <Notice>: service state: running 2023-05-31 17:27:45.648940 (system/com.ruieduardolopes.onaird [15908]) <Notice>: internal event: INIT, code = 0 2023-05-31 17:27:45.648948 (system/com.ruieduardolopes.onaird [15908]) <Notice>: Successfully spawned onaird-join[15908] because ipc (mach) 2023-05-31 17:27:45.687251 (system/com.ruieduardolopes.onaird [15908]) <Notice>: exited due to SIGTRAP | sent by exc handler[15908] 2023-05-31 17:27:45.687261 (system/com.ruieduardolopes.onaird [15908]) <Notice>: service has crashed 1 times in a row 2023-05-31 17:27:45.687263 (system/com.ruieduardolopes.onaird [15908]) <Notice>: service state: exited 2023-05-31 17:27:45.687267 (system/com.ruieduardolopes.onaird [15908]) <Notice>: internal event: EXITED, code = 0 2023-05-31 17:27:45.687269 (system) <Notice>: service inactive: com.ruieduardolopes.onaird 2023-05-31 17:27:45.687281 (system/com.ruieduardolopes.onaird [15908]) <Notice>: service state: not running 2023-05-31 17:27:45.687290 (system/com.ruieduardolopes.onaird) <Notice>: Service only ran for 0 seconds. Pushing respawn out by 10 seconds. 2023-05-31 17:27:45.687339 (system/com.ruieduardolopes.onaird) <Notice>: internal event: WILL_SPAWN, code = 0 2023-05-31 17:27:45.687343 (system/com.ruieduardolopes.onaird) <Notice>: service state: spawn scheduled 2023-05-31 17:27:45.687344 (system/com.ruieduardolopes.onaird) <Notice>: service throttled by 10 seconds The plist file I'm currently loading to /Library/LaunchDaemons is as follows: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.ruieduardolopes.onaird</string> <key>Program</key> <string>PATH_TO_ONAIR_JOIN_XPC_SERVICE_BINARY</string> <key>BuildMachineOSBuild</key> <string>22C65</string> <key>CFBundleDevelopmentRegion</key> <string>en</string> <key>CFBundleDisplayName</key> <string>onaird-join</string> <key>CFBundleExecutable</key> <string>onaird-join</string> <key>CFBundleIdentifier</key> <string>com.ruieduardolopes.onaird-join</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>onaird-join</string> <key>CFBundlePackageType</key> <string>XPC!</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleSupportedPlatforms</key> <array> <string>MacOSX</string> </array> <key>CFBundleVersion</key> <string>1</string> <key>DTCompiler</key> <string>com.apple.compilers.llvm.clang.1_0</string> <key>DTPlatformBuild</key> <string></string> <key>DTPlatformName</key> <string>macosx</string> <key>DTPlatformVersion</key> <string>13.3</string> <key>DTSDKBuild</key> <string>22E245</string> <key>DTSDKName</key> <string>macosx13.3</string> <key>DTXcode</key> <string>1430</string> <key>DTXcodeBuild</key> <string>14E222b</string> <key>LSMinimumSystemVersion</key> <string>13.1</string> <key>MachServices</key> <dict> <key>com.ruieduardolopes.onaird.join</key> <true/> </dict> <key>XPCService</key> <dict> <key>ServiceType</key> <string>Application</string> </dict> </dict> </plist> Can anybody help me? Thanks in advance, Rui
Post not yet marked as solved
1 Replies
756 Views
We have 2 process in our macOS application Daemon process written in golang Swift application Currently, the communication between both the process are done with Unix domain socket. However, we are seeing significant amount of delay when large amount of data communication. We are looking for some faster communication. Probably XPC is the answer. But not sure how to use XPC between two process which are written in different language. Any sample code would be great help.
Posted
by
Post not yet marked as solved
1 Replies
537 Views
Hi! First time using XPC on a Mac app, and I'm stuck on a problem I can't understand. I have an app with multiple frameworks, and I'm adding an XPC service to one of the pre-existing frameworks. Right now the service is just the template that uppercases a string. I took all the necessary steps, I believe (adding the service as a target dependency, and copying it to the XPC Services folder). However, when I run it in Debug mode, I always get: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named <fully qualified service bundle ID> was invalidated: failed at lookup with error 3 - No such process." I also tested on a different, pre-existing framework, and the same thing happens. Here's the weird parts: if I create a new framework and follow exactly the same steps, it works. I've compare the build settings between both frameworks and everything seems similar. And if I run in Release mode, the original service on the problematic framework also works! If I create a project with similar setup (app + framework with service inside it), it also works. Looking at Console.app, I don't see anything that explains what's happening, but I may be filtering for the wrong thing. Any help on why this fails specifically on my pre-existing frameworks and only on Debug mode is much appreciated. :) Thank you, Miguel Arroz
Posted
by
Post marked as solved
1 Replies
603 Views
I have a regular GUI-based app that communicates with an Endpoint System Extension installed by another app. Both the GUI app and Endpoint System Extension have the same Team ID and are part of the same App Groups. But I still need to do one of the following to the GUI-based app to allow it to communicate with the Endpoint System Extension over XPC: Disable the sandbox Add com.apple.security.temporary-exception.mach-lookup.global-name to entitlements For some reason I thought there was another way to resolve this. Am I missing anything? (My goal is to allow an app distributed through the Mac App Store to communicate with my Endpoint System Extension if it exists, and I am worried about the "temporary-exception" entitlement needed to support this.)
Posted
by
Post not yet marked as solved
5 Replies
600 Views
Hello, I'm struggling to understand how I can use NSXPC API to communicate between two processes on iOS. The problem which I want to solve is how to pass some information from VPN tunnel to the VPN app. I'm looking at the XPC documentation and for iOS I can create NSXPCListener only with the following functions: service() anonymous() Both return NSXPCListener instance. But the question remains, how to connect to such an instance? In NSXPConnection API I see only one option for iOS: init(listenerEndpoint: NSXPCListenerEndpoint) Other constructors accepting serviceName or machServiceName are available only form macOS. I feel like the problem of communicating between two processes should be easy, but surprisingly I did find it quite difficult on iOS. Can you please advice if this is a proper API for my use case? Or maybe is there some better one, which I'm not aware of? If this is a proper API, how should I create a connection between two apps? How to pass a listener from one process to the other?
Posted
by
Post not yet marked as solved
1 Replies
313 Views
I have a NSXPCListener in an app and like to connect to from a command line tool. I can’t get it to work so I wonder if it is not supported of if I miss something. Any help is greatly appreciated.
Posted
by
Post marked as solved
4 Replies
725 Views
Assume this over-simplified @protocol I'm using for my XPC-service: @protocol MyMinimalProtocol <NSObject> - (void)getStatusWithReply:(void (^ _Nullable)(NSDictionary * _Nonnull))reply; @end The Client side would then NSXPCConnection *connection = [[NSXPCConnection alloc] initWithMachServiceName:myServiceLabel options:NSXPCConnectionPrivileged]; connection.remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(MyMinimalProtocol)]; connection.interruptionHandler = ^{ NSLog(@"XPC: connection - interrupted"); }; connection.invalidationHandler = ^{ NSLog(@"XPC: connection - invalidated"); }; [connection resume]; [connection.remoteObjectProxy getStatusWithReply:^(NSDictionary * response) { NSLog(@"XPC service status received - %@", response); }]; So far - so good. My XPC service receives the asynchronous call, schedules it's "status gathering operation" on internal background queue, and returns. Later - when information is available, my XPC service executes the reply-block then, on the remote calling side - I see the log line with the status, as expected. BUT!!! If I add another different code-block argument to the method e.g. @protocol MyMinimalProtocol <NSObject> - (void)getStatusWithReply:(void (^ _Nullable)(NSDictionary * _Nonnull))reply andFailureBlock:(void (^ _Nullable)(NSError * _Nonnull))failureBlock; @end Then all hell breaks loose. Both XPC service and the client crash with hilarious crash reasons I can't decipher. Here's "Client side" caller crash (excerpt - forgive the methods are NOT the simplified ones above) XPC Client(Caller) side crash - excerpt while on the "XPC Service" side, crashes like these: XPC service side crash excerpt I wonder if there's something inherently wrong with having two code-block arguments for an XPC remote method? Another issue. The client XPC calls are asynchronous. They return immediately. The XPC service implementing the remote-call also returns immediately - and it executes the "reply block" far (a minute!) later, on another queue. However, if the XPC service attempts to execute the code-block MORE THAN ONCE, then the client-side code-block is only called ONCE. rest of the executions look benign in the XPC-service side - but never happen on the calling (client) side. Any idea why? can this be overcome? Any thoughts/ideas/references to documentation will be greatly appreciated. I couldn't find any good source on this. Thanks.
Posted
by
Post not yet marked as solved
3 Replies
452 Views
Hello, I encountered such a problem, the scenario is like this: I have a launchctl startup daemon called xpcserver.app, which uses NSXPC to start an xpc Server. There is a Client program that links to the nsxpc service of this xpcserver.app, and when I establish the connection, I call an interface implemented by xpcserver named setName:(nsstring*)name. I was sure that my xpcserver implemented the corresponding interface, but when the client called the interface to pass the value, it triggered the error "unrecognized selector sent to instance". When I restarted the client, the call to the interface successfully implemented the function. May I ask why? Using the NSXPC started service, hope to solve, thank you
Posted
by