ไม่สามารถใช้คลาส Swift ภายใน Objective-C


260

ฉันพยายามรวมSwiftรหัสในแอพของฉันแอพของฉันเขียนขึ้นObjective-Cและฉันเพิ่มSwiftคลาส ฉันได้ทำทุกอย่างที่อธิบายไว้ที่นี่ แต่ปัญหาของฉันคือXcodeยังไม่ได้สร้าง-Swift.hไฟล์เฉพาะส่วนหัวการเชื่อมโยง ดังนั้นฉันจึงสร้างมันขึ้นมา แต่มันว่างเปล่าจริง ๆ ฉันสามารถใช้คลาส ObjC ของฉันทั้งหมดใน Swift ได้ แต่ฉันไม่สามารถทำได้ในทางกลับกัน ฉันทำเครื่องหมายชั้นเรียนที่รวดเร็วด้วย@objcแต่มันก็ไม่ได้ช่วยอะไร ฉันจะทำอะไรได้บ้าง

แก้ไข: Apple พูดว่า: "เมื่อคุณนำเข้ารหัส Swift ลงใน Objective-C คุณต้องใช้Xcode-generatedไฟล์ส่วนหัวเพื่อเปิดเผยไฟล์เหล่านั้นไปยัง 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
    }
}

27
YourProjectName-Swift.hควรเป็นไฟล์ส่วนหัวเวทย์มนตร์ที่ Xcode สร้างขึ้นให้คุณโดยอัตโนมัติระหว่างการรวบรวม (คุณจะไม่เห็นมันในเบราว์เซอร์โครงการ) ลองลบไฟล์ที่คุณสร้างขึ้นและเพิ่ม#import YourProjectName-Swift.hไฟล์ที่คุณต้องการใช้คลาส Swift
เกร็ก

3
แอปของคุณที่คุณกำลังสร้างชื่ออยู่myProjectModuleหรือไม่ -Swift.hไฟล์ควรเริ่มต้นด้วยชื่อของแอป คุณมีไฟล์ที่ลงท้ายด้วย-Bridging-Header.hหรือไม่? คุณควร. ถ้าเป็นเช่นนั้นส่วนแรกของไฟล์นั้นคือชื่อโครงการของคุณ รวมส่วนแรกของชื่อไฟล์นั้นด้วย-Swift.hและนั่นคือสิ่งที่คุณควรรวมไว้ด้วย
vacawama

4
ฉันประสบความสำเร็จในการทำงานในโครงการของฉันแล้ว แต่ก็ไม่มีไฟล์จริงที่ลงท้ายด้วย-Swift.hMac ของฉันและยังสามารถรวมมันได้ ดังนั้นอย่าเมาค้างเพื่อค้นหาไฟล์ดังกล่าว เพียงตรวจสอบว่าคุณตั้งชื่อถูกต้อง
vacawama

2
@vacawama โปรดทราบว่าคุณสามารถดูเนื้อหาหลังจากที่คุณเพิ่มคำสั่งการนำเข้าไปยังไฟล์ Objective-C โดยการคลิกคำสั่งบนการนำเข้าราวกับว่าคุณกำลังเยี่ยมชมไฟล์ส่วนหัวอื่น ๆ
Kendall Helmstetter Gelner

4
ฉันต้องใช้#import <MyProjectName/MyProjectName-Swift.h>
Oliver Pearmain

คำตอบ:


516

ฉันใช้เวลาประมาณ 4 ชั่วโมงในการพยายามเปิดใช้งานSwiftในXcodeโครงการตามวัตถุประสงค์ของฉัน ฉันmyproject-Swift.hไฟล์ที่ถูกสร้างขึ้นประสบความสำเร็จ แต่ฉันไม่เห็นฉันXcode Swift-classesดังนั้นฉันตัดสินใจที่จะสร้างXcodeโครงการที่ใช้ Objc ใหม่และสุดท้ายฉันก็พบคำตอบที่ถูกต้อง! หวังว่าโพสต์นี้จะช่วยให้ใครบางคน :-)

