ส่วนหัว Swift to Objective-C ไม่ได้สร้างใน Xcode 6


242

ฉันเพิ่งทำงานเพื่อเพิ่ม Swift ลงในโครงการที่มีอยู่เพื่อทดลองใช้ในโลกแห่งความจริง

เมื่อเพิ่มไฟล์ต้นฉบับ Swift ลงในโครงการฉันไม่มีปัญหาเกี่ยวกับการรับ "Bridging Header" นั่นคือ Objective-C to Swift

แต่*-Swift.hไฟล์ส่วนหัวที่ควรจะเปิดเผยเรียน Swift ทำเครื่องหมายอย่างใดอย่างหนึ่ง@objcหรือ subclasses ของชั้นเรียน ObjC คือไม่มีที่ไหนเลยที่จะพบ :-(

ฉันไม่เห็นคำแนะนำเฉพาะเกี่ยวกับวิธีการใช้งานคลาสย่อยใหม่ของฉันซึ่งเขียนด้วย Swift ในรหัสแอปหลักของฉัน (ซึ่งยังคงเป็น Objective-C)

แอพที่ฉันเป็นผู้นำในการพัฒนามี codebase ค่อนข้างใหญ่ (70.000 บรรทัด) ดังนั้นการเปลี่ยนในครั้งเดียวนั้นหมดไป


5
ใช่แล้ว. มันถามว่าที่ไหนใน XCode IDE คุณต้องทำอะไรบางอย่างเพื่อให้ได้ Swift-> ObjC นี้สร้างขึ้นเพราะมันไม่ได้เกิดขึ้น "โดยค่าเริ่มต้น" เมื่อเพิ่ม Swift code ในโครงการ ObjC ที่มีอยู่
David Kristensen

5
@ โปปอายฉันไม่เห็นด้วย ในกรณีนี้หากคุณแก้ไขไฟล์และรวบรวมจากบรรทัดคำสั่งคุณจะไม่เห็นปัญหานี้ เป็น IDE ที่ทำงาน (หรือควรจะทำ) ในนามของคุณซึ่งเป็นปัญหา นี่น่าจะเกี่ยวข้องกับการตั้งค่าโครงการซึ่งแน่นอนว่าเป็นฟังก์ชั่น IDE
gaige

11
@Popeye จากเอกสาร (PDF) : เมื่อคุณนำเข้ารหัส Swift ใน Objective-C คุณต้องใช้ไฟล์ส่วนหัวที่สร้างจาก Xcodeเพื่อแสดงไฟล์เหล่านั้นไปยัง Objective-C (ตัวหนาของฉันตัวเอียงของ Apple) นี่เป็นคำถามที่ชัดเจนเกี่ยวกับคุณสมบัติของ Xcode ที่ช่วยให้คุณใช้ Swift และ Objective-C ร่วมกันและแท็กทั้งสามนั้นเหมาะสมอย่างแน่นอน
Caleb

3
ฉันแก้ไขมันด้วยความช่วยเหลือของ gaige และเอกสารประกอบ และฉันไม่เพียงแค่โยนแท็กไปรอบ ๆ : ในกรณีนี้ไฟล์ส่วนหัวควรถูกสร้างขึ้นโดย XCode และมองเห็นได้ มันไม่ได้ทำให้เกิดข้อผิดพลาด
David Kristensen

3
@Popeye ไม่มีอะไรผิดพลาด - ฉันคัดลอกคำพูดโดยตรงจากหน้า 46 คุณได้พบข้อความที่คล้ายกัน แต่แตกต่างกันซึ่งระบุว่าเหมือนกันมากหรือน้อย
Caleb

คำตอบ:


165

ตอนนี้มันใช้งานได้

  1. โครงการจะต้องมีสินค้าชื่อโมดูลที่ไม่ได้มีช่องว่าง
  2. กำหนดโมดูลจะต้องตั้งค่าเป็นใช่ในการตั้งค่าการสร้างภายใต้บรรจุภัณฑ์

ในที่สุดก็ใช้งานได้ ขอบคุณทุกคนสำหรับความช่วยเหลือ :-)


64
ในBuild Settingsภายใต้PackagingของฉันDefines Moduleมีการตั้งค่าYesและฉันสร้างProduct Module Nameโดยไม่มีช่องว่าง "* -Swift.h" ไม่ได้ถูกสร้างขึ้นโดย XCode 6 ???
Loozie

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

22
ฉันยังมีปัญหาเดียวกัน ฉันได้Defines Moduleตั้งค่าYesสำหรับทั้งโครงการและเป้าหมายและที่Product Module Nameกำหนดโดยไม่มีช่องว่างแต่ฉันไม่สามารถสร้างไฟล์นี้ได้
Craig Otis

8
ในกรณีที่คนอื่นสับสนเหมือนฉัน ... ฉันต้องมีโชคตาบอดที่นี่และเพียงนำเข้าส่วนหัวเนื่องจากมันจะไม่เติมข้อความอัตโนมัติ
shawnwall

14
คุณไม่สามารถนำเข้า -swift บนไฟล์ส่วนหัว (.h) ในการนำไปใช้
zirinisp

122

ฉันมีปัญหาที่คล้ายกันและพบว่าคุณสามารถเพิ่มได้เท่านั้น

#import "ProductModuleName-Swift.h"

เพื่อ obj-c .m ไม่ใช่ไฟล์. h สำหรับส่วนหัวของร่มที่จะพบ


2
สิ่งนี้ถูกต้องและ ... ถ้าฉันจำเป็นต้องใช้คลาส Swift ในส่วนหัวของ objc ฉันพยายามประกาศไปข้างหน้า แต่ก็ไม่ได้ผล
Ixx

