SourceKitten icon indicating copy to clipboard operation
SourceKitten copied to clipboard

Generate Swift Interface/Structure from Bridging Header

Open fabb opened this issue 8 years ago • 9 comments

I have a mixed ObjC/Swift project and like to generate the Swift Interface (structure information would be even better) from the Bridging header from commandline. I have already invested quite a few unfruitful hours. Could you give me some direction on how to achieve that? Is it possible with SourceKitten commandline tool? Or should I rather use the framework? Do I need to preprocess the file first or can SourceKitten do that?

Thanks in advance :-)

fabb avatar Jun 11 '16 14:06 fabb

Can you share exact steps to cause Xcode to auto-generate this interface? If I have that I could probably figure out how to reverse engineer it to make SourceKitten do it too

jpsim avatar Jun 11 '16 16:06 jpsim

Thanks for helping!

Xcode has this "Generated Interface" view: https://developer.apple.com/library/ios/qa/qa1914/_index.html It also works for ObjC header files. Unfortunately it seems to ignore #imports which would be necessary for me. So I need to run the preprocessor first. Xcode can generate that, but only for .m files, not for .h files. I do the following steps manually to achieve the desired result in Xcode:

  1. Copy the content of the my-bridging-header.h into a new .m file
  2. In Xcode choose the "Preprocess" view
preprocess 3. Copy the preprocessed content to a new .h file 4. In Xcode choose the "Generated Interface" view generatedinterface 5. Done! But sometimes SourceKit reports an error and does not generate output, it seems to have problems with input files more than a a few hundred lines long. Unfortunately in my case it's around 8000 lines. So maybe it's just a timeout thing that can be avoided by increasing the timeout.

fabb avatar Jun 11 '16 19:06 fabb

I suppose you're not actually looking for a Swift generated interface for the bridging header itself, but rather for the Objective-C interfaces it imports?

If it's the latter, you can do that using SourceKitten's Request.Interface(...). You can see it in use here.

jpsim avatar Jun 11 '16 20:06 jpsim

You can search for interface-gen in apple/swift and get tons of hits showing ways to use this: https://github.com/apple/swift/search?utf8=%E2%9C%93&q=interface-gen

jpsim avatar Jun 11 '16 21:06 jpsim

Awesome, I'll try that out, thanks!

fabb avatar Jun 11 '16 21:06 fabb

Ok, I managed to create a command line application Xcode project, which can use SourceKittenFramework. Wasn't so easy, as command line application cannot use dynamic frameworks as I learned :-) (at least not straightforward, so I just included it statically as a target dependency for now)

For starters I initialized a ClangTranslationUnit just like in the unit test, and made a breakpoint at the line Request.Interface(...) you pointed me to (Seems like the stateful stuff ClangTranslationUnit does is necessary before calling Request.Interface(...), after all I'm new to this compiler stuff). You were right, Request.Interface(...) creates the Swift Interface I need (nearly) in key.sourcetext.

I still have a few problems:

  • The generated Swift Interface in key.sourcetext seems to ignore nullability annotations from the original source code. But this is exactly what I need. E.g. both NSString * and nullable NSString * become AnyObject!.
  • NSString does not bridge to String
  • During runtime I get the following errors: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/usr/include/sys/cdefs.h:707:2: error: Unsupported architecture etc.

Any ideas where I should investigate further?

fabb avatar Jun 12 '16 11:06 fabb

Related to the first two points, I got the same behaviour in Xcode when I generate a Swift interface from an ObjC header, so I think this is an issue related to Xcode and not to SourceKitten

4brunu avatar Nov 19 '17 19:11 4brunu

I had the same issue and I ended up writing a tool for it: https://github.com/lvsti/Bridgecraft

Observations:

  • it solves NSString bridging to String
  • nullability audited regions are indeed reset during the preprocessing phase, but if all your headers are annotated then there is a workaround (see readme)

lvsti avatar Jan 14 '18 09:01 lvsti

Awesome tool @lvsti!

jpsim avatar Mar 07 '18 07:03 jpsim