ไม่พบการนำเข้า Project-Swift.h ไปยังคลาส Objective-C …


131

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

ฉันได้ปรึกษาเอกสารของ Apple เกี่ยวกับการใช้ Swift และ Objective-C ในโครงการเดียวกันรวมถึงคำถาม SO เช่นนี้ แต่ก็ยังไม่มีประโยชน์: ฉันยังคงได้รับไฟล์ไม่พบข้อผิดพลาดหลังจากใส่#import "NewTestApp-Swift.h"( NewTestAppคือชื่อของผลิตภัณฑ์ และโมดูล)

นี่คือสิ่งที่ฉันได้ทำไปแล้ว:

  1. ในDefine ModulesเลือกYESสำหรับแอป
  2. ตรวจสอบให้แน่ใจว่าชื่อโมดูลผลิตภัณฑ์ไม่มีที่ว่าง (ดูภาพหน้าจอด้านล่างคำถาม)

ผมได้ลองใช้#import "NewTestApp-Swift.h"ภายในViewController.m, ViewController.hและAppDelegate.mแต่ไม่มีพวกเขาได้ทำงาน

ฉันทำอะไรไม่ถูกต้องอีก? ขอบคุณสำหรับความช่วยเหลือของคุณ.


ภาพหน้าจอของการตั้งค่า:

ใส่คำอธิบายภาพที่นี่


ข้อผิดพลาดที่ฉันพบในปัจจุบัน:

ใส่คำอธิบายภาพที่นี่


3
ลบข้อมูลที่ได้รับทั้งหมดใน~/Library/Developer/Xcode/DerivedDataเคล็ดลับสำหรับฉัน
wzhang84

นี่คือวิธีที่ฉันแก้ไขปัญหา: stackoverflow.com/a/45338549/8102549
schrulnz

คำตอบ:


160

ฉันประสบปัญหาเดียวกันและไม่สามารถรับโปรเจ็กต์ของฉันเพื่อนำเข้าอย่างรวดเร็วในคลาส obj-c ใช้ Xcode 6 (ควรใช้กับ Xcode 6+) และสามารถทำได้ด้วยวิธีนี้ ...

  1. คลาสใด ๆ ที่คุณต้องการเข้าถึงในไฟล์. hจะต้องมีการประกาศไปข้างหน้าเช่นนี้

@class MySwiftClass;

  1. ในไฟล์. m เท่านั้นหากรหัสอยู่ในโครงการเดียวกัน (โมดูล) คุณต้องนำเข้าด้วยไฟล์

#import "ProductModuleName-Swift.h"

ลิงก์ไปยังเอกสารของ Apple เกี่ยวกับเรื่องนี้

https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_swift_into_objective-c


3
ขอบคุณสำหรับคำตอบ. นั่นทำให้ฉันไปสู่ทิศทางที่ถูกต้อง ฉันมีปัญหาเดียวกัน แต่มีโปรโตคอลดังนั้นฉันจึงต้องเพิ่ม @protocol MySwiftProtocol แทนการนำเข้าในไฟล์ส่วนหัวของฉัน
60

ในการประกาศการส่งต่อไฟล์. h ของคลาสโดยไม่ต้องจัดเก็บไฟล์. h เป็นเคล็ดลับสำหรับฉัน ขอบคุณ
Sikander

1
โปรดทราบว่าถ้าชื่อผลิตภัณฑ์ของคุณมีตัวละครในนั้นชื่อของไฟล์ส่วนหัวที่สร้างขึ้นจะมีที่แปลง- _เช่นถ้าชื่อผลิตภัณฑ์ของคุณเป็นคุณจะนำเข้าMy-App My_App-Swift.h
dvanoni

1
ฉันพบวิธีใหม่ในการค้นหาชื่อไฟล์ส่วนหัวที่สร้างขึ้นที่ถูกต้อง: ไปที่เป้าหมายของคุณ -> การตั้งค่าการสร้าง -> คำค้นหาObjective-C Generated Interface Header Name , บิงโก!
Itachi

2
ฉันได้ทำทั้งสองสิ่งนี้แล้วและยังคงพบปัญหาเดียวกัน คุณคิดว่ามันเกี่ยวข้องกับคำสั่งซื้อหรือไม่?
ArielSD

83

หากโค้ด Swift อยู่ในโมดูล (เช่นในกรณีของคุณ):