2
ทำงานขอโทษประกาศไปข้างหน้า ฉันลืมเพิ่มเซมิโคลอน: P
Ixx

14
สำหรับผู้ค้นหาในอนาคต: ในส่วนหัวของคุณทำการประกาศไปข้างหน้าโดยทำ @class YourSwiftClass ที่ด้านบนของไฟล์. h (แทนที่จะนำเข้าส่วนหัวของร่ม)
rogueleaderr

4
ถ้าฉันจำเป็นต้องใช้ Swift enum ในไฟล์ส่วนหัว
jakecraige

1
นอกจากนี้หาก "#import ProductModuleName-Swift.h" อยู่ในไฟล์ส่วนหัวใด ๆ ไฟล์ ProductModuleName-Swift.h จะไม่ถูกสร้างเลย (เช่น Xcode 7.2) ดังนั้นหากถูกลบ (เช่นโดยการทำความสะอาดบิลด์ โฟลเดอร์) จากนั้นคุณจะเห็นข้อความแสดงข้อผิดพลาดทุกที่ที่นำเข้าไฟล์แม้กระทั่งไฟล์. m เพื่อเพิ่มความสับสน
rene

59

ฉันพบว่าฉันต้องแก้ไขข้อผิดพลาดบิลด์ทั้งหมดก่อนที่จะสร้างไฟล์

ปัญหาสำหรับฉันก็คือว่ามันเป็นปัญหาไก่ / ไข่ในที่ฉันไม่เห็นข้อผิดพลาดการสร้างใด ๆ จนกว่าฉันจะแสดงความคิดเห็นออก#importแถลงการณ์จริง:

//#import "ProductModuleName-Swift.h"

ซึ่งพบข้อผิดพลาดอื่น ๆ ในรหัส Swift ของฉัน

เมื่อฉันแก้ไขข้อผิดพลาดใหม่เหล่านี้และได้รับการสร้างแหล่งที่มาเรียบร้อยแล้วฉันก็ยกเลิกคำวิจารณ์#importและบิงโก! หัวข้อถูกสร้างขึ้นและนำเข้าอย่างถูกต้อง :)


ขอบคุณนี่คือสิ่งที่ทำให้ฉัน หลังจากแก้ไขข้อผิดพลาดในการสร้างรวดเร็วฉันก็ไปได้ดี (เวอร์ชั่น Xcode 6.1.1)
Rick Roberts

10
นี่เป็นจุดที่ดีและเป็นเหตุผลที่ดีในการเปิดใช้งานการตั้งค่า "สร้างต่อเนื่องจากข้อผิดพลาด" ใน Xcode
Kendall Helmstetter Gelner

นั่นคือกรณีของฉันเช่นกัน: การขาดหายไป -Swift-h เกิดขึ้นหลังจากการเปลี่ยนแปลงในซอร์สโค้ดที่รวดเร็ว
Giorgio Calzolato

3
หลังจากเห็น ปัญหาไก่ / ไข่ฉันตระหนักถึงปัญหาของฉันการเปรียบเทียบที่ดี
d0ye

ปัญหานี้กลับมาหาฉันเสมอ (Xcode10) และฉันเพิ่งตีความ Xcode ว่าเป็นบั๊กกี้ นี่คือคำตอบว่า
SumakuTension

44

หากคุณเป็นเหมือนฉันคุณอาจมีชื่อส่วนหัวผิด หลังจากทุบตีหัวของฉันในขณะที่ฉันค้นหาไฟล์ใน DerivedData และแน่ใจว่ามันอยู่ที่นั่น ในการตั้งค่าของฉัน (โดยใช้โฟลเดอร์ข้อมูลที่ได้รับมาตรฐานฉันเชื่อว่า):

cd ~/Library/Developer/Xcode/DerivedData
find * -iname '*Swift.h'

จะพบว่า หากไม่มีสิ่งใดในโฟลเดอร์นั้นที่ตรงกัน Xcode จะไม่สร้างมันขึ้นมา

ฉันใช้ Xcode เวอร์ชั่น 6.2 (6C86e)


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

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

ขอบคุณ! ช่วยฉันได้มากเวลา
estemendoza

43

หากชื่อโมดูลโครงการของคุณมีช่องว่างคุณต้องแทนที่ช่องว่างด้วยเครื่องหมายขีดล่าง

ตัวอย่างเช่นหากชื่อโครงการของคุณคือ "My Project" คุณจะใช้:

#import "My_Project-Swift.h"


12
หากชื่อโมดูลโครงการของคุณมียัติภังค์อยู่ในนั้นก็ควรจะถูกแทนที่ด้วยขีด ดังนั้นหากชื่อโครงการของคุณคือ "My-Project" ให้ใช้ #import "My_Project.h"
Jeff Ames

6
นอกจากนี้หากชื่อโมดูลโครงการของคุณเริ่มต้นด้วยตัวเลขก็ควรจะถูกแทนที่ด้วยขีดล่าง "โครงการที่ 1" จะเป็น "_st_Project-Swift.h"
Danation

31

* สิ่งสำคัญเพียงอย่างเดียวคือ: *

เพื่อใช้ "ชื่อโมดูลผลิตภัณฑ์" ที่กำหนดไว้ในเป้าหมายตามด้วย -Swift.h

#import <Product Module Name>-Swift.h

// in each ObjectiveC .m file having to use swift classes
// no matter in which swift files these classes sit.

ไม่ว่าจะตั้งพารามิเตอร์ "กำหนดโมดูล" เป็นใช่หรือไม่หรือหากไม่ได้ตั้งค่าโครงการ "ชื่อโมดูลผลิตภัณฑ์"

เตือนความจำ: คลาส Swift ต้องมาจาก NSObject หรือถูกแท็กด้วยแอ็ตทริบิวต์ @objc เพื่อแสดงผลกับ ObjectiveC / Foundation || โกโก้ ...


