5

I have two C functions:

extern UIColor* LNRandomDarkColor();
extern UIColor* LNRandomLightColor();

As an exercise, I am trying to import them into Swift as extension methods to UIColor.

Following Apple's "What's New in Swift" presentation from WWDC 2016 example:

void CGContextFillPath(CGContextRef) NS_SWIFT_NAME(CGContext.fillPath(self:)); 

I attempted to annotate my functions similarly:

extern UIColor* LNRandomDarkColor() NS_SWIFT_NAME(UIColor.randomDarkColor());
extern UIColor* LNRandomLightColor() NS_SWIFT_NAME(UIColor.randomLightColor());

However I am receiving the following warning:

'swift_name' attribute can only be applied to function declarations with prototypes

What am I doing wrong here?


Update: Opened SR-2999 for this issue.

Léo Natan
  • 56,823
  • 9
  • 150
  • 195
  • I'm pretty sure that by using extern you will find that it's relying on the linker to point to the actual implementation. Because of this I'm not sure it'll work in the way you are trying to use it. – dlbuckley Oct 19 '16 at 15:25

1 Answers1

3

This is a partial result. The following code – created from the examples at SE-0044 Import as member – compiles:

struct MyColor { };

UIColor * _Nonnull LNRandomDarkColor(void)
__attribute__((swift_name("MyColor.randomDarkColor()")));

and imports the C function as a static member function of the MyColor type to Swift:

let col = MyColor.randomDarkColor()

But I was not able to import the function as a member function of any existing type like UIColor:

UIColor * _Nonnull LNRandomDarkColor(void)
__attribute__((swift_name("UIColor.randomDarkColor()")));
// warning: imported declaration 'LNRandomDarkColor' could not be mapped to 'UIColor.randomDarkColor()'

(and UIColor.randomDarkColor() does not compile). I don't know if that is an intentional restriction or a bug.

Using the NS_SWIFT_NAME macro instead of the swift_name attribute does not work either:

UIColor * _Nonnull LNRandomDarkColor(void)
NS_SWIFT_NAME("MyColor.randomDarkColor()");
// warning: parameter of 'swift_name' attribute must be a Swift function name string
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • There is such little documentation on this, and as usual with anything Swift related, buggy as hell. Thanks for the effort! Is `struct MyColor { };` required, or can it be inferred by importer? Can a `typedef` work, where `MyColor` is a "typealias" to `UIColor`? Not next to my Mac to test myself. Will open a bug if this is so limited. – Léo Natan Oct 19 '16 at 20:49
  • Also, what is the difference between `__attribute__((swift_name("")))` and `NS_SWIFT_NAME`? Why does this duplication exist? – Léo Natan Oct 19 '16 at 20:54
  • @LeoNatan: The type needs to be defined, and I could not make it work with a type alias. – NS_SWIFT_NAME *should* be the same as far as I can see from the macro expansion, but that is what I observed. – Btw, import as subscript did not work either the last time that I checked, don't know if that is fixed now. Please add the bug # here if you report one. – Martin R Oct 19 '16 at 20:59
  • Hmm, according to https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/Base.subproj/CFBase.h#L339, it is the same. Should be `NS_SWIFT_NAME(MyColor.randomDarkColor());` – Léo Natan Oct 19 '16 at 21:00
  • I will add the bug report. I will file tomorrow if nothing else pops up. – Léo Natan Oct 19 '16 at 21:00