Can't use Swift classes inside Objective-C

前端 未结 25 2032
野趣味
野趣味 2020-11-22 08:10

I try to integrate Swift code in my app.My app is written in Objective-C and I added a Swift class. I\'ve done everything described he

相关标签:
25条回答
  • 2020-11-22 08:17

    Details: Objective-C project with Swift 3 code in Xcode 8.1

    Tasks:

    1. Use swift enum in objective-c class
    2. Use objective-c enum in swift class

    FULL SAMPLE

    1. Objective-C class which use Swift enum

    ObjcClass.h

    #import <Foundation/Foundation.h>
    
    typedef NS_ENUM(NSInteger, ObjcEnum) {
        ObjcEnumValue1,
        ObjcEnumValue2,
        ObjcEnumValue3
    };
    
    @interface ObjcClass : NSObject
    
    + (void) PrintEnumValues;
    
    @end
    

    ObjcClass.m

    #import "ObjcClass.h"
    #import "SwiftCode.h"
    
    @implementation ObjcClass
    
    + (void) PrintEnumValues {
        [self PrintEnumValue:SwiftEnumValue1];
        [self PrintEnumValue:SwiftEnumValue2];
        [self PrintEnumValue:SwiftEnumValue3];
    }
    
    + (void) PrintEnumValue:(SwiftEnum) value {
        switch (value) {
            case SwiftEnumValue1:
                NSLog(@"-- SwiftEnum: SwiftEnumValue1");
                break;
                
            case SwiftEnumValue2:
            case SwiftEnumValue3:
                NSLog(@"-- SwiftEnum: long value = %ld", (long)value);
                break;
        }
    }
    
    @end
    

    Detect Swift code in Objective-C code

    In my sample I use SwiftCode.h to detect Swift code in Objective-C. This file generate automatically (I did not create a physical copy of this header file in a project), and you can only set name of this file:

    If the compiler can not find your header file Swift code, try to compile the project.

    2. Swift class which use Objective-C enum

    import Foundation
    
    @objc
    enum SwiftEnum: Int {
        case Value1, Value2, Value3
    }
    
    @objc
    class SwiftClass: NSObject {
        
        class func PrintEnumValues() {
            PrintEnumValue(.Value1)
            PrintEnumValue(.Value2)
            PrintEnumValue(.Value3)
        }
        
        class func PrintEnumValue(value: ObjcEnum) {
            switch value {
            case .Value1, .Value2:
                NSLog("-- ObjcEnum: int value = \(value.rawValue)")
                
            case .Value3:
                NSLog("-- ObjcEnum: Value3")
                break
            }
            
        }
    }
    

    Detect Objective-C code in Swift code

    You need to create bridging header file. When you add Swift file in Objective-C project, or Objective-C file in swift project Xcode will suggest you to create bridging header.

    You can change bridging header file name here:

    Bridging-Header.h

    #import "ObjcClass.h"
    

    Usage

    #import "SwiftCode.h"
    ...
    [ObjcClass PrintEnumValues];
    [SwiftClass PrintEnumValues];
    [SwiftClass PrintEnumValue:ObjcEnumValue3];
    

    Result


    MORE SAMPLES

    Full integration steps Objective-c and Swift described above. Now I will write some other code examples.

    3. Call Swift class from Objective-c code

    Swift class

    import Foundation
    
    @objc
    class SwiftClass:NSObject {
        
        private var _stringValue: String
        var stringValue: String {
            get {
                print("SwiftClass get stringValue")
                return _stringValue
            }
            set {
                print("SwiftClass set stringValue = \(newValue)")
                _stringValue = newValue
            }
        }
        
        init (stringValue: String) {
            print("SwiftClass init(String)")
            _stringValue = stringValue
        }
        
        func printValue() {
            print("SwiftClass printValue()")
            print("stringValue = \(_stringValue)")
        }
        
    }
    

    Objective-C code (calling code)

    SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: @"Hello World!"];
    [obj printValue];
    NSString * str = obj.stringValue;
    obj.stringValue = @"HeLLo wOrLd!!!";
    

    Result

    4. Call Objective-c class from Swift code

    Objective-C class (ObjcClass.h)

    #import <Foundation/Foundation.h>
    
    @interface ObjcClass : NSObject
    @property NSString* stringValue;
    - (instancetype) initWithStringValue:(NSString*)stringValue;
    - (void) printValue;
    @end
    

    ObjcClass.m

    #import "ObjcClass.h"
    
    @interface ObjcClass()
    
    @property NSString* strValue;
    
    @end
    
    @implementation ObjcClass
    
    - (instancetype) initWithStringValue:(NSString*)stringValue {
        NSLog(@"ObjcClass initWithStringValue");
        _strValue = stringValue;
        return self;
    }
    
    - (void) printValue {
        NSLog(@"ObjcClass printValue");
        NSLog(@"stringValue = %@", _strValue);
    }
    
    - (NSString*) stringValue {
        NSLog(@"ObjcClass get stringValue");
        return _strValue;
    }
    
    - (void) setStringValue:(NSString*)newValue {
        NSLog(@"ObjcClass set stringValue = %@", newValue);
        _strValue = newValue;
    }
    
    @end
    

    Swift code (calling code)

    if let obj = ObjcClass(stringValue:  "Hello World!") {
        obj.printValue()
        let str = obj.stringValue;
        obj.stringValue = "HeLLo wOrLd!!!";
    }
    

    Result

    5. Use Swift extension in Objective-c code

    Swift extension

    extension UIView {
        static func swiftExtensionFunc() {
            NSLog("UIView swiftExtensionFunc")
        }
    }
    

    Objective-C code (calling code)

    [UIView swiftExtensionFunc];
    

    6. Use Objective-c extension in swift code

    Objective-C extension (UIViewExtension.h)

    #import <UIKit/UIKit.h>
    
    @interface UIView (ObjcAdditions)
    + (void)objcExtensionFunc;
    @end
    

    UIViewExtension.m

    @implementation UIView (ObjcAdditions)
    + (void)objcExtensionFunc {
        NSLog(@"UIView objcExtensionFunc");
    }
    @end
    

    Swift code (calling code)

    UIView.objcExtensionFunc()
    
    0 讨论(0)
  • 2020-11-22 08:18

    When you add new Swift files to the project, please, make sure that you add them to correct targets. Please, make sure that every swift file you're going to use inherits NSObject class and annotated with @ObjCMembers Change to YES inside the build settings under the option ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES. Change to YES inside the build settings under the option DEFINES_MODULE.

    0 讨论(0)
  • 2020-11-22 08:19

    I had issues in that I would add classes to my objective-c bridging header, and in those objective-c headers that were imported, they were trying to import the swift header. It didn't like that.

    So in all my objective-c classes that use swift, but are also bridged, the key was to make sure that you use forward class declarations in the headers, then import the "*-Swift.h" file in the .m file.

    0 讨论(0)
  • 2020-11-22 08:20

    my problem was I got stuck after xcode created the bridge file but still I got error in header file name MYPROJECTNAME-swift.h

    1.I check in terminal and search for all auto created swift bridge files:

    find ~/library/Developer/Xcode/DerivedData/ -name "*-Swift.h"|xargs basename|sort -

    you see what xcode created.

    1. in my case, I had space in my project name and xcode replace this is '_'
    0 讨论(0)
  • 2020-11-22 08:23

    @sig answer is one of the best, however, it did not work for me with the old project (not new!), I needed some modifications. After a lot of variations I found the recipe for me (using XCode 7.2):

    1. Product Module Name : $(PRODUCT_NAME:c99extidentifier)
    2. Defines Module : NO
    3. Embedded Content Contains Swift : NO
    4. Install Objective-C Compatibility Header : YES
    5. Objective-C Bridging Header : ProjectName-Bridging-Header.h

    The last point (5) was crucial. I put it only on the second section (Targets field), the Project field should be left empty: Otherwise, it did not generate the right "Project-Swift.h" file for me (it did not include swift methods).

    0 讨论(0)
  • 2020-11-22 08:23

    In my case, apart from these steps:

    1. Product Module Name : myproject
    2. Defines Module : YES
    3. Embedded Content Contains Swift : YES
    4. Install Objective-C Compatibility Header : YES
    5. Objective-C Bridging Header : $(SRCROOT)/Sources/SwiftBridging.h

    I have needed to put the class as public in order to create productName-Swift.h file:

    import UIKit
    
       @objc public class TestSwift: NSObject {
           func sayHello() {
              print("Hi there!")
           }
       }
    
    0 讨论(0)
提交回复
热议问题