1
เป็นเรื่องจริง: ไม่จำเป็นต้องมี "กำหนดโมดูล" ในโครงการหรือในเป้าหมาย
Giorgio Calzolato

25

ฉันต้องการเพิ่มอีกหนึ่งเหตุผลที่คุณอาจพบปัญหาเกี่ยวกับสิ่งนี้ - ฉันกำลังสร้างเฟรมเวิร์กที่ผสมรหัส Swift และ Objective-C ฉันไม่สามารถนำเข้าคลาส Swift นอกกรอบได้ - ฉันตรวจสอบไฟล์ -Swift.h และกำลังถูกสร้าง แต่ว่างเปล่า

ปัญหากลายเป็นเรื่องง่ายมาก - ฉันไม่ได้ประกาศให้ชั้นเรียน Swift ของฉันเป็นสาธารณะ! ทันทีที่ฉันเพิ่มคำสำคัญสาธารณะในชั้นเรียนฉันสามารถใช้พวกเขาจากชั้นเรียนภายในและนอกกรอบ

นอกจากนี้ยังมีข้อความที่อยู่ในกรอบงาน (ในไฟล์. m ภายในเป็นคำตอบอื่นเท่านั้น) ฉันต้องนำเข้าไฟล์ -Swift.h เป็น:

#import <FrameworkName/FrameworkName-Swift.h>

2
ใน Framework ฉันยังทราบว่าเพื่อใช้คลาส Swift พวกเขาควรสืบทอดจาก NSObject (แม้ @objc จะไม่ช่วย) และวิธีการ / คุณสมบัติทั้งหมดควรเป็นแบบสาธารณะ
dmitrynikolaev

3
อย่างน้อยในรุ่นก่อนหน้า XCode 7 ปัจจุบันจนกว่าคุณจะสืบทอดจาก NSObject พวกเขาจะไม่สามารถใช้ได้ในส่วนหัวของ swift ที่สร้างขึ้น
dmitrynikolaev

100% ไม่ได้แก้ไขปัญหาของฉัน ทางออกทุกอย่างคือ "ทำให้คลาสของคุณเป็นแบบสาธารณะ" ฉันทำอย่างนี้. ระยะเวลา มันยังไม่เปิดเผยคลาส Swift ในโครงการที่ใช้เฟรมเวิร์ก
datWooWoo

@lespommes คุณควรเขียนคำถามและวางตัวอย่างโครงการที่มีปัญหาใครบางคนสามารถคิดได้ว่าเกิดอะไรขึ้น ... ฉันแค่ให้คำตอบว่าเป็นวิธีแก้ปัญหาที่เป็นไปได้เพราะมันเป็นความผิดพลาดในการมองเห็นที่ฉันทำมากที่สุด บ่อยๆ
Kendall Helmstetter Gelner

2
โอ้ใช่แล้วคำใบ้ของคุณที่มีกับการนำเข้าก็ทำเพื่อฉันแล้ว! ขอบคุณมาก!
endowzoner

14

ผมมีปัญหาเหมือนกัน. ดูเหมือนว่าคุณจะต้องปรับการตั้งค่า (กำหนดโมดูลและชื่อโมดูลผลิตภัณฑ์) ก่อนที่คุณจะเพิ่มไฟล์ Swift ไฟล์แรกของคุณ

หากคุณทำภายหลังไฟล์ "* -Swift.h" จะไม่ถูกสร้างขึ้นสำหรับโครงการนี้แม้ว่าคุณจะเพิ่มไฟล์ Swift เพิ่มเติมหรือลบไฟล์ Swift และสร้างไฟล์ใหม่


ฉันไม่แน่ใจว่าเป็นเรื่องจริง ฉันไม่ได้ตัดสินใจเปิดใช้ 'กำหนดโมดูล' จนกระทั่งดีหลังจากสร้างไฟล์ที่รวดเร็วและฉันสามารถรับ -Swift.h ได้
Michael Peterson