#import <ProductName/ProductModuleName-Swift.h>

หากโค้ด Swift อยู่ในโปรเจ็กต์ (ผสม Swift และ ObjC):

#import <ProductModuleName-Swift.h>

ในกรณีของคุณคุณต้องเพิ่มบรรทัดนี้ในไฟล์ * .m:

#import <NewTestApp/NewTestApp-Swift.h>

สำคัญ: ดูที่ "<" ในคำสั่งนำเข้า

https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html


ขอบคุณที่ตอบ @ ikocel1 น่าเสียดายที่สิ่งเหล่านี้ไม่ได้ผล ฉันได้พยายามรูปแบบของ<NewTestApp-Swift/NewTestApp-Swift.h>, <NewTestApp/NewTestApp-Swift.h>และ<NewTestApp/ViewController-Swift.h>ภายในทั้งหมดViewController.mแต่ยังคงได้รับ "ไฟล์ไม่พบข้อผิดพลาด" แม้จะมีCleaningโครงการในแต่ละครั้งหลังจากที่พยายามรวมกัน ฉันได้รวมภาพหน้าจอไว้ในเนื้อหาของคำถามเผื่อว่าจะช่วยได้
daspianist

ผมยังไม่ได้ป้อนรหัส Swift ใด ๆ ViewController.mลงไป ฉันพยายามแค่นำเข้าส่วนหัวก่อนเพื่อพยายามให้มันยอมรับรหัส Swift ฉันจะผสมและจับคู่รหัส Objective-C และ Swift ในViewController.m.
daspianist

1
ฉันไม่รู้ว่ามันเป็นไปได้ไหมที่จะผสมรหัส objc โดยตรงกับรหัสที่รวดเร็วในไฟล์เดียวกัน
ikocel1

1
ขอบคุณฉันเดาว่านี่เป็นข้อสันนิษฐานที่ฉันอิงตามเอกสาร "มิกซ์แอนด์แมตช์" ของ Apple .. แต่ฉันเดาว่าไม่ได้อยู่ในไฟล์จริง ขอบคุณ!
daspianist

6
ฉันไม่เข้าใจว่าทำไมคำตอบนี้จึงได้รับการอนุมัติ ใช่ถูกต้องตามเอกสาร แต่ในทางปฏิบัติก็ใช้ไม่ได้กับฉันเช่นกัน แม้ในคำถามจะเห็นได้ชัดว่าผู้ใช้ใช้ไวยากรณ์ตามที่แนะนำในคำตอบนี้ แต่ยังคงได้รับข้อผิดพลาด
Darius Miliauskas

54

ฉันจัดการการนำเข้าอย่างรวดเร็วไปยังวัตถุประสงค์ -c ได้อย่างไร:

  • กำหนดโมดูลที่ตั้งค่าเป็นใช่ (ในโครงการ - ไม่ใช่เป้าหมาย)
  • ชื่อโมดูลผลิตภัณฑ์ที่ตั้งไว้ (ตามเป้าหมาย - ไม่ใช่ในโครงการ)
  • ใน ViewController.m ของคุณนำเข้ารหัสที่รวดเร็วด้วย:

    #import "MyProductModuleName-Swift.h"
  • เพิ่มไฟล์ที่รวดเร็วในโครงการ Object-c ของคุณ (ไฟล์ -> ใหม่ -> Swift) และXcode จะสร้างส่วนหัวเชื่อมต่อจาก objective-c ถึง Swift แต่สิ่งนี้มีความสำคัญในการทำให้มันทำงานในทางอื่นด้วยเช่นกัน

สำหรับชิ้นส่วนสุดท้ายในปริศนานี้ต้องขอบคุณ Swiftoverload ที่ทำให้ฉันรู้ว่าการเพิ่มไฟล์ Swift ผ่าน Xcode GUI ไม่ใช่แค่การลากและวางไฟล์ที่รวดเร็วที่มีอยู่ลงในโปรเจ็กต์ของฉันเพื่อให้มันใช้งานได้: http://nikolakirev.com/blog / ใช้-รวดเร็วในวัตถุประสงค์ -c โครงการ


บันทึกที่ยอดเยี่ยม ฉันจะเพิ่มว่าเป้าหมายการทดสอบเป็นโมดูลของตัวเองและจะมีส่วนหัวของตัวเองชื่อ "<#TestTargetName #> - Swift.h" และช่องว่างในชื่อเป้าหมายจะถูกแปลงเป็นช่องว่าง
Chuck Krutsinger

