我尝试在我的应用程序中集成Swift代码。我的应用程序是用Objective-C编写的,我添加了一个Swift类。我做了这里描述的所有事情。但我的问题是Xcode还没有创建-Swift.h文件,只有桥接头。我创建了它,但它实际上是空的。 我可以在Swift中使用我所有的ObjC类,但我不能反之亦然。我用@objc标记了我的swift类,但它没有帮助。我现在该怎么办?

编辑:苹果说:“当你将Swift代码导入Objective-C时,你依靠xcode生成的头文件将这些文件公开给Objective-C。[…此头文件的名称是您的产品模块名称,后跟“-Swift.h”。

现在当我想导入这个文件时,它会给出一个错误:

    //MainMenu.m

    #import "myProjectModule-Swift.h" //Error: 'myProjectModule-Swift.h' file not found

    @implementation MainMenu

这是我的FBManager.swift文件:

@objc class FBManager: NSObject {

    var descr = "FBManager class"

    init() {
        super.init()
    }

    func desc(){
        println(descr)
    }

    func getSharedGameState() -> GameState{
        return GameState.sharedGameState() //OK! GameState is written in Objective-C and no error here
    }
}

当前回答

详细信息:Objective-C项目与Swift 3代码在Xcode 8.1

任务:

在objective-c类中使用swift enum 在swift类中使用objective-c enum

完整的样品

1. Objective-C类使用Swift枚举

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

在Objective-C代码中检测Swift代码

在我的示例中,我使用SwiftCode.h来检测Objective-C中的Swift代码。这个文件自动生成(我没有在项目中创建这个头文件的物理副本),你只能设置这个文件的名称:

如果编译器找不到你的Swift头文件代码,尝试编译项目。

2. Swift类使用Objective-C枚举

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
        }
        
    }
}

检测Swift代码中的Objective-C代码

您需要创建桥接头文件。当你在Objective-C项目中添加Swift文件,或在Swift项目中添加Objective-C文件时,Xcode会建议你创建桥接头。

你可以在这里更改桥接头文件的名称:

Bridging-Header.h

#import "ObjcClass.h"

使用

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

结果


更多的样品

上述Objective-c和Swift的完整集成步骤。现在我将编写一些其他代码示例。

3.从Objective-c代码调用Swift类

斯威夫特类

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代码(调用代码)

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

结果

4. 从Swift代码调用Objective-c类

Objective-C类(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码(呼叫码)

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

结果

5. 在Objective-c代码中使用Swift扩展

迅速扩展

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

Objective-C代码(调用代码)

[UIView swiftExtensionFunc];

6. swift代码中使用Objective-c扩展

Objective-C扩展(UIViewExtension.h)

#import <UIKit/UIKit.h>

@interface UIView (ObjcAdditions)
+ (void)objcExtensionFunc;
@end

UIViewExtension.m

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

Swift码(呼叫码)

UIView.objcExtensionFunc()

其他回答

当您向项目添加新的Swift文件时,请确保您将它们添加到正确的目标。 请确保你要使用的每个swift文件都继承了NSObject类,并带有@ObjCMembers注释 在ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES选项下的构建设置中更改为YES。 在选项DEFINES_MODULE下的构建设置中更改为YES。

详细信息:Objective-C项目与Swift 3代码在Xcode 8.1

任务:

在objective-c类中使用swift enum 在swift类中使用objective-c enum

完整的样品

1. Objective-C类使用Swift枚举

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

在Objective-C代码中检测Swift代码

在我的示例中,我使用SwiftCode.h来检测Objective-C中的Swift代码。这个文件自动生成(我没有在项目中创建这个头文件的物理副本),你只能设置这个文件的名称:

如果编译器找不到你的Swift头文件代码,尝试编译项目。

2. Swift类使用Objective-C枚举

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
        }
        
    }
}

检测Swift代码中的Objective-C代码

您需要创建桥接头文件。当你在Objective-C项目中添加Swift文件,或在Swift项目中添加Objective-C文件时,Xcode会建议你创建桥接头。

你可以在这里更改桥接头文件的名称:

Bridging-Header.h

#import "ObjcClass.h"

使用

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

结果


更多的样品

上述Objective-c和Swift的完整集成步骤。现在我将编写一些其他代码示例。

3.从Objective-c代码调用Swift类

斯威夫特类

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代码(调用代码)

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

结果

4. 从Swift代码调用Objective-c类

Objective-C类(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码(呼叫码)

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

结果

5. 在Objective-c代码中使用Swift扩展

迅速扩展

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

Objective-C代码(调用代码)

[UIView swiftExtensionFunc];

6. swift代码中使用Objective-c扩展

Objective-C扩展(UIViewExtension.h)

#import <UIKit/UIKit.h>

@interface UIView (ObjcAdditions)
+ (void)objcExtensionFunc;
@end

UIViewExtension.m

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

Swift码(呼叫码)

UIView.objcExtensionFunc()

只包括 以。m或。h格式导入“myProject-Swift.h”文件

附注:你不会在文件检查器中找到“myProject-Swift.h”,它是隐藏的。但它是由应用程序自动生成的。

我不需要改变构建中的任何设置,也不需要将@obj添加到类中。

我所要做的就是创建bridge-header,当我在Objective-c项目中创建Swift类时,它会自动创建。然后我要做的就是

导入"Bedtime-Swift.h" <-需要使用swift文件的objective-c内部文件。

对于Swift 5:

将@objc关键字添加到类和方法中 向类和方法添加public关键字 让你的类继承自NSObject 建设项目 在Objective-C文件中输入“MyProject-Swift.h” @objc MyClass: NSObject { @objc myMethod() { } }