SourceKitten
SourceKitten copied to clipboard
App Store App
Is it possible to use the sourcekitten framework in an app submitted to the App Store?
Obviously, App Store apps need to be sandboxed. Unfortunately, simply turning that on doesn't work. I get xcrun: error: cannot be used within an App Sandbox
.
So I found this issue that suggested wrapping SourceKitten in an XPC Service. I did so, turned sandboxing on in my app, and it worked as intended! So I submitted to the App Store and it failed upon upload because The XPC Service needs to be sandboxed too...
So I turned sandboxing on for the XPC Service and was confronted with xcrun: error: cannot be used within an App Sandbox
again.
Is this just impossible? Or is there more to it to get it to work?
I think the sandbox issues are due to loading external dynamic libraries (namely libclang and sourcekitd). You may be able to avoid those sandbox issues by including copies of those libraries in your app bundle, re-signed by you.
Interesting... I had assumed it was related to running a Process
command in the sandbox, but googling a bit about that, I haven't found anything to explicitly say that's not allowed.
So I turned sandboxing on for the XPC Service and was confronted with
xcrun: error: cannot be used within an App Sandbox
again.
Ah yes sorry I didn't pay close enough attention to this sentence. That's definitely a Process
invocation. We do this to dynamically determine where to look for sourcekitd.framework
and libclang.dylib
. If you set the TOOLCHAIN_DIR
environment variable to the location where SourceKitten should look to load these libraries, you can avoid running xcrun
.
Check out library_wrapper.swift
for the implementation details.
I tried both hardcoding
private let toolchainDir = env("TOOLCHAIN_DIR")
to
private let toolchainDir = "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib"
(and /Applications/Xcode.app/Contents/Developer/Toolchains/
cuz I wasn't sure which was correct)
and setting the scheme to set the TOOLCHAIN_DIR to both of those values. Breakpoints confirm the value passed through, but the issue persists.
What's odd though is that xcrun
is running before those breakpoints ever hit. (I put the breakpoint on the return statement of the env
function in library_wrapper.swift
)
If it clarifies anything at all, I'm extracting documentation through the following code:
let module = Module(xcodeBuildArguments: [], inPath: url.path)
guard let docs = module?.docs else {
completion(nil)
return
}
let docString = docs.description
guard let jsonData = docString.data(using: .utf8) else {
completion(nil)
return
}
When sandboxing is off, the first thing I see printed in the console is Running xcodebuild
, otherwise the first thing I see is the xcrun: error: cannot be used within an App Sandbox
error when it's on.
Ah, yeah that still invokes a separate Process
instance.
If you find another way to get swiftc arguments, you could use a different Module initializer.
Hi @mredig , did you find solution for this problem? :<
Unfortunately I have not had time to try the suggestion and the project has been sitting on the back burner. Some day though....