Using Swift Cocoa Pod with objective-c launch daemon

Hi All,


With XCode 9+, can we use "Swift + Objective-C" code in the pods now? For us those pods are integrated with the launch daemon. Previously, we observed issues as the daemon binary was marked tainted by OS once deployed if it has Swift framework. Would this usecase be possible now with XCode 9?


Thanks.

Previously, we observed issues as the daemon binary was marked tainted by OS …

I have no idea what “marked as tainted” means but, in general, launchd daemons are usually deployed as a single executable rather than as a bundle used for apps, app extensions, and so on. This makes it hard to use frameworks or other dynamic libraries. There are three common solutions to this:

  • Install these dynamic libraries at a known path (for example, frameworks go into

    /Library/Frameworks/
    ) and link to them dynamically (A).
  • Embed your launchd daemon in a bundle and install that bundle in a location that’s suitable for a launchd daemon (B).

  • Eschew dynamic linker and statically link everything (C).

With regards B:

  • You can create such a project by starting with an app template and then ripping out all the app parts.

  • “suitable for a launchd daemon” means that the directory, and its parents all the way up to the root, must only be modifiable by root.

  • When you create your launchd property list, it has to point to the executable within the bundle (

    /Whatever/Path/You/Choose/Foo.app/Contents/MacOS/Foo
    ) rather than to the
    .app
    .
  • This approach makes you incompatible with

    SMJobBless
    .

With regards C:

  • One wrinkle is the Swift runtime libraries. If you create a command-line tool project then Xcode will automatically statically link the Swift runtime libraries. This is true regardless of whether the

    main
    function is written in Swift or Objective-C.
  • On the CocoaPods side of this, I’m not sure how it handles static linking so I can’t help you with that. My recommendation is that you escalate this via whatever support channel they provide.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Quinn. So there should not be any issue linking Swift runtime using one of the approaches above with daemon, right? Means as daemons run as root, would OS allow the dynamically loaded piece of code run?

So there should not be any issue linking Swift runtime using one of the approaches above with daemon, right?

I presume you’re talking about options A and B, because option C suggests static linking. If that’s correct then you’re correct, there shouldn’t be any problems using this approach for both the Swift runtime libraries and any other frameworks you need.

There are a bunch of potential gotchas here but the one that immediately springs to mind is library validation (see the

library
flag in the
codesign
man page). This definitely won’t be a problem for B because all of your components are within your bundle. Option A is a bit trickier. I believe that library validation allows you to link with non-system libraries by absolute path as long as the libraries are signed by you. However, the man page doesn’t mention that possibility, so I may be wrong. If you need a definitive answer on this you should open a DTS tech support incident and talk to our Mac code signing specialist.

Regardless, library validation is an opt-in thing.

ps If you’re working on the edges of macOS you definitely need to watch WWDC 2018 Session 702 Your Apps and the Future of macOS Security, which talks about some important developments in the 10.14 timeframe.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Using Swift Cocoa Pod with objective-c launch daemon
 
 
Q