การรวม Swift แบบทีละขั้นตอนสำหรับโครงการที่ใช้ Xcode Objc:

  1. สร้าง*.swiftไฟล์ใหม่(ใน Xcode) หรือเพิ่มโดยใช้ Finder
  2. สร้างObjective-C bridging headerเมื่อ Xcode ถามคุณเกี่ยวกับเรื่องนั้น
  3. ใช้คลาส Swift ของคุณ:

    import Foundation
    
    // use @objc or @objcMembers annotation if necessary
    class Foo {
        //..
    }
    
  4. เปิดการตั้งค่า Build และตรวจสอบพารามิเตอร์เหล่านี้:

    • กำหนดโมดูล: YES

      คัดลอกและวางชื่อพารามิเตอร์ในแถบค้นหา

    • ชื่อโมดูลผลิตภัณฑ์: myproject

      ตรวจสอบให้แน่ใจว่าชื่อโมดูลผลิตภัณฑ์ของคุณไม่มีอักขระพิเศษใด ๆ

    • ติดตั้งส่วนหัวความเข้ากันได้ Objective-C: YES

      เมื่อคุณเพิ่ม*.swiftไฟล์ลงในโครงการแล้วคุณสมบัตินี้จะปรากฏในการตั้งค่าการสร้าง

    • ส่วนหัวของอินเตอร์เฟสที่สร้างขึ้น C วัตถุประสงค์: myproject-Swift.h

      ส่วนหัวนี้สร้างขึ้นอัตโนมัติโดย Xcode

    • วัตถุประสงค์ -C Bridging Header: $(SRCROOT)/myproject-Bridging-Header.h
  5. นำเข้าส่วนหัวส่วนต่อประสาน Swift ในไฟล์ * .m ของคุณ

    #import "myproject-Swift.h"

    อย่าใส่ใจกับข้อผิดพลาดและคำเตือน

  6. ทำความสะอาดและสร้างโครงการ Xcode ของคุณใหม่
  7. กำไร!

2
มีใครเห็นถึงการกำหนดค่าที่ต้องการ (อย่างน้อยสำหรับฉัน) ในเอกสารประกอบที่: developer.apple.com/library/prerelease/ios/documentation/Swift/… ในขั้นตอนที่ 4 ด้านบน ถ้าเป็นฉันพลาดมัน ขอบคุณ @ ซิก
Morkrom

2
ปัญหาของฉันนั้นง่ายกว่ามาก - ฉันหาไฟล์ไม่พบ"myproject-Swift.h"ดังนั้นฉันคิดว่ามันใช้งานไม่ได้ เห็นได้ชัดว่าไฟล์นี้ไม่สามารถมองเห็นได้ในตัวนำทางโครงการ
Asaf

6
@Asaf ที่จริงแล้วใช่ไฟล์นี้สร้างอัตโนมัติโดย Xcode และค้นหาในเส้นทางการสร้างโครงการของคุณ ดังนั้นคุณสามารถหาไฟล์นี้ด้วยตนเองใน Finder / คอนโซลหรือเปิดโดยตรงใน Xcode โดยใช้ Cmd + LeftClick #import "myproject-Swift.h"บน
sig

1
สำหรับฉัน # 5 ก็เพียงพอที่จะแก้ไขปัญหาได้ !!
skywinder

12
ด้วย 4 ชั่วโมงเหล่านั้นของคุณคุณประหยัดหลายร้อยชั่วโมงของเราขอบคุณมาก :) บันทึกไว้ในรายการโปรดของฉัน;)
Abo3atef

65

อย่าสร้างไฟล์ส่วนหัวด้วยตัวคุณเอง ลบอันที่คุณสร้างขึ้น

ให้แน่ใจว่าสวิฟท์ชั้นเรียนของคุณมีการติดแท็กด้วย@objcหรือรับมรดกจากระดับที่บุคลากร (โดยตรงหรือโดยอ้อม) NSObjectจาก

Xcode จะไม่สร้างไฟล์หากคุณมีข้อผิดพลาดของคอมไพเลอร์ในโครงการของคุณ - ตรวจสอบให้แน่ใจว่าโครงการของคุณสร้างเรียบร้อย


8
ความสามารถในการสร้างเป็นกุญแจสำคัญสำหรับฉัน ไม่สามารถสร้างได้เนื่องจากไม่พบไฟล์ -swift.h ของฉัน แต่ไม่พบไฟล์ -swift.h ของฉันเพราะไม่สามารถสร้างได้: /
anders

