issue-14-xpc icon indicating copy to clipboard operation
issue-14-xpc copied to clipboard

How did you get Xcode to generate you an XPC Service with Swift boilerpate?

Open theladyjaye opened this issue 11 years ago • 10 comments

When I add a new XPC target it generates my files in Obj-C

theladyjaye avatar Oct 15 '14 11:10 theladyjaye

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

theladyjaye avatar Oct 15 '14 11:10 theladyjaye

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

theladyjaye avatar Oct 18 '14 01:10 theladyjaye

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.swift file with the boilerplate from the main.swift file 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.

theladyjaye avatar Oct 18 '14 02:10 theladyjaye

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).

danieleggert avatar Oct 19 '14 10:10 danieleggert

Thanks to both of you! This helped me to get started with my first XPC service and keep my project in pure Swift!

udondan avatar Mar 14 '15 06:03 udondan

Glad to help.

danieleggert avatar Mar 17 '15 11:03 danieleggert

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. =)

theladyjaye avatar Jul 16 '16 15:07 theladyjaye

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.

vojto avatar Feb 02 '17 14:02 vojto

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

ITzTravelInTime avatar Apr 21 '18 00:04 ITzTravelInTime

can any one update this code to swift 5? I tried but getting major build errors

patchthecode avatar Nov 29 '19 09:11 patchthecode