0

I want to declare an Objective-C method with a custom Swift class as one of it's arguments, like this:

+ (void)doCalculationsWithACustomSwiftObject:(CustomSwiftClass *)swiftObject andADictionanary:(NSDictionary *)ordinaryDictionary;

The aim is to call this method from Swift, pass an instance of the custom class "CustomSwiftClass.swift" so that the Objective-C code can access its properties. Is it possible, and if so, how do I declare the "CustomSwiftClass" to make the compiler accept it?

turingtested
  • 6,356
  • 7
  • 32
  • 47
  • 2
    Add `@objc` in front of the Swift class declaration – Steve Wilford Nov 04 '15 at 15:15
  • @SteveWilford Have tried that, and the compiler still doesn't accept the class. How should the import/include/class declaration look like in the Objective-C header file did you mean? – turingtested Nov 04 '15 at 15:32
  • @turingtested There's the `bridging-header` tag for Swift/Objective-C mix-and-match (unfortunately the tag has no description yet). I agree we could have something more useful. – Eric Aya Nov 04 '15 at 15:54

1 Answers1

2

A couple of thoughts:

  1. To make Swift class accessible to your Objective-C code, you have to import the system generated header. As the documentation says:

    When you import Swift code into Objective-C, you rely on an Xcode-generated header file to expose those files to Objective-C. This automatically generated file is an Objective-C header that declares the Swift interfaces in your target. It can be thought of as an umbrella header for your Swift code. The name of this header is your product module name followed by adding "-Swift.h". (You’ll learn more about the product module name later, in Naming Your Product Module.)

    For example, your Objective-C file would import this generated header:

    #import "MyApp-Swift.h"
    

    For more information, see Importing Swift into Objective-C section of the Using Swift with Cocoa and Objective-C: Mix and Match

  2. If you're not seeing the xxx-Swift.h file, double check your target settings:

    enter image description here

    (Note, I searched for "swift" in the settings to narrow down the results.)

    As you'll see, the following are all set:

    • "Install Objective-C Compatibility Header" is set to "Yes";

    • The "Objective-C Generated Interface Header Name" is set (and matches what I imported into my Objective-C code);

    • The "Objective-C Bridging Header" is also specified.

      Note, the Objective-C bridging header is ostensibly solely for the purpose of making the Objective-C classes available to the Swift code (and you're currently trying to accomplish the converse), but I notice that this affects what code is generated in the compatibility header, too. So make sure you have a bridging header, too.

  3. Of course, make sure your Swift file is included in the list of compile sources:

    enter image description here

  4. And make sure the class is subclassed from NSObject:

    import UIKit
    
    class MyObject: NSObject {
        var text: String?
        var value: Int = 0
    }
    
  5. Note, some Swift types are not available to Objective-C code. For example, Objective-C cannot not use some optional types (e.g. an optional type such as Int? will not work, whereas an optional class type of String? will). So if you are seeing the class, but not some of the properties, make sure they're Objective-C compatible.

    But I gather from your question that you're having more fundamental problems, that you're not finding the -Swift.h header at all. But once you solve that, this is a consideration for individual properties.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • I' have done all that. Your answer is a very good introduction to mix-matching Swift and Objective-C. But it doesn't solve my problem and maybe you have misunderstood the question a bit. I am using Objective-C bridging header, of course, since I'm calling this method from Swift. And I noticed just now that `#import "MyApp-Swift.h"` is working fine in the .m file! But that is not the question, it is how to declare a method with a custom Swift-class as argument. Then you must do the import in the .h file, which is causing errors. At least for me. – turingtested Nov 05 '15 at 07:49
  • @turingtested - If you have an Objective-C function that takes a "swift object" as a parameter, you just (a) `#import "MyApp-Swift.h"` in the `.m` file (or if this method is defined in the public interface for your Objective-C class, then do that `import` in the `.h` file) and then (b) declare the function precisely as shown in the question. If it is not recognizing `CustomSwiftClass`, then I'd open up that `MyApp-Swift.h` file (i.e., just command-click on it) and make sure you see your custom class defined there. You might not see it for any of a multitude of reasons which I enumerate above. – Rob Nov 05 '15 at 08:12