@ holm51 ขอโทษที่ถามสิ่งนี้ แต่อยู่ที่ไหนDefine ModuleและProduct Module Name?
matchifang

ขีดกลาง-ในชื่อจะถูกแปลงเป็นขีดล่าง_เช่นกัน
CyberMew

11

ใช้ Xcode 8.2.1 และถ้าคุณดูที่Project > Build Settings> Objective-C Generated Interface Header Nameจะแสดงไฟล์ส่วนหัวเพียงไฟล์เดียวชื่อProduct -Swift.h

ซึ่งหมายความว่าแทนที่จะนำเข้าแต่ละโมดูลแยกจากไฟล์ Objective-C .m โดยใช้ไฟล์ -Swift.h แต่ละไฟล์คุณเพียงแค่นำเข้าProduct -Swift.h หนึ่งรายการซึ่งรวมโมดูล Swift ทั้งหมดไว้ด้วยกัน

ฉันพบปัญหาเดียวกันโดยมองหาวิธีการนำเข้าโมดูลแบบดั้งเดิมแยกกัน แต่ Xcode และ Swift 3 เวอร์ชันปัจจุบันเปลี่ยนให้ใช้ส่วนหัวเดียวสำหรับการนำเข้าโมดูลทั้งหมด


สวัสดีปีเตอร์คุณจะหาไฟล์นี้ได้ที่ไหน หรือมันสร้างขึ้นโดยอัตโนมัติโดย xcode? นอกจากนี้คุณต้องตั้งค่า podfile ให้แตกต่างกันเนื่องจากการเปลี่ยนแปลงนี้หรือไม่?
Rob Norback

@RobNorback ถ้าฉันไม่ผิดคุณสามารถเขียน "import" Product-Swift.h "ในไฟล์ส่วนหัว / การนำไปใช้งานของ Obj-C เพื่อดูผลโดยไม่ต้องทำอะไรเพิ่มเติม ตรวจสอบให้แน่ใจว่าการตั้งค่าโปรเจ็กต์ของคุณเปิดใช้งานการกำหนดค่าทั้งหมดสำหรับการผสม Swift และ Obj-C นอกจากนี้ฉันยังไม่พบปัญหากับ Podfile โปรดแจ้งให้เราทราบหากฉันเห็นสิ่งต่าง ๆ
petershine

ขอบคุณฉันใช้เวลาหลายชั่วโมงในการพยายามแก้ไขข้อบกพร่องนี้และปัญหาก็คือแต่ละโมดูลในโครงการของฉันกำลังสร้าง-Swift.hไฟล์ส่วนหัวของตัวเอง บังคับให้พวกเขาทั้งหมด (ฉันมี 5 เป้าหมาย) ให้ใช้ไฟล์ส่วนหัวทั่วไปแก้ไขปัญหาให้ฉัน
Apoorv Khatreja

@ApoorvKhatreja คุณบังคับให้พวกเขาทำเช่นนั้นได้อย่างไร? เขียนชื่อไฟล์อย่างโจ่งแจ้ง?
Amit Raz

8

ใช้เวลาหนึ่งชั่วโมงในการแก้ไขปัญหานี้การทำตามขั้นตอนเหล่านี้จะช่วยให้คุณเข้าใจสิ่งที่ขาดหายไป

  1. เปิดการตั้งค่า Xcode และไปที่โฟลเดอร์ DerivedData
  2. ค้นหา "swift.h" ใน Finder
  3. หากคุณไม่พบไฟล์ project-swift.h แสดงว่าไฟล์นี้ไม่ถูกสร้างขึ้น โดยปกติคุณจะต้องเพิ่ม @objc ลงในคลาสที่รวดเร็วของคุณและสร้างแอปให้สำเร็จจากนั้น Xcode จะสร้างไฟล์นี้
  4. หากคุณพบไฟล์ "xxx-swift.h" ให้ตรวจสอบว่าคำสั่งการนำเข้าของคุณมีชื่อที่ถูกต้อง

วิธีที่จะหา-รวดเร็วไฟล์


