12

I'm running into an issue where my Swift code compiles fine but then the generated -Swift.h file has an error in it...

Here is an example of what I'm doing:

class MyScene : CCLayer {
    var ctrl : CCControlSlider?
}

This compiles just fine in the swift code and I can see the methods on the ctrl object just fine as well. I have the following in my bridge header:

#import "cocos2d.h"
#import "CCControlSlider.h"

This works perfectly fine in other classes that use other libraries which work correctly. Also note that I can use this CCControlSlider class in my objective-c classes with no issues at all as well.

Here is what happens on the generated -Swift.h file:

SWIFT_CLASS("_TtC15MyProject10MyScene")
@interface MyScene : CCLayer
@property (nonatomic) CCControlSlider * ctrl;
@end

The property has the error "Unknown type name "CCControlSlider" and if it's used in a method then it gives the error "Expected a type".

This works just fine using other classes but for some reason this one class gives this compiler error only in the generated header file and only when used from Swift.

I guess what I'm wondering is, am I doing something wrong or is this just a bug??

Rocky Pulley
  • 22,531
  • 20
  • 68
  • 106

4 Answers4

10

While incorporating a set of Objective C files into my mostly Swift-based project I suddenly started getting a lot of these errors on them. Then I realized though the file had:

#import <Foundation/Foundation.h>

It did not have:

#import <UIKit/UIKit.h>

and once I added that line the errors started resolving. Cleaning afterwards always helps. Good luck

NOTE: With newer versions of Swift imports are much easier to type and are done like so:

import UIKit
Chris Klingler
  • 5,258
  • 2
  • 37
  • 43
  • 1
    Good one, would've never figured that out on my own that I also need "higher" imports than the class I wanna import, too. Thanks man, saved me an hour – user2875404 Feb 27 '17 at 23:02
8

If you don't want to worry about the order of imports everywhere you import your ProjectName-Swift.h file, try this:

Create a file named ProjectName-Swift-Fixed.h with the following contents

// ProjectName-Swift-Fixed.h
@class CCControlSlider;
// (Add other imports or forward declarations here)
#import "ProjectName-Swift.h"

Second, throughout the rest of your codebase, replace #import "ProjectName-Swift.h" with #import "ProjectName-Swift-Fixed.h"

This approach has two benefits over copying and pasting a list of #import statements above each place you use Swift classes in Objective-C code:

  1. You won't have to worry about the order of imports, except in the ProjectName-Swift-Fixed.h file
  2. When you add new Objective-C classes to your Swift code, you won't have to add new #import statements in every Objective-C file that uses Swift code
johnboiles
  • 3,494
  • 1
  • 32
  • 26
6

The answer given here is the simplest approach: https://stackoverflow.com/a/24216718/341994

Basically, somewhere in your Objective-C code you are importing the automatically generated -Swift.h header. In that same code, before that #import line, insert #import "CCControlSlider.h". The order of these two #import statements is crucial!

The fact that this Objective-C class may not need CCControlSlider is irrelevant (though if it does, that's a bonus). The important thing is the order. We want to expose the namespace to CCControlSlider before exposing the namespace to the automatically generated -Swift.h header.

Community
  • 1
  • 1
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Does that make this a bug? I'd expect that the autogenerated -Swift file would have access to everything in the bridging header? – sammyd Jun 26 '14 at 06:12
  • ProjectName-Swift.h file is generated by XCode automatically, you just need to import it in .m file: #import Of course, -Swift.h file and -Bridging-Header.h, both are needed if you add Swift to Objective-C. – Darius Miliauskas Jan 02 '16 at 20:10
1

OC code has a global call # import "projectName - swift. H", and "the projectName - Bridging - Header. H" and calls the OC code.Is equivalent to the parent class call subclasses, subclasses and calls the superclass.To make the "projectName - Bridging - Header. H" calls the oc class don't call # import "projectName - swift. H.

Chen
  • 11
  • 1