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
Replies
Boosts
Views
Activity
I'm experiencing a strange problem with dlopen in my app. I use it to load a plugin .dylib, which works fine generally (I have a few plugins already). I'm developing a new plugin feature.dylib that has an external shared library dependency libexternal.so and here's where I'm having trouble. After a lot of work with install_name_tool and otool, I have the following situation: if I run my app from terminal open MyApp.app or ./MyApp.app/Contents/MacOS/MyApp or from the finder by double clicking MyApp.app, the dlopen of feature.dylib is successful. However, if I run MyApp from within Xcode, dlopen feature.dylib fails with image not found for libexternal.so. I've checked this with debug and release builds, and with and without debugging (and if I run lldb from the terminal as lldb MyApp.app/Contents/MacOS/MyApp it works fine too) and the behavior is the same: running from inside Xcode, the dlopen fails, but outside Xcode, it works.
Some other details: otool -L libexternal.so shows its id is libexternal.so and otool -L feature.dylib shows its id is feature.dylib and it has the dependency @loader_path/libexternal.so. If I change it to @rpath/libexternal.so and add my plugins folder path to MyApp.app's Runpath Search Paths, then it works in Xcode (but I don't want to have to enumerate all the places a plugin might be found here).
This is on osx 10.15.7 with Xcode 12.4. I'm not using hardened runtime. feature.dylib and MyApp.app are signed with the same certificate, while libexternal.so is not signed. I thought this might be a problem until I saw it works outside Xcode.
Is it possible Xcode is somehow changing the behavior of dlopen?
I've been developing a macOS app as part of a small team of developers for a year now. The app is not going to be distributed through the App Store. Our Xcode configuration has Debug, Release, and Dist configurations, and we manually manage signing. Debug and Release are set to "sign to run locally". Dist uses our Developer ID Application cert. None of the configurations have a provisioning profile and all use our team's developer account Team identifier.
This setup has worked fine -- developers can clone the project and build it without changing project settings or downloading profiles / certificates, and I am able to build, sign, and notarize the app for distribution.
We would now like to support universal links to our app, which requires the Associated Domains entitlement. This creates a problem because Xcode requires a provisioning profile that includes the Associated Domains feature.
I can create a provisioning profile with our Developer ID Application cert and use it for the Dist configuration. This works fine. However, for Debug and Release, it seems I cannot create a provisioning profile that will work with the "sign to run locally" setting. I can create an Apple Development certificate and use it, but that certificate has my name and ID on it, not my organization's team name and ID. That means for another developer on my team, they would need to clone the project, then adjust the project settings to select their provisioning profile with their signing certificate. This creates an obvious problem for our repository management.
I can imagine a few ways I might fix this, but don't see how to make any of them work. Can I make an Apple Development certificate for my team that we can all use? Or can I make a provisioning profile that will allow signing to run locally? Or is there some other solution?