13
@ และในขณะที่ถูกขังอยู่ในวงรอบนั้นคุณสามารถใช้find ~/library/Developer/Xcode/DerivedData/ -name "*-Swift.h"|xargs basename|sort -uเพื่อดูว่าไฟล์นั้นถูกสร้างขึ้นด้วยชื่อที่ไม่คาดคิดเช่นเดียวกับฉันหรือไม่ :)
CodeReaper

38

อนุญาตให้ Xcode ทำงานได้อย่าเพิ่ม / สร้าง Swift header ด้วยตนเอง เพียงเพิ่ม @objc ก่อนที่คลาสของ Swift จะออกมา

@objc class YourSwiftClassName: UIViewController

ในการตั้งค่าโครงการของคุณค้นหาการตั้งค่าสถานะด้านล่างและเปลี่ยนเป็น YES (ทั้งโครงการและเป้าหมาย)

Defines Module : YES
Always Embed Swift Standard Libraries : YES
Install Objective-C Compatibility Header : YES

จากนั้นทำความสะอาดโครงการและสร้างครั้งเดียวหลังจากสร้างสำเร็จ (ควรเป็นไปได้) นำเข้าไฟล์ส่วนหัวด้านล่างในไฟล์. c คลาส. m วัตถุประสงค์ของคุณ

#import "YourProjectName-Swift.h" 

Boooom!


1
ขอบคุณนี่ง่ายมากและแก้ไขปัญหาของฉัน
เฟลิเป้

ฉันไม่เห็นตัวเลือกเหล่านี้ใน Build Settings (Xcode 7.3.1) ฉันควรทำอย่างไรดี?
iosdude

1
^ ต้องเปลี่ยนจากBasicเป็นAllในแถบด้านบน
iosdude

1
Embedded Content Contains Swiftถูกเปลี่ยนเป็นAlways Embed Swift Standard LibrariesXcode 8: stackoverflow.com/questions/38792650/…
William Grand

@ WilliamGrand ขอบคุณสำหรับคำแนะนำอัปเดตคำตอบ
Bharat Modi

28

อาจเป็นประโยชน์สำหรับผู้ที่มีเป้าหมาย Framework :

คำสั่งนำเข้าของไฟล์ส่วนหัวสร้างขึ้นโดยอัตโนมัติมีลักษณะแตกต่างกันเล็กน้อยจากเป้าหมายของแอป นอกเหนือจากสิ่งอื่น ๆ ที่กล่าวถึงในคำตอบอื่น ๆ ใช้

#import <ProductName/ProductModuleName-Swift.h>

แทน

#import "ProductModuleName-Swift.h"

ตามเอกสารของแอปเปิ้ลเกี่ยวกับMix & Matchสำหรับเป้าหมายเฟรมเวิร์ก


1
@dinesharjani ดีใจที่ฉันช่วยได้! :)
Jeehut

สิ่งที่เกี่ยวกับกลุ่มเป้าหมาย?
Iulian Onofrei

14

ตรวจสอบให้แน่ใจว่าโครงการของคุณกำหนดโมดูลและคุณได้ตั้งชื่อให้กับโมดูล จากนั้นสร้างใหม่และ Xcode จะสร้าง-Swift.hไฟล์ส่วนหัวและคุณจะสามารถนำเข้าได้

คุณสามารถตั้งค่าการกำหนดโมดูลและชื่อโมดูลในการตั้งค่าโครงการของคุณ


14

รายละเอียด:โครงการ Objective-C พร้อม Swift 3 code ใน Xcode 8.1

งาน:

  1. ใช้ swift enum ในคลาส -c
  2. ใช้วัตถุประสงค์ -c enum ในระดับที่รวดเร็ว

ตัวอย่างเต็ม

1. คลาส Objective-C ซึ่งใช้ 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

ตรวจจับโค้ด Swift ในรหัส Objective-C

ในตัวอย่างของฉันฉันใช้ SwiftCode.h เพื่อตรวจจับรหัส Swift ใน Objective-C ไฟล์นี้สร้างขึ้นโดยอัตโนมัติ (ฉันไม่ได้สร้างสำเนาจริงของไฟล์ส่วนหัวนี้ในโครงการ) และคุณสามารถตั้งชื่อไฟล์นี้ได้เท่านั้น:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

หากคอมไพเลอร์ไม่สามารถค้นหาไฟล์ส่วนหัวของคุณรหัส Swift ลองรวบรวมโครงการ