กรุณาอย่าเพิ่มคำตอบเดียวกันกับหลายคำถาม ตอบคำถามที่ดีที่สุดและตั้งค่าสถานะที่เหลือว่าซ้ำกันเมื่อคุณได้รับชื่อเสียงมากพอ หากไม่ใช่รายการที่ซ้ำกันให้ปรับแต่งโพสต์ให้ตรงกับคำถามและตั้งค่าสถานะสำหรับการยกเลิกการลบ
Bhargav Rao

ขอบคุณสำหรับสิ่งนี้! ฉันเปลี่ยนชื่อนักการทูตของแอป (ไม่ใช่ของเป้าหมาย) และส่วนหัวของ Swift ก็เปลี่ยนชื่อเช่นกัน นี่เป็นวิธีเดียวที่ฉันจะพบว่าเกิดอะไรขึ้น
Lucas P.

ขอบคุณสำหรับการโพสต์คำตอบ ภาพหน้าจอและรูปแบบจุดที่แม่นยำทำให้ฉันเลื่อนกลับทันที + ดู + สิ้นสุดการค้นหา ... แก้ปัญหาได้!
dklt

6

ฉันประสบปัญหาในการนำเข้า Swift ไปยังโครงการ Objective-C ในที่สุดฉันก็เข้าไปดูในโฟลเดอร์ Derivied Data เพื่อตรวจสอบว่า Xcode 7 กำลังสร้างอะไร ชื่อไฟล์แตกต่างอย่างสิ้นเชิงกับชื่อที่ฉันคาดหวัง

เมื่อฉันมีชื่อไฟล์จริงแล้วฉันก็นำเข้าและโครงการสามารถสร้างได้


2
ไฟล์นี้อยู่ที่ไหน ฉันมองไปรอบ ๆ และไม่พบอะไรเลย
Amit Raz

5

-Swift.hควรสร้างโดย Xcode โดยอัตโนมัติหากโค้ด Swift เปิดเผย API ผ่าน@objcหรือ@objcMembers[เกี่ยวกับ]

โดยปกติแล้วตำแหน่งจะมีลักษณะดังนี้

~/Library/Developer/Xcode/DerivedData/
  ProductModuleName-foo/
    Build/
      Intermediates.noindex/
        ProductModuleName.build/
          Debug-iphoneos/
            ProductModuleName.build/
              DerivedSources/
                ProductModuleName-Swift.h

สามารถเปลี่ยนแปลงได้โดย

Project editor -> select a target -> Build Settings -> Per-configuration Intermediate Build Files Path

โดยค่าเริ่มต้นคือ $(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)


2

DEFINE MODULES: ใช่และนำเข้า "ProjectName-Swift.h" ในไฟล์. m ของคลาส Obj-C

สิ่งนี้ได้ผลสำหรับฉันในการเข้าถึงคลาส Swift ใน Obj-c


3
แต่จะนำเข้าเป็นไฟล์. h ได้อย่างไรถ้าฉันต้องการคลาสที่รวดเร็วในส่วนหัว objc
Alexander Danilov

1

เคยประสบปัญหาเดียวกันกับทีมของฉันเมื่อทำงานกับโครงการโดยใช้ git นักพัฒนารายหนึ่งยังไม่ได้อัปเดต Xcode เป็นเวอร์ชันล่าสุด (7.3) ซึ่งจำเป็นสำหรับ Swift 2.2 เวอร์ชันล่าสุด ดังนั้นคอมไพเลอร์ไม่รู้จักไวยากรณ์ Swift ใหม่และไม่สามารถสร้างอินเทอร์เฟซสำหรับไลบรารี Swift (projectname-swift.h) ตรวจสอบว่า Xcode เป็นเวอร์ชันล่าสุดหรือไม่!


กรณีของฉันฉันประสบปัญหาเนื่องจากได้ตัดสินใจที่จะเลื่อนการโยกย้ายไปยัง Swift 3 ที่ Xcode นำเสนอ เป็นผลให้ Xcode ไม่สามารถสร้างซอร์สไฟล์ Swift และไม่ได้สร้างส่วนหัวที่จะรวม
iutinvg

1

ในระหว่างการพัฒนาอาจมีความเป็นไปได้ที่คุณจะมีคลาสที่รวดเร็วซึ่งไม่ได้ใช้งานอย่างสมบูรณ์เนื่องจากอาจมีข้อผิดพลาดทางไวยากรณ์ ไฟล์ส่วนหัวที่รวดเร็วจะพร้อมใช้งานก็ต่อเมื่อไฟล์ที่รวดเร็วทั้งหมดไม่มีข้อผิดพลาด

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


