issue-14-xpc
issue-14-xpc copied to clipboard
How did you get Xcode to generate you an XPC Service with Swift boilerpate?
When I add a new XPC target it generates my files in Obj-C
Ah, it looks like to ensure that both the main app and the XPC service can see the protocol, you manually add the ImageDownloaderProtocol to both targets in their respective Compile Sources Build Phase
Since the flag in the XPC (swift) service is set: Install Objective-C Compatibility Header I'm going to guess the answer to my initial question is:
Xcode creates the XPC Service as Objective-C and you just kill the main.m/*.h etc files an replace them with Swift files?
It also looks like, do pull that conversion off from the initial XPC OBJC template, you need to toggle the Embedded Content Contains Swift Code flag in the Build Settings for the XPC Service or this error pops up: Library not loaded: @rpath/libswiftCore.dylib
Set it to YES once, compile/run then you can set it to NO and it will all behave just fine. (unless you Clean, then you have to set it again)
You are not doing the above flag setting in your project, so I'm curious how you got it to know Swift was available. For example, your XPC target compiles to ~59k. If I enable Embedded Content Contains Swift Code in my alternate example, the XPC target is 4.1 meg
ok.. here is the error I get when building the project after updating it for 6.1:
dyld: Library not loaded: @rpath/libswiftCore.dylib
Referenced from: /Users/aventurella/Library/Developer/Xcode/DerivedData/Superfamous_Images-eyxuymvkcexwokbqtkmbkuwgnork/Build/Products/Debug/Superfamous Images.app/Contents/XPCServices/io.objc.Superfamous-Images.ImageDownloader.xpc/Contents/MacOS/io.objc.Superfamous-Images.ImageDownloader
Reason: image not found
Ok, solved it for now:
- Create an XPC target in your project, it will be Objective-C (until they fix/add the templates)
- Delete all of the .h/.m files etc
- add a
main.swiftfile with the boilerplate from themain.swiftfile in this project
That's it you are done on the swift side, but we need to do some configuration of the XPC target's build settings still.
So the other part the issue, aside from the boilerplate templates not being there is that if you have a swift app, and then add a swift XPC service you need to set the Embeded Content Contains Swift Code setting on the XPC target so that it copies the swift libraries into XPC service's bundle. So now your App + XPC service will contain 2 copies of the swift libraries (which weight about 4.1meg-ish). So it's packaging an extra 4.1 meg per XPC Service but the main app is already swift based and has the libraries already; so wasteful.
To fix this duplication, in the XPC service's Build Settings, this can be added to the Runpath Search Paths
@loader_path/../../../../Frameworks
This works for XPC services based on where they are embedded in the main app bundle.
Thanks for your help — I'm sorry for being slow at responding. I've been crazy busy lately.
I did create the service manually. The Xcode boilerplate project is ObjC based.
Seems like you solved it? Let me know if you still have questions. I guess it may be a good idea to update the objc.io article with more details? I didn't look at this for a while.
You’re on the right track, though: The suggested approach is to move common code into a shared framework and use this framework (i.e. link against it) from both the app and the XPC service(s).
Thanks to both of you! This helped me to get started with my first XPC service and keep my project in pure Swift!
Glad to help.
That time on the internet, when almost 2 years later you google for a problem you are experiencing and then end up back at your own answer that solves your problem. =)
Hi, just wanted to confirm that putting shared code into SharedFrameworks works nicely.
I currently have architecture consisting of 1 main app [Foo], 1 LoginItem [FooHelper] (which has UI, so it can't be an XPC target), and then 1 XPC service [FooAgent] they both talk to.
Shared code is in a private framework called FooCore, and all targets link to this framework.
Hi guys, do you have some ideas about how to use this for privileged tasks? i need to do some operations which requires running an external executable which requires to be run using the root user, something i can achieve only using sudo + user's password for now which is really unsafe, someone told me to use an xpc service to do this kind of privileged operation because xpc services runs on top of launchd which is a process of the root user, my question is how should i do that xpc service to perform a privileged operation thing? obviusly i want to keep my app as pure swift as possible
Thank you very much for you patience
can any one update this code to swift 5? I tried but getting major build errors