2. คลาส Swift ที่ใช้ 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
        }
        
    }
}

ตรวจจับรหัส Objective-C ในรหัส Swift

คุณต้องสร้างไฟล์ส่วนหัวการเชื่อมต่อ เมื่อคุณเพิ่มไฟล์ Swift ในโครงการ Objective-C หรือไฟล์ Objective-C ในโครงการ Swift Xcode จะแนะนำให้คุณสร้างส่วนหัวการเชื่อมต่อ

ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถเปลี่ยนชื่อไฟล์ส่วนหัวบริดจ์ได้ที่นี่:

ป้อนคำอธิบายรูปภาพที่นี่

Bridging-Header.h

#import "ObjcClass.h"

การใช้

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

ผลลัพธ์

ป้อนคำอธิบายรูปภาพที่นี่


ตัวอย่างเพิ่มเติม

บูรณาการตามขั้นตอนที่ Objective-C และสวิฟท์กล่าวไว้ข้างต้น ตอนนี้ฉันจะเขียนตัวอย่างรหัสอื่น ๆ

3. เรียกคลาส Swift จากรหัส Objective-c

คลาสที่รวดเร็ว

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. เรียกคลาส Objective-c จาก Swift code

คลาส 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. ใช้ Swift extension ในรหัส Objective-c

ส่วนขยายที่รวดเร็ว

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

รหัส Objective-C (รหัสโทร)

[UIView swiftExtensionFunc];

6. ใช้ Objective-c extension ในรหัส swift

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 (รหัสโทร)

UIView.objcExtensionFunc()

ตัวอย่างเหล่านี้มีประโยชน์จริง ๆ ขอบคุณ! และสำหรับ Swift 4+ เราต้องเพิ่ม@objcMembersต่อหน้าชั้นเรียน เนื่องจากการ@objcอนุมานได้ลดลงใน Swift 4 เพื่อการเพิ่มประสิทธิภาพ ตัวอย่างเช่นคุณสมบัติภายในคลาสที่ได้รับจาก NSObject จะไม่อนุมาน @objc เป็นค่าเริ่มต้น (เช่นเดียวกับใน Swift 3) ฉันได้รับ intel นี้จากคำตอบนี้
Hustlion

11

ฉันมีปัญหาเดียวกันและปรากฎสัญลักษณ์พิเศษในชื่อโมดูลจะถูกแทนที่ด้วย xcode (ในกรณีที่ขีดกลางของฉันกลายเป็นขีดล่าง) ในการตั้งค่าโครงการให้ตรวจสอบ "ชื่อโมดูล" เพื่อค้นหาชื่อโมดูลสำหรับโครงการของคุณ หลังจากนั้นใช้ModuleName-Swift.hหรือเปลี่ยนชื่อโมดูลในการตั้งค่า


10
ฉันเป็นคนปัญญาอ่อน ฉันกำลังเพิ่มชื่อชั้นแล้วผนวก "-Swift" ปรากฎว่าเป็นชื่อ "โมดูล" +1 ที่ทำให้ฉันตระหนักถึงสิ่งนี้
HotFudgeSunday

2
ปัญญาอ่อนอีกคนที่นี่ที่คิดว่าเป็นชื่อคลาส!
Charlie Martin

9

ไฟล์จะถูกสร้างขึ้นโดยอัตโนมัติ (พูดถึง Xcode 6.3.2 ที่นี่) แต่คุณจะไม่เห็นมันเพราะมันอยู่ในโฟลเดอร์ Derived Data ของคุณ หลังจากทำเครื่องหมายคลาสที่รวดเร็วของคุณ@objcให้คอมไพล์แล้วค้นหาSwift.hในโฟลเดอร์ Derived Data ของคุณ คุณควรหาส่วนหัว Swift ที่นั่น

ผมมีปัญหาที่ Xcode เปลี่ยนชื่อของฉันmy-Project-Swift.hไปmy_Project-Swift.hXcode ไม่ชอบ "." "-"สัญลักษณ์ ฯลฯ ด้วยวิธีการด้านบนคุณสามารถค้นหาชื่อไฟล์และนำเข้าสู่คลาส Objective-C


1
นี่ก็แก้ปัญหาของฉันด้วย ในไฟล์. m ของฉันฉันนำเข้าไฟล์แบบนี้#import "my_project-Swift.h" และชื่อโครงการจริงของฉันคือmy-project
Bhavin_m