จริง ๆ แล้วฉันเสียใจที่ได้รายงานว่านี่เป็นปัญหาที่ฉันมี :( ฉันต้องลบ. swift และเพิ่มใหม่อีกครั้งจากนั้นก็ใช้งานได้
StuFF mc

2
ตอนนี้คืออะไร ฉันกำลังเปลี่ยนรหัสทั้ง Swift และ ObjC My Project-Swift.h ไม่ได้ทำการอัพเดต ฉันพยายามลบไฟล์ส่วนหัวด้วย
Suhail Bhat

2
ฉันได้เขียนหนึ่งขึ้นนี้dev.iachieved.it/iachievedit/?p=980 เคล็ดลับในการอัปเดตการตั้งค่าการสร้างก่อนที่จะเพิ่มไฟล์ Swift เป็นกุญแจสำคัญสำหรับฉัน
โจ

นี่หมายความว่าฉันต้องสร้างโครงการขึ้นใหม่และเพิ่มทุกอย่างอีกครั้งถ้าฉันไม่ทำเช่นนี้? ไม่ว่าฉันจะทำอะไรฉันก็ไม่สามารถสร้างไฟล์ * -Swift.h ได้
kgreenek

13

อนุญาตให้ฉันแบ่งปันประสบการณ์ของฉันที่พยายามใช้ Swift ในโครงการ objc แบบเก่า ฉันไม่ได้มีการตั้งค่าที่จะDefines moduleYES

ในกรณีของฉันฉันต้องตรวจสอบให้แน่ใจด้วยตนเองว่ามี Bridging Header objc เฉพาะชื่อส่วนหัวของอินเตอร์เฟสที่สร้างขึ้นเท่านั้นที่มีอยู่ในการตั้งค่าการสร้างของฉัน

ไม่มีส่วนหัวการเชื่อมโยง

สิ่งนี้นำไปสู่ไฟล์ MyApp-Swift.h เพื่อสร้าง แต่ไม่มีร่องรอยของคลาส Swift ของฉัน

เอกสารประกอบของ Apple บอกว่าคุณจะได้รับแจ้งให้สร้างส่วนหัวการเชื่อมโยงเมื่อเพิ่มไฟล์ swift ไฟล์แรกของคุณ ฉันไม่ ฉันเพิ่มMyApp-Bridging-header.hไฟล์ด้วยตนเองและชี้ไปที่มันในฟิลด์ "Objective-C Bridging Header" นั่นทำให้ไฟล์ MyApp-Swift.h ของฉันกลายเป็นไฟล์ที่มีคลาส Swift ของฉัน

เอกสาร: การนำเข้า Swift เข้าสู่ Objective-C


ใช่ไม่ว่าด้วยเหตุผลใดก็ตามไฟล์ ObjC Swift.h ของฉันถูกสร้างขึ้นด้วยส่วนหัวของคลาส Swift หลังจากที่ฉันเพิ่มไฟล์ส่วนหัวบริดจ์เปล่าลงในโปรเจ็กต์แล้ว!
แอนดรู

กันที่นี่ รหัส Swift ของฉันไม่ได้ถูกนำเข้าไปยังไฟล์ * -Swift.h ที่สร้างจนกว่าฉันจะเพิ่มไฟล์ส่วนหัว Bridging Objective-C ที่ว่างเปล่า
Nik

12

นี่คือรูปแบบอื่นของ moduleName-Swift.h ที่ไม่ได้ถูกสร้างขึ้น

ฉันตัดสินใจที่จะรวมIOS Chartsในโครงการของฉัน แต่ไม่ต้องการรวมแหล่งที่มาในไดเรกทอรีเดียวกันดังนั้นฉันจึงวางโฟลเดอร์ Charts Project ถัดจากโฟลเดอร์โครงการของรหัสของฉัน ผมลากแผนภูมิโครงการเข้าไปในโครงการนาวิเกเตอร์บาร์ของฉันและรวมอยู่ในกรอบเป้าหมายโครงการของฉันของไบนารีฝังตัวรายการในการตั้งค่าโครงการทั่วไปและการตั้งค่าเนื้อหาที่ฝังประกอบด้วยรหัส Swiftสลับไปใช่ในโครงการของฉันของรูปร่างการตั้งค่าแท็บในตัวเลือกรูปร่างส่วน

ไฟล์ moduleName-Swift.h ของโครงการของฉันจะไม่มีวันสร้างไม่ว่าสวิตช์หรือการตั้งค่าอื่น ๆ จะแนะนำที่นี่ ในที่สุดเมื่อใช้วิธีการของ Lou Z ในการค้นหาไฟล์ -Swift.h ฉันเห็นว่าไฟล์ Charts-Swift.h ถูกสร้างขึ้นในไดเรกทอรีสร้างรหัส xcode ของโครงการใน Charts.framework / ส่วนหัว /

วิธีแก้ปัญหาในการใช้แพคเกจ ios-charts Swift ของ Daniel Gindi โดยไม่รวมรหัสในไดเรกทอรีต้นทางของโครงการของฉันคือการเพิ่ม:

#import "Charts/Charts-Swift.h"

ไปยังโมดูลที่สร้างแผนภูมิข้อมูลโครงการของฉัน


เป็นไปได้หรือไม่ที่จะเปลี่ยน / ปรับแต่งเคล็ดลับเครื่องมือในชาร์ต IOS ถ้าใช่คุณสามารถยกตัวอย่างได้หรือไม่?
Amit Chauhan

12

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

วิธีหนึ่งในการจัดการกับสิ่งนี้คือ

  1. เพิ่มตัวประมวลผลล่วงหน้าสำหรับเป้าหมายแต่ละตัวของคุณซึ่งเป็นชื่อของเป้าหมายของคุณเอง (ไม่มีช่องว่าง) อดีต MY_TARGET=1. เพิ่มสิ่งนี้ใน Project settings-> Build Settings-> Mac Preprocessor สำหรับแต่ละเป้าหมายของคุณ
  2. หากคุณใช้ไฟล์ PCH

เพิ่มบรรทัดเหล่านี้ในไฟล์ PCH

#if MY_TARGET==1
#include "My_Target-Swift.h"
#elif THAT_TARGET==1
#include "That_Target-Swift.h" 
#endif

ข้อดีของการใช้ไฟล์ PCH คือคุณไม่จำเป็นต้องรวมส่วนหัวไว้ทุกที่

  1. หากคุณไม่ได้ใช้ไฟล์ PCH เพียงเพิ่มบรรทัดเดียวกันนี้ในส่วนหัวเดียวและรวมส่วนหัวนั้นทุกที่ที่คุณต้องการใช้คลาส swift

มันน่าจะใช้ได้ดี


ฉันชอบใช้โซลูชันนี้มากกว่าการนำเข้าส่วนหัวไปยังแหล่งที่มาของคุณโดยตรง ฉันมีโครงสร้างโครงการที่ซับซ้อนซึ่งมีการใช้ซอร์สโค้ดเดียวกันโดยหลายเป้าหมาย / โครงการ วิธีนี้หลีกเลี่ยงการเพิ่มคำชี้แจง #if #else ยุ่ง ๆ ทั่วโค้ดของฉัน ขอบคุณสำหรับคำตอบ!
Ryan

สิ่งนี้ช่วยชีวิตฉันไว้ ฉันใส่โค้ด 5 บรรทัดลงในไฟล์ "Something-Swift-Headers.h" ( includeในนั้น) จากนั้นฉันก็นำเข้าไฟล์ใหม่นี้จากที่ที่ฉันต้องการ ฉันชอบที่จะไม่วางสิ่งนี้ไว้ใน PCH หรือไฟล์. h ใด ๆ เพื่อหลีกเลี่ยงการพึ่งพาแบบวนซ้ำและใช้ส่วนหัวอำนวยความสะดวกในไฟล์. m
ctietze

นี่เป็นสิ่งที่ผิดในหลาย ๆ ระดับ ประการแรกไฟล์มีกำลังใจอย่างมาก.pch ประการที่สองชื่อไฟล์มีชื่อผลิตภัณฑ์และไม่ใช่ชื่อเป้าหมายเลย อาจเป็นเรื่องบังเอิญที่เหมือนกัน แต่ใช้ชื่อผลิตภัณฑ์!
Iulian Onofrei

10

หาก Xcode กำลังสร้างส่วนหัว -Swift.h ของคุณ (ส่วนลึกภายใน DerivedData) แต่มันไม่ได้อ้างถึงคลาส Swift ของคุณตรวจสอบให้แน่ใจว่าคุณได้กำหนดส่วนหัวบริดจ์แล้ว วิธีที่ฉันอ่านเอกสารที่บอกเป็นนัยว่าฉันเพียงต้องการให้เรียก Objective-C จาก Swift แต่ดูเหมือนว่าจำเป็นสำหรับการเรียก Swift จาก Objective-C ด้วย

ดูคำตอบของฉัน: https://stackoverflow.com/a/27972946/337392

แก้ไข: มันเป็นเพราะตัวดัดแปลงการเข้าถึงสาธารณะเทียบกับการเข้าถึงภายในอย่างที่ฉันได้พบในที่สุดก็อธิบายไว้ในเอกสารของ Apple: -

โดยค่าเริ่มต้นส่วนหัวที่สร้างขึ้นมีอินเทอร์เฟซสำหรับการประกาศ Swift ที่ทำเครื่องหมายด้วยตัวดัดแปลงสาธารณะ นอกจากนี้ยังมีสิ่งที่ทำเครื่องหมายด้วยตัวแก้ไขภายในหากเป้าหมายแอปของคุณมีส่วนหัวการเชื่อมโยง Objective-C


ใช่มันช่วยได้จริงๆ ฉันไม่รู้ ฉันคิดว่ามันเป็นสิ่งจำเป็นสำหรับ Obj-C จากกรณีใช้งาน Swift
พยักหน้า

ยินดีที่ได้ช่วย. ฉันแก้ไขคำตอบเพราะฉันพบว่าสาเหตุของพฤติกรรมนี้
Echelon

7

สิ่งที่สองที่มีผู้คนจำนวนมากอยู่ที่นี่ แต่เพิ่มภาพหน้าจอที่เกี่ยวข้อง รหัส Swift และ Obj-C สามารถอยู่ด้วยกันได้อย่างแน่นอน มันไม่ใช่เกมทั้งหมดหรือไม่มีเลย

ในการเข้าถึงไฟล์ Swift ใน Objective-C ของคุณสิ่งที่คุณต้องทำคือเพิ่มการเรียกไปยังไฟล์ Obj-C ของคุณ (ในไฟล์. m / Implementation):

#import "{product_module_name}-Swift.h"

(โดยที่ {product_module_name} แทนชื่อโมดูลผลิตภัณฑ์ของโครงการของคุณ) แทนที่จะลองเดาชื่อโมดูลผลิตภัณฑ์ของคุณหรือค้นหาตัวพิมพ์มุมที่มีช่องว่างและอักขระพิเศษเพียงไปที่แท็บการตั้งค่าการสร้างในโครงการและพิมพ์ใน "ชื่อโมดูลผลิตภัณฑ์" - ผู้ตรวจสอบจะแสดงให้คุณเห็น ฉันเป็นสิ่งที่ฉันไม่คาดหวังว่าจะเป็น ลองดูภาพหน้าจอนี้ถ้าคุณสับสน

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

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


1
มันไม่ควรจะเป็น#import?
Iulian Onofrei

สมมติว่าชื่อโครงการของฉันคือ ABC จากนั้น "ABC-Swift.h" ต้องมีอยู่ในโครงการของฉันใช่ไหม ฉันหามันไม่เจอ ต้องสร้างด้วยตนเองหรือไม่ ฉันไม่ได้สร้างไฟล์สวิฟท์ใด ๆ ด้วยตัวเองเพียงแค่ใส่ฝักโกโก้ที่เขียนด้วยความรวดเร็ว
nr5

Bridging Header (ในกรณีของคุณ ABC-Swift.h) จะไม่สร้างขึ้นโดยอัตโนมัติ เมื่อคุณพยายามสร้างไฟล์ Swift ไฟล์แรกในโครงการ Obj-C โดยปกติ Xcode จะให้คุณเพิ่มไฟล์ นอกจากนี้คุณยังสามารถสร้าง Bridging header ด้วยตัวคุณเองตามที่แสดงไว้ที่นี่ (control + f สำหรับ 'bridging header'): developer.apple.com/library/content/documentation/Swift/…
Brian Sachetta

5

สิ่งที่สำคัญที่สุดคือไฟล์นี้จะมองไม่เห็น !!! อย่างน้อยก็อยู่ใน Xcode6 beta5 จะไม่มีไฟล์ดังกล่าวชื่อ "YourModule-Swift.h" ในพื้นที่ทำงานของคุณ เพียงให้แน่ใจว่าคุณมีชื่อโมดูลและกำหนดชุดโมดูลเป็นใช่และใช้ในคลาส Objective-C ของคุณ


5

ตกลงนี่คือทุกสิ่งที่คุณต้องการจริงๆ!

1. ลบไฟล์ swift ทั้งหมดที่คุณเพิ่มและคอมไพล์โค้ดโดยไม่มีข้อผิดพลาด

----------

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

----------

2. ไปที่การตั้งค่าการสร้าง "โครงการ" และตั้งชื่อโมดูลผลิตภัณฑ์ โครงการต้องมีชื่อโมดูลผลิตภัณฑ์ที่ไม่มีช่องว่าง

----------

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

----------

3. กำหนดโมดูลจะต้องตั้งค่าเป็นใช่ในการตั้งค่าการสร้างภายใต้บรรจุภัณฑ์ในโครงการของคุณและไม่ได้กำหนดเป้าหมาย!

----------

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

----------

4. ตอนนี้สร้างไฟล์ swift หรือตัวควบคุมมุมมองในไฟล์ -> newFile->

----------

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

----------

มันจะขอให้สร้าง bridging-header อนุญาตให้ทำ หากคุณปฏิเสธหนึ่งครั้งคุณจะต้องเพิ่ม -Bridging-Header.h ด้วยตนเอง

5. เพิ่ม @objc ในคอนโทรลเลอร์เพื่อบอกคอมไพเลอร์ว่ามีไฟล์ swift บางไฟล์ซึ่งจำเป็นต้องเปิดเผยกับ ObjectiveC

----------

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

----------

6. สร้างโปรเจ็กต์และอิมปอร์ต #import "-Swift.h" ในส่วนใด ๆ ของ controllerC และมันจะทำงาน! คุณสามารถคลิกคำสั่งเพื่อดูไฟล์จริง!

----------

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

----------

หวังว่านี่จะช่วยได้!


>> คุณสามารถคลิกคำสั่งเพื่อดูไฟล์จริง! นี่มันเจ๋ง
Jagan

4

คำตอบนี้กล่าวถึงกรณีการใช้งานที่คุณอาจมีรหัส Objective-C อยู่แล้วซึ่งเรียกคลาส Swift จากนั้นคุณเริ่มได้รับข้อผิดพลาดนี้

วิธีแก้ไขปัญหา

ขั้นตอนต่อไปนี้จะแก้ไขปัญหาทั้งหมดในที่สุด ฉันอ่านข้างบนมีคนพูดถึง "ไก่และไข่" และมันเป็นแนวคิดที่นำฉันไปสู่กระบวนการนี้ กระบวนการที่ชัดเจนนี้แสดงให้เห็นว่าต้องลบรหัส Objective-C ใด ๆ ที่อ้างอิงคลาส Swift จนกว่าจะมีการสร้างส่วนหัว

  1. ใส่เครื่องหมายคอมเมนต์ #import "ProductModuleName-Swift.h" ในไฟล์การติดตั้ง Objective-C ของคุณ
  2. ความคิดเห็นเกี่ยวกับการอ้างอิงใด ๆ ในไฟล์การใช้งาน Objective-C ไปที่ Swift Classes
  3. ทำความสะอาด & ​​สร้าง
  4. แก้ไขข้อผิดพลาด / คำเตือนทั้งหมด
  5. ลบความคิดเห็นในคำสั่ง #import "ProductModuleName-Swift.h"
  6. ล้างและสร้าง (สำเร็จหรือแก้ไขข้อผิดพลาดใด ๆ ที่เหลืออยู่ตรวจสอบว่าคุณไม่ได้อ้างอิงคลาส Swift ใด ๆ ใน Objective-C ณ จุดนี้นี้ถ้าเป็นเช่นนั้นให้ชั่วคราวแสดงความคิดเห็นเหล่านี้ออก)
  7. ตรวจสอบว่า "ProductModuleName-Swift.h" ถูกสร้างโดยการคลิก Cmd ที่ชื่อคลาสของคำสั่ง #import "ProductModuleName-Swift.h"
  8. ลบความคิดเห็นเกี่ยวกับรหัสอ้างอิงคลาส Swift ในไฟล์การใช้งาน Objective-C
  9. ล้างข้อมูลและสร้างตามปกติ (ควรสร้าง "ProductModuleName-Swift.h" และรหัส Objective-C ของคุณที่อ้างอิงคลาส Swift สามารถใช้งานได้ตามปกติ)

Nota Bene:คำตอบเกี่ยวกับการเปลี่ยนช่องว่างเป็นขีดล่างและกำหนดโมดูลเป็น YES ตามที่กำหนดข้างต้นยังคงใช้เมื่อดำเนินการตามกระบวนการนี้เช่นเดียวกับกฎที่ระบุในเอกสาร Appleเอกสารแอปเปิ้ล

Bridging Header Path

ในข้อผิดพลาดเดียวไฟล์ ProductModuleName-Bridging-Header.h ไม่พบในระหว่างกระบวนการสร้าง ข้อเท็จจริงนี้สร้างข้อผิดพลาด

<ไม่ทราบ>: 0: ข้อผิดพลาด: การเชื่อมต่อส่วนหัว '/Users/Shared/Working/abc/abc-Bridging-Header.h'

การตรวจสอบข้อผิดพลาดอย่างใกล้ชิดบ่งชี้ว่าไฟล์จะไม่มีอยู่ในตำแหน่งที่อธิบายไว้เนื่องจากเป็นตำแหน่งที่ถูกต้อง (เส้นทางที่ไม่ถูกต้อง )

'/Users/Shared/Working/abc/abc/abc-Bridging-Header.h' การค้นหาอย่างรวดเร็วของเป้าหมาย / โครงการสร้างการตั้งค่าเพื่อทำการแก้ไขด้วยตนเองและไฟล์ abc-Swift.h ถูกสร้างขึ้นโดยอัตโนมัติอีกครั้ง

สร้างการตั้งค่า


1
เกิดอะไรขึ้นถ้าโครงการของคุณมีขนาดใหญ่มากที่แสดงความคิดเห็นการอ้างอิงทั้งหมดของรหัส swift ในวัตถุประสงค์ c จะทำไม่ได้?
Andrew Morris

3

คุณต้องนำเข้าส่วนหัวในคลาส Objective-C ซึ่งก็คือ:

#import “ProductModuleName-Swift.h”

มันถูกสร้างขึ้นโดยอัตโนมัติโดยอ้างอิงว่า "ไฟล์ Swift ใด ๆ ในเป้าหมายของคุณจะปรากฏในไฟล์ Objective-C .m ที่มีคำสั่งนำเข้านี้"


24
แต่เมื่อฉันทำเช่นนั้นฉันได้รับข้อผิดพลาดของบิลด์ AppName-Swift.h ไม่มีอยู่ ในขณะที่ AppName-Bridging-Header.h
David Kristensen

5
@DavidKristensen: คุณไม่ได้รับการแก้ปัญหาของมัน ?, ที่ผมได้ติดอยู่กับปัญหาเดียวกัน
Basha

2

ไฟล์จริงในโครงการไม่ได้ถูกสร้างขึ้น ([ProductModuleName] -Swift.h) Cmd + คลิกที่การนำเข้าสร้างแบบทันที (และในหน่วยความจำ) เพื่อให้คุณสามารถดูว่าการเชื่อมโยงเสร็จสิ้นหรือเปิดไฟล์ที่ไหนสักแห่งใน Xcode cache dir บางส่วน แต่ไม่ได้อยู่ในโปรเจ็กต์ dir

คุณต้องตั้งค่ากำหนด prop project project (ใน Build Settings ของเป้าหมาย) เป็นYesและถ้าชื่อโมดูลของคุณมีช่องว่างหรือขีดคั่นให้ใช้ _ ในการนำเข้าทั้งหมดของไฟล์ [ProductModuleName] -Swift.h

คุณสามารถนำเข้ามันในไฟล์. h และ. m ทั้งหมดที่คุณใช้ประเภท swift หรือคุณสามารถนำเข้าใน. pch

ดังนั้นหากโมดูล (โครงการ) ของฉันชื่อ "ทดสอบโครงการ" ฉันจะนำเข้าแบบนี้ในไฟล์. pch ของโครงการของฉัน (ตรงนั้น):

#import "Test_Project-Swift.h"

2

เพียงหัวขึ้นสำหรับทุกคนที่ใช้ "." ในชื่อโครงการ Xcode จะแทนที่ "." ด้วยเครื่องหมายขีดเส้นใต้ "_" สำหรับเวอร์ชัน Swift ของไฟล์ส่วนหัวการเชื่อมต่อ Bridging-Header.h ที่สร้างขึ้นไม่เพียงพอแทนที่จุดด้วยขีดล่าง

ตัวอย่างเช่นโครงการที่มีชื่อ My.Project จะมีชื่อไฟล์ Bridging Header ดังต่อไปนี้

Bridging-Header.h (สร้างอัตโนมัติ)

My.Project-Bridging-Header.h

Swift.h

My_Project.h

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

Macintosh HD / ผู้ใช้ / ผู้ใช้ / ห้องสมุด/ ผู้พัฒนา /Xcode/DerivedData/My.Project-fntdulwpbhbbzdbyrkhanemcrfil/Build/Intermediates/My.Project.build/Debug-iphonesimulator/My.Project.build

ดูแล,

จอน


2

โครงการจะต้องมีชื่อโมดูลไม่รวมถึงช่องว่าง กำหนดโมดูลจะต้องตั้งค่าเป็นใช่ในการตั้งค่าการสร้างภายใต้บรรจุภัณฑ์ แสดงความคิดเห็นในคำสั่ง #import:

หากคุณยังคงมีข้อผิดพลาดในการนำเข้า "ProductModuleName-Swift.h"

// # import "ProductModuleName-Swift.h"

ซึ่งพบข้อผิดพลาดอื่น ๆ ในรหัส Swift ของฉัน

เมื่อฉันแก้ไขข้อผิดพลาดใหม่เหล่านี้และได้รับการสร้างแหล่งที่มาเรียบร้อยแล้วฉันไม่ใส่เครื่องหมายข้อคิดเห็น #import และ bingo! หัวข้อถูกสร้างขึ้นและนำเข้าอย่างถูกต้อง :)


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

1

ฉันพบเคล็ดลับที่ใช้ได้กับฉันเสมอ

  1. สร้าง #import "ProductModuleName-Swift.h" ของคุณในไฟล์ appDelegate.h และในไฟล์ ProductName-Prefix.pch ของคุณ หากคุณไม่ได้ใช้มันใน xcode 6 คุณสามารถสร้างมันด้วยวิธีนี้ทำไม ProjectName-Prefix.pch จึงไม่สร้างโดยอัตโนมัติใน Xcode 6
  2. Command + shift + k เพื่อล้างรหัสของคุณหากคุณได้รับข้อผิดพลาดเกี่ยวกับ "ProductModuleName-Swift.h" ของคุณให้ลบออกจากไฟล์ appDelegate.h
  3. ทำความสะอาดรหัสของคุณอีกครั้ง ตอนนี้ทุกอย่างจะทำงานเหมือนมีเสน่ห์
  4. หากคุณได้รับข้อผิดพลาดอีกครั้งเกี่ยวกับ "ProductModuleName-Swift.h" ให้สร้างอีกครั้งในไฟล์ appDelegate.h และล้างรหัสของคุณอีกครั้ง

ทำงานนี้ (ลบและสร้าง "ProductModuleName-Swift.h" จากไฟล์ appDelegate.h และล้างรหัสของคุณ) ทุกครั้งที่คุณได้รับข้อผิดพลาดนี้เพื่อปิดเสียง


1

ฉันพบโซลูชันนี้แล้ว

  • สร้าง SwiftBridge.h
  • ใส่ #import“ ProductModuleName-Swift.h”
  • กำหนดให้เป็นไฟล์. h สาธารณะ (สำคัญ) เลือกไฟล์ -> ในแสดงไฟล์ตัวตรวจสอบ (แถบด้านขวา) -> ทำให้เป็นสาธารณะ

ตอนนี้คุณสามารถ

#import "SwiftBridge.h"

แทน ProductModuleName-Swift.h

นี่เป็นวิธีแก้ปัญหาสำหรับ Xcode รุ่นถัดไปฉันคิดว่าปัญหานี้จะได้รับการแก้ไข โชคดี


ใช้งานไม่ได้ แค่ลองดู บรรทัด#import “ProductModuleName-Swift.h”เพิ่งเกิดข้อผิดพลาดในไฟล์ SwiftBridge.h แทนไฟล์โค้ด Objective-C ดั้งเดิม
Supertecnoboff

1

ฉันมีช่วงเวลาที่ยากลำบากในการกำหนดชื่อโมดูล / วัตถุประสงค์ของการนำเข้าส่วนหัวสวิฟท์ ฉันอ่านบทความมากมายที่นี่ด้วย

แต่คำตอบที่ชัดเจนสำหรับชื่อโครงการของคุณพร้อมด้วยอักขระพิเศษทั้งหมด (ไม่ว่าจะเป็น '.' หรือตัวเลขหรือช่องว่าง) - คุณสามารถค้นหาข้อความที่เหมาะกับคุณใน " ชื่อโมดูลผลิตภัณฑ์ " ภายใต้การตั้งค่า Build ของเป้าหมาย .

เช่นชื่อเป้าหมายของฉันเริ่มต้นด้วยตัวเลข - "1 มก." และฟิลด์ที่กล่าวถึงข้างต้นแสดง "_mg" เป็นชื่อโมดูลของฉัน

ดังนั้นฉันจึงใช้ #import "_mg-Swift.h" และใช้งานได้

ชื่อโมดูลผลิตภัณฑ์ในการตั้งค่าการสร้างของเป้าหมายให้ชื่อโมดูลที่ถูกต้องซึ่งจะทำงานสำหรับโครงการของคุณ


หากคุณสามารถแก้ไขในลิงค์ไปยังภาพหน้าจอฉันสามารถแก้ไขคำตอบของคุณเพื่อแสดงให้คุณ
SuperBiasedMan

1

ในกรณีของฉันฉันต้องตั้งค่าเป้าหมายการปรับใช้เป็นอย่างน้อย“ OS X 10.9” และ-Swift.hส่วนหัวถูกสร้างขึ้นโดยอัตโนมัติ โปรดทราบว่าคุณจะได้รับคำเตือนจำนวนมากเมื่อคุณเปลี่ยนรุ่นเป้าหมายการปรับใช้โดยเฉพาะอย่างยิ่งเมื่อคุณมีฐานรหัส Objective C ที่เก่ากว่าและมีขนาดใหญ่มาก ในกรณีของเราเรายังมีงานอีกมากที่ต้องทำในไฟล์ XIB และดูชั้นเรียน


2
สำหรับคนอื่น - ดูในการตั้งค่าการสร้างสำหรับเป้าหมายของคุณรับชื่อที่แน่นอน "MyProject-Swift.h" - นั่นคือสิ่งที่คุณต้องรวมเป็น "#include" MyProject-Swift.h "ในไฟล์ Objc ที่เหมาะสม BTW สิ่งนี้ คำตอบช่วยฉันได้มาก - ทำงานเพื่อแปลงโอเพ่นซอร์ส ObjectiveC ที่เก่ากว่า
David H

0

หากคุณสามารถสร้างโครงการมาก่อนโดยไม่มีปัญหาเกี่ยวกับ“ProductModuleName-Swift.h” not foundข้อผิดพลาดและตอนนี้คุณได้รับข้อผิดพลาดที่น่ารังเกียจอีกครั้งสาเหตุอาจมาจากการเปลี่ยนแปลงล่าสุดของคุณ

สำหรับฉันการ.swiftเข้ารหัสไฟล์ไม่ถูกต้อง (โดยไม่ตั้งใจ) คืนค่าการเปลี่ยนแปลงและนำกลับมาด้วยตนเองทำงาน


0

นี่อาจเป็นจุดที่ชัดเจน (อาจชัดเจนเกินไป) แต่คุณต้องมีไฟล์ swift อย่างน้อยหนึ่งไฟล์ในโครงการเพื่อให้ส่วนหัวสร้าง หากคุณกำลังเขียนแผ่นสำเร็จรูปหรือรหัสการกำหนดค่าโดยมีความตั้งใจที่จะเขียนอย่างรวดเร็วในภายหลังการนำเข้าจะไม่ทำงาน


0

ฉันต้องลบ WatchOS2 swift code จากโปรเจค Objective C ของฉัน และหลังจาก XCode นั้นเสนอให้สร้าง -Swift.h


0

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


0

หากคุณกำลังใช้งานสิ่งที่คล้ายกับ Cocoapods (และใช้พื้นที่ทำงานแทนโครงการ) ให้ลองเปิดโครงการและสร้างโครงการก่อนที่จะเปิดพื้นที่ทำงานและสิ่งปลูกสร้าง YMMV


0

บางครั้งคุณเพียงแค่ต้องยกเลิกการตั้งค่าจากนั้นตั้งค่าความเป็นสมาชิกเป้าหมายอีกครั้งบนไฟล์ obj-c .m

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