1

การนำเข้าไฟล์ส่วนหัวเช่น

#import "<ProjectName>-Swift.h" 

ภายในไฟล์. h สร้างข้อผิดพลาดโดยระบุว่า:

ไม่พบไฟล์ -Swift.h '

และการสร้างล้มเหลว

ใช้แทน:

#import "<ProjectName>-Swift.h"

ภายในไฟล์. m และแม้ว่าข้อผิดพลาดเดียวกันจะปรากฏขึ้น แต่การเรียกใช้โปรเจ็กต์จะระงับข้อผิดพลาดนั้น

จากนั้นคลาสที่รวดเร็วจะพร้อมใช้งานภายในไฟล์. m


1

ฉันประสบปัญหากับชื่อโครงการ (เป้าหมาย) มีสัญลักษณ์ "-" ดังนั้นการตัดสินใจต่อไป: ถ้าชื่อโครงการคือ "Test-App" ชื่อของคลาสที่นำเข้าคือ "Test_App-Swift.h"


โซลูชันที่ยอดเยี่ยม
iOS Lifee

1

หากชื่อแอปของคุณมีอักขระพิเศษให้ใช้ _ สำหรับอักขระพิเศษ

ตัวอย่างเช่นหากชื่อแอปของคุณคือชื่อ "Test App®"

จากนั้นคุณสามารถนำเข้าไฟล์ที่รวดเร็วโดย "Test_App_-Swift.h"

Space และ®ถูกแทนที่ด้วย _ ในขณะที่คุณกำลังนำเข้า


0

หากคุณมีหลายเป้าหมายตรวจสอบให้แน่ใจว่าคุณได้สร้างกรอบงานทั้งหมดแล้ว


0

Xcode 11

ฉันพบปัญหานี้เมื่อสร้างบน Xcode 11 ใช้เวลาเล็กน้อยเพื่อหาว่าอะไรผิดปกติ แต่โดยพื้นฐานแล้วฉันได้เปลี่ยนการตั้งค่า "ชื่อที่แสดง" ในแท็บ "ทั่วไป" ของเป้าหมายแทนที่จะเปลี่ยนโดยตรงในInfo.plistไฟล์ผ่านแท็บแท็บ "ข้อมูล" บนเป้าหมาย

สิ่งนี้ส่งผลให้ Xcode 11.5 ต้องผ่านการเขียนใหม่ / สร้างการตั้งค่าบิลด์ที่กำหนดเองใหม่เอี่ยมและแก้ไขชื่อของโมดูลแอพและผลิตภัณฑ์. app ที่สร้างขึ้น ในกรณีนี้ชื่อที่แสดงใหม่ยังมี/อักขระสแลช ( ) ข้างหน้าซึ่งในที่สุดอาจเป็นสาเหตุที่ไม่ได้สร้าง (ดูคำตอบของ@Silversky Technology )

ไม่ว่าฉันจะแก้ไขสิ่งนี้โดยการยกเลิกการเปลี่ยนแปลงอัตโนมัติทั้งหมดของ Xcode 11.5 ในไฟล์โครงการและทำการเปลี่ยนแปลงชื่อที่แสดงของกลุ่มในInfo.plistไฟล์ด้วยตนเองและทุกอย่างทำงานได้อย่างสมบูรณ์

ฉันหวังว่ามันจะบอกคุณว่ามันกำลังทำเรื่องแบบนี้ก่อนที่มันจะเกิดขึ้นและทำโดยไม่ได้รับความยินยอมจากคุณ


0

ตรวจสอบให้แน่ใจว่าคลาสที่รวดเร็วของคุณมีการประกาศต่อสาธารณะและขยาย NSObject:

public class MySwiftClass: NSObject {
    //...
}

การนำเข้าควรใช้กับเครื่องหมายคำพูดไม่ใช่วงเล็บหากคลาสที่รวดเร็วอยู่ในโปรเจ็กต์เดียวกัน


0

หากคุณเพิ่มไฟล์ Swift ก่อนให้จำไว้ว่าจะเพิ่มไฟล์ที่รวดเร็วไปยังเป้าหมายของคุณ ... ในคอลัมน์ด้านซ้าย

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