ความสนใจ - ไม่ใช่แค่ "." "-" ยังเว้นวรรค :(
user1105951

8

เพียงใส่ #import "myProject-Swift.h" ในไฟล์. m หรือ. h

PS คุณจะไม่พบ "myProject-Swift.h" ในตัวตรวจสอบไฟล์ที่ซ่อนอยู่ แต่แอปสร้างขึ้นโดยอัตโนมัติ


ขอบคุณสำหรับหัวขึ้นเพื่อน
เฟลิเป้

คำตอบนี้ช่วยฉันและช่วยชีวิตฉันไว้ สิ่งสำคัญคือ Xcode กำลังสร้างขึ้นโดยอัตโนมัติและเป็นไฟล์ HIDDEN ฉันกำลังสร้าง "myProject-Swift.h" ด้วยตัวเองและมันไม่ทำงาน
C0mrade

5

@sig คำตอบเป็นหนึ่งในสิ่งที่ดีที่สุด แต่มันไม่ได้ผลสำหรับฉันกับโปรเจ็กต์เก่า (ไม่ใช่ของใหม่!) ฉันต้องการการแก้ไขบางอย่าง หลังจากการเปลี่ยนแปลงมากมายฉันพบสูตรสำหรับฉัน (ใช้ XCode 7.2):

  1. ชื่อโมดูลผลิตภัณฑ์: $ (PRODUCT_NAME: c99extidentifier)
  2. กำหนดโมดูล: NO
  3. เนื้อหาแบบฝังประกอบด้วย Swift: NO
  4. ติดตั้งส่วนหัวความเข้ากันได้ของ Objective-C: YES
  5. วัตถุประสงค์ -C Bridging Header: ProjectName-Bridging-Header.h

จุดสุดท้าย (5) สำคัญมาก ฉันใส่เฉพาะในส่วนที่สอง (เขตข้อมูลเป้าหมาย), เขตข้อมูลโครงการควรเว้นว่างไว้: ป้อนคำอธิบายรูปภาพที่นี่ไม่เช่นนั้นจะไม่สร้างไฟล์ "Project-Swift.h" ที่เหมาะสมสำหรับฉัน


1
ลิงก์ที่มีประโยชน์เช่นกัน: ericasadun.com/2014/08/21/ …
Darius Miliauskas

1
Thanks Thanks Thanks Thanks มาก @DariusMiliauskas เพียงได้ทำงานกับลิงค์ของคุณ
a4arpan

1
@DariusMiliauskasthanks มาก ๆ ! 5 จุดยังแก้ไขปัญหาสำหรับฉันในโปรเจ็กต์ Xcode เก่า
tatiana_c

Define ModulesควรจะNo??
Sunil Chauhan

@SunilChauhan ใช่มันใช้สำหรับ framewoksเท่านั้น
Iulian Onofrei

5

มีสองเงื่อนไขคือ

  • ใช้ไฟล์ swift ของคุณในไฟล์ c วัตถุประสงค์
  • ใช้ไฟล์ c วัตถุประสงค์ของคุณในไฟล์ swift

ดังนั้นเพื่อจุดประสงค์นั้นคุณต้องทำตามขั้นตอนนี้:

  • เพิ่มไฟล์ swift ของคุณในโครงการ -c วัตถุประสงค์หรือในทางกลับกัน
  • สร้างไฟล์ส่วนหัว (.h)
  • ไปที่การสร้างการตั้งค่าและทำตามขั้นตอนด้านล่างด้วยการค้นหา

    1. ค้นหาข้อความนี้ "brid" และตั้งค่าพา ธ ของไฟล์ส่วนหัวของคุณ
    2. "กำหนดโมดูล": ใช่
    3. "ฝังไลบรารีมาตรฐาน Swift เสมอ": ใช่
    4. "ติดตั้งส่วนหัวความเข้ากันได้ Objective-C": ใช่

หลังจากนั้นทำความสะอาดและสร้างโครงการของคุณใหม่

ใช้ไฟล์ swift ของคุณในไฟล์ c วัตถุประสงค์

ในกรณีนี้อันดับแรกให้เขียน "@objc" ก่อนที่ชั้นเรียนของคุณจะเป็นไฟล์ swift

หลังจากนั้นในไฟล์ c วัตถุประสงค์ของคุณเขียนสิ่งนี้

  #import "YourProjectName-Swift.h"

ใช้ไฟล์ c วัตถุประสงค์ของคุณในไฟล์ swift

ในกรณีนั้นในไฟล์ส่วนหัวของคุณเขียนสิ่งนี้

  #import "YourObjective-c_FileName.h"

ฉันหวังว่านี่จะช่วยคุณได้


4

สำหรับ Swift 5:

  1. เพิ่ม@objcคำหลักให้กับชั้นเรียนและวิธีการของคุณ
  2. เพิ่มpublicคำหลักให้กับชั้นเรียนและวิธีการของคุณ
  3. ให้ชั้นเรียนของคุณสืบทอด NSObject
  4. สร้างโครงการ
  5. ใส่#import "MyProject-Swift.h"ในไฟล์ Objective-C ของคุณ

    @objc
    public class MyClass: NSObject {
    
        @objc
        public func myMethod() {
    
        }
    }

"เพิ่มคำหลัก @objc ให้กับชั้นเรียนและวิธีการของคุณ" - เหมือนกันสำหรับ Swift 4
Krzysztof Skrzynecki

3

ในกรณีของฉันนอกเหนือจากขั้นตอนเหล่านี้:

  1. ชื่อโมดูลผลิตภัณฑ์: myproject
  2. กำหนดโมดูล: ใช่
  3. เนื้อหาแบบฝังประกอบด้วย Swift: YES
  4. ติดตั้งส่วนหัวความเข้ากันได้ของ Objective-C: YES
  5. ส่วนหัว Bridging-C วัตถุประสงค์: $ (SRCROOT) / แหล่งที่มา /SwiftBridging.h

ฉันต้องการทำให้คลาสเป็นแบบสาธารณะเพื่อสร้างไฟล์productName-Swift.h :

import UIKit

   @objc public class TestSwift: NSObject {
       func sayHello() {
          print("Hi there!")
       }
   }

2

ฉันเพิ่งค้นพบว่าการเพิ่มไดเรกทอรีของไฟล์ swift ลงในโครงการจะไม่ทำงาน คุณต้องสร้างกลุ่มก่อนสำหรับไดเรกทอรีจากนั้นเพิ่มไฟล์ swift ...


@ <คลาสเฉพาะ>; ควรกำหนดไว้และจากนั้นโครงการที่ใช้จะเห็นไฟล์เหล่านั้น
Nikita

2

ฉันมีปัญหาเดียวกันและในที่สุดก็ปรากฏว่าพวกเขาไม่ได้ยึดติดกับเป้าหมายเดียวกัน คลาส ObjC แนบกับ Target1 และ Target2 คลาส Swift จะแนบกับ Target1 เท่านั้นและไม่สามารถมองเห็นได้ภายในคลาส ObjC

หวังว่านี่จะช่วยใครซักคน


ฉันมองข้ามสิ่งนี้อย่างสมบูรณ์โดยมีเป้าหมายที่แตกต่างกันสำหรับการจัดเตรียมและการผลิต ขอบคุณสำหรับคำตอบ!
Benjamin Martin

"แนบ" หมายถึงอะไร
Iulian Onofrei

"แนบ" = "สมาชิก" พวกเขาควรถูกระบุว่าเป็นสมาชิกเป้าหมาย
Dani.Rangelov

1

ปัญหาของฉันคือฉันติดหลังจาก xcode สร้างไฟล์บริดจ์ แต่ฉันยังคงมีข้อผิดพลาดในชื่อไฟล์ส่วนหัว MYPROJECTNAME-swift.h

1. ฉันเช็คอินเทอร์มินัลและค้นหาไฟล์บริดจ์ swift ที่สร้างอัตโนมัติทั้งหมด:

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

คุณเห็นสิ่งที่ xcode สร้างขึ้น

  1. ในกรณีของฉันฉันมีพื้นที่ในชื่อโครงการและ xcode แทนที่นี่คือ '_'

1

เมื่อคุณเพิ่มไฟล์ Swift ใหม่ลงในโครงการโปรดตรวจสอบให้แน่ใจว่าคุณเพิ่มไฟล์เหล่านั้นเพื่อแก้ไขเป้าหมาย โปรดตรวจสอบให้แน่ใจว่าไฟล์ swift ทุกไฟล์ที่คุณจะใช้สืบทอดคลาส NSObject และใส่คำอธิบายประกอบด้วย @ObjCMembers เปลี่ยนเป็น YES ภายในการตั้งค่าบิลด์ภายใต้ตัวเลือก ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES เปลี่ยนเป็น YES ภายในการตั้งค่าการสร้างภายใต้ตัวเลือก DEFINES_MODULE


0

ฉันมีข้อผิดพลาดเดียวกัน: myProjectModule-Swift.hไม่พบไฟล์ "แต่ในกรณีของฉันเหตุผลที่แท้จริงคือเป้าหมายการปรับใช้ที่ไม่ถูกต้อง:" Swiftไม่สามารถใช้งานได้ใน OS X ก่อนหน้า 10.9; โปรดตั้งค่าMACOSX_DEPLOYMENT_TARGETเป็น 10.9 หรือใหม่กว่า (ปัจจุบันคือ '10 .7 ') "ดังนั้นเมื่อฉันเปลี่ยนเป้าหมายการปรับใช้เป็น 10.9 - โครงการได้รับการรวบรวมสำเร็จ


0

ปัญหาของฉันคือไฟล์ auto-generation -swift.h ไม่สามารถเข้าใจคลาสย่อยของ CustomDebugStringConvertible ได้ ฉันเปลี่ยนคลาสเป็น subclass ของ NSObject แทน หลังจากนั้นไฟล์ -swift.h รวมคลาสอย่างถูกต้องแล้ว


0

ฉันมีปัญหาในการที่ฉันจะเพิ่มเรียนในส่วนหัว Bridging วัตถุประสงค์ -c ของฉันและในส่วนหัว -c วัตถุประสงค์ที่นำเข้าพวกเขากำลังพยายามที่จะนำเข้าส่วนหัวอย่างรวดเร็ว มันไม่เป็นเช่นนั้น

ดังนั้นในคลาส -c ของฉันทุกวัตถุประสงค์ที่ใช้ swift แต่ยังเชื่อมโยงคีย์คือเพื่อให้แน่ใจว่าคุณใช้การประกาศคลาสไปข้างหน้าในส่วนหัวจากนั้นนำเข้าไฟล์ "* -Swift.h" ในไฟล์. m


0

ฉันไม่จำเป็นต้องเปลี่ยนการตั้งค่าใด ๆ ในบิลด์หรือเพิ่ม @obj ให้กับคลาส

สิ่งที่ฉันต้องทำคือสร้างหัวสะพานซึ่งสร้างขึ้นโดยอัตโนมัติเมื่อฉันสร้างคลาส Swift ในโครงการ Objective-c จากนั้นฉันก็ต้องทำ

นำเข้า "Bedtime-Swift.h" <- ไฟล์ภายใน -c วัตถุประสงค์ที่จำเป็นต้องใช้ไฟล์ swift นั้น


0

ดีหลังจากที่ได้อ่านความคิดเห็นทั้งหมดและพยายามอ่านและลองอีกครั้งฉันก็สามารถรวมคลาส swift ลงในโครงการ Big obj-c ของฉันได้ ดังนั้นขอขอบคุณสำหรับความช่วยเหลือทั้งหมด ฉันต้องการแบ่งปันเคล็ดลับหนึ่งข้อที่ช่วยให้ฉันเข้าใจกระบวนการดีขึ้น ในคลาส. m ไปที่บรรทัดการนำเข้าของชื่อเป้าหมาย swift #import "myTargetName-Swift.h" และคลิกที่คีย์:

คำสั่ง + คลิกเมาส์ -> ข้ามไปที่การกำหนด ป้อนคำอธิบายรูปภาพที่นี่

คุณสามารถดูคำแปลทั้งหมดได้อย่างรวดเร็วจาก obj-c และคุณจะพบกับฟังก์ชั่นต่างๆที่ประกาศใหม่ใน obj-c หวังว่าเคล็ดลับนี้จะช่วยคุณได้มากเท่าที่ช่วยฉัน


0

การใช้คลาส Swift ใน Objective-C

หากคุณกำลังจะนำเข้ารหัสภายในเป้าหมายของแอป (การผสม Objective-C และ Swift ในโครงการหนึ่ง) คุณควรใช้บรรทัดการนำเข้าถัดไป#import "<#YourProjectName#>-Swift.h"เพื่อแสดงรหัส Swift ไปยังรหัส Objective-C [รหัสการผสม Swift และ Objective-C ในโครงการ]

ในโพสต์นี้ฉันจะอธิบายวิธีการนำเข้าไลบรารี Swift นิ่งไปยังรหัส Objective-C

Objective-C consumer -> ไลบรารี่คงที่ของ Swift

Xcode รุ่น 10.2.1

สร้างห้องสมุดคง Swift

ติดตามCreate Swift static libraryด้วยการเพิ่มเติมต่อไป:

เปิดเผย Swift API หากต้องการใช้ฟังก์ชั่นของ Swift จาก Objective-C [เกี่ยวกับ]

หลังการสร้างคุณควรหา<product_name>-Swift.hไฟล์ที่ควรอยู่ในDerivedSources [ไม่พบไฟล์]

Objective-C consumer ที่มีไลบรารี่คงที่ของ Swift

Drag and dropไบนารีในโครงการ Xcode [เกี่ยวกับ]

Link Library[สัญลักษณ์ที่ไม่ได้กำหนด] [ลิงก์ vs ฝัง]

Project editor -> select a target -> General -> Linked Frameworks and Libraries -> add -> Add Others... -> point to `lib<product_name>.a` file
//or
Project editor -> select a target -> Build Phases -> Link Binary With Libraries -> add -> Add Others... -> point to `lib<product_name>.a` file

เพิ่มLibrary Search paths[ไม่พบไลบรารีสำหรับ] [เส้นทางแบบเรียกซ้ำ]

Project editor -> select a target -> Build Settings -> Search Paths -> Library Search paths -> add path to the parent of `lib<product_name>.a` file

เพิ่มHeader Search Paths[ไม่พบโมดูล] [เส้นทางแบบเรียกซ้ำ]

Project editor -> select a target -> Build Settings -> Search Paths -> Header Search Paths -> add path to generated `<product_name>-Swift.h` file 

เพิ่มที่ว่างเปล่า.swift fileให้กับโครงการ Objective-C [สัญลักษณ์ที่ไม่ได้กำหนด] เมื่อ Xcode ถามกดสร้างBridging Header(มันจะสร้างmodule_name-Bridging-Header.h) และตั้งค่าเส้นทางไปยังไฟล์นี้

Project editor -> select a target -> Build Settings -> Swift Compiler - General -> Objective-C Bridging Header

อิมพอร์ตโมดูลไปยังโค้ดไคลเอ็นต์ Objective-C [ไม่พบไฟล์] [module_name]

#import "module_name-Swift.h"

ตัวอย่างเพิ่มเติมที่นี่


0

XCode 11.3.1:

เมื่อฉันต้องการใช้คลาสภายใน Swift ในรหัส objc มันไม่ได้คอมไพล์สำหรับข้อผิดพลาด "สัญลักษณ์ที่ไม่ได้กำหนด" (สำหรับคลาสภายในและคลาสภายนอกที่น่ารำคาญ) ฉันตรวจสอบส่วนหัว "-swift.h" ที่สร้างขึ้นและทั้งสองคลาสนั้น ที่นั่น

หลังจากลองเป็นเวลาหลายชั่วโมงฉันจะแปลงคลาสภายในเป็นคลาสปกติและรวบรวม

ฉันล้างโครงการลบโฟลเดอร์ DerivedData และคอมไพล์


1
คุณลองเพิ่ม@objcก่อนการประกาศของชั้นในหรือไม่?
dnnagy

ขอบคุณ @dnnagy ตรวจสอบว่าไม่ใช่ปัญหาไวยากรณ์
Bill Chan

-1

หลังจากทำทุกอย่างด้านบนแล้วฉันยังพบข้อผิดพลาด ปัญหาของฉันก็คือไฟล์ Swift ที่ฉันต้องการไม่ได้ถูกเพิ่มเข้าไปในทรัพยากรบันเดิลด้วยเหตุผลบางอย่าง

ฉันแก้ไขสิ่งนี้ได้โดยไปที่ [MyTarget]> Build Phases> Copy Bundle Resources จากนั้นคลิกปุ่มบวกและเพิ่มไฟล์ Swift


คัดลอกทรัพยากรบันเดิลไม่ควรมีซอร์สโค้ด
Bill Chan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.