Niedawno pracowałem nad dodaniem Swift do istniejącego projektu, aby wypróbować go w świecie rzeczywistym.
Po dodaniu do projektu pliku źródłowego Swift nie mam problemów z uzyskaniem „Bridging Header”, czyli Objective-C do Swift.
Ale nigdzie nie można znaleźć *-Swift.h
pliku nagłówkowego, który ma ujawniać klasy Swift oznaczone @objc
lub podklasy klas ObjC :-(
Nie widzę żadnych konkretnych instrukcji, jak osiągnąć wykorzystanie mojej nowej podklasy, napisanej w Swift, w moim głównym kodzie aplikacji (który wciąż jest celem C).
Aplikacja, której jestem głównym programistą, ma dość dużą bazę kodową (70 000 linii), więc nie ma możliwości przeniesienia jej za jednym razem.
objective-c
xcode
swift
David Kristensen
źródło
źródło
Odpowiedzi:
Teraz działa.
Wreszcie działa. Dziękujemy wszystkim za pomoc :-)
źródło
Build Settings
underPackaging
mójDefines Module
jest ustawiony naYes
i utworzyłemProduct Module Name
bez spacji. „* -Swift.h” nie jest generowany przez XCode 6. ???Defines Module
ustawionyYes
zarówno dla projektu i cel orazProduct Module Name
określono, ze bez spacji , ale nie wydaje się uzyskać ten plik wygenerowany.Miałem podobny problem i stwierdziłem, że można tylko dodać
#import "ProductModuleName-Swift.h"
do plików obj-c .m, a nie plików .h, aby znaleźć nagłówek parasola
źródło
Odkryłem, że muszę naprawić wszystkie błędy kompilacji, zanim wygeneruje plik.
Problem polegał na tym, że był to problem z kurczakiem / jajkiem, ponieważ nie widziałem żadnych błędów kompilacji, dopóki nie skomentowałem
#import
oświadczenia://#import "ProductModuleName-Swift.h"
co ujawniło wiele innych błędów w moim kodzie Swift.
Kiedy naprawiłem te nowe błędy i udało mi się zbudować źródło, odkomentowałem
#import
bingo! Nagłówek został utworzony i importowany poprawnie :)źródło
Jeśli jesteś podobny do mnie, prawdopodobnie masz nieprawidłową nazwę nagłówka. Po uderzeniu głową przez chwilę szukałem pliku w DerivedData i na pewno tam jest. W moim ustawieniu (przy użyciu standardowego folderu danych pochodnych):
Znajdziesz to. Jeśli nic w tym folderze nie pasuje, Xcode go nie generuje.
Używam Xcode w wersji 6.2 (6C86e)
źródło
-Swift.h
a nie nazwą mojego rzeczywistego pliku Swift. Dziękuję Ci!Jeśli w nazwie modułu projektu znajdują się spacje, należy zastąpić je spacją.
Na przykład, jeśli nazwa twojego projektu to „Mój projekt”, możesz użyć:
źródło
* Jedyną ważną rzeczą jest: *
aby użyć zdefiniowanej „Nazwy modułu produktu” w celu, a następnie -Swift.h
Bez względu na to, czy parametr „Definiuje moduł” jest ustawiony na Tak czy Nie, czy też projekt „Nazwa modułu produktu” nie jest ustawiony.
Przypomnienie: klasy Swift muszą pochodzić z NSObject lub zostały otagowane atrybutem @objc, aby być narażonym na ObjectiveC / Foundation || Kakao ...
źródło
Chciałem dodać jeszcze jeden powód, dla którego możesz mieć z tym problem - tworzyłem framework, który mieszał kod Swift i Objective-C. Nie byłem w stanie zaimportować klas Swift poza ramy - sprawdziłem, czy plik -Swift.h jest generowany, ale był pusty.
Problem okazał się bardzo, bardzo prosty - nie ogłosiłem żadnej z moich klas Swift publicznie! Jak tylko dodałem publiczne słowo kluczowe do klas, byłem w stanie użyć ich z klas wewnątrz i na zewnątrz frameworka.
Warto również zauważyć, że wewnątrz frameworka (tylko w plikach .m, jak wspomniano w innej odpowiedzi) musiałem zaimportować plik -Swift.h jako:
źródło
Miałem ten sam problem. Wygląda na to, że musisz dostosować ustawienia (definiuje nazwę modułu i moduł produktu) przed dodaniem pierwszego pliku Swift.
Jeśli zrobisz to później, plik „* -Swift.h” nie zostanie wygenerowany dla tego projektu, nawet jeśli dodasz kolejne pliki Swift lub usuniesz plik Swift i utworzysz nowy.
źródło
Pozwólcie, że podzielę się swoimi doświadczeniami, próbując używać Swift w starym projekcie objc. I nie trzeba było ustawić
Defines module
sięYES
.W moim przypadku musiałem ręcznie upewnić się, że istnieje nagłówek mostkujący objc. Tylko wygenerowana nazwa nagłówka interfejsu była obecna w moich ustawieniach kompilacji.
Doprowadziło to do wygenerowania pliku MyApp-Swift.h, ale bez żadnych śladów moich klas Swift.
Dokumentacja Apple mówi, że podczas dodawania pierwszego pliku szybkiego pojawi się monit o utworzenie nagłówka pomostowego. Cóż, nie byłem. Ręcznie dodałem
MyApp-Bridging-header.h
plik i wskazałem go w polu „Nagłówek mostkujący Objective-C”. To spowodowało, że mój plik MyApp-Swift.h został zapełniony moimi klasami Swift.Dokumenty: importowanie programu Swift do celu C
źródło
Oto kolejna odmiana modułu moduleName-Swift.h, która nie została wygenerowana.
Zdecydowałem się dołączyć wykresy IOS do mojego projektu, ale nie chciałem mieszać źródeł w tym samym katalogu, dlatego umieściłem folder Projekt wykresów obok folderu projektu mojego kodu. Przeciągnąłem projekt Wykresy do paska nawigacyjnego mojego projektu i zawarłem ramę na liście Osadzone pliki binarne mojego projektu w ogólnych ustawieniach projektu i ustawiłem opcję Osadzona zawartość zawiera kod Swift na Tak na karcie Ustawienia budowania w moim projekcie w sekcji Opcje budowania .
Plik moduleName-Swift.h mojego projektu nigdy nie wygenerowałby się, bez względu na inne sugerowane tutaj przełączniki lub ustawienia. W końcu, stosując metodę Lou Z do wyszukiwania plików -Swift.h, zobaczyłem, że plik Charts-Swift.h został wygenerowany głęboko w katalogu xcode Build mojego projektu w Charts.framework / Headers /
Rozwiązaniem użycia pakietu ios-charts Daniela Gindi Swift bez uwzględnienia kodu w katalogu źródłowym mojego projektu było dodanie:
Do modułów sporządzających wykresy danych mojego projektu.
źródło
Nazwa pliku jest zawsze poprzedzona nazwą docelową . Jest to nazwa produktu, ale praktycznie jest to nazwa docelowa. Więc jeśli chcesz zbudować go dla nowego celu, przygotuj się na
that_target-Swift.h
plik.Jednym ze sposobów rozwiązania tego problemu jest
MY_TARGET=1
. Dodaj to w Ustawieniach projektu -> Ustawienia kompilacji -> Makra preprocesora dla każdego celu.Dodaj te linie do pliku PCH
Zaletą korzystania z pliku PCH jest to, że nie trzeba wszędzie dołączać nagłówków.
To powinno działać dobrze.
źródło
include
nim zawartym ). Następnie importuję ten nowy plik z miejsca, w którym go potrzebuję. Wolę nie umieszczać tego w pliku PCH ani żadnym pliku .h, aby uniknąć cyklicznych zależności i używać nagłówka wygodnego w plikach .m..pch
pliki są mocno odradzane . Po drugie, nazwa pliku zawiera nazwę produktu, a NIE nazwę docelową. To może być zbieg okoliczności, że jest taki sam, ale użył nazwy produktu!Jeśli Xcode faktycznie generuje nagłówek -Swift.h (głęboko w DerivedData), ale nie odnosi się do twoich klas Swift, upewnij się, że masz również zdefiniowany nagłówek pomostowy. Sposób, w jaki czytałem dokumenty, sugerował, że potrzebowałem go tylko do wywołania Celu-C z Szybkiego, ale wydaje się to konieczne również do wywołania Szybkiego z Celu-C.
Zobacz moją odpowiedź: https://stackoverflow.com/a/27972946/337392
EDYCJA: Jest to spowodowane modyfikatorami dostępu publicznego vs. wewnętrznego, co ostatecznie znalazłem wyjaśnione w dokumentach Apple: -
źródło
Popiera to, co ma tu wiele osób, ale dodaje odpowiedni zrzut ekranu. Kod Swift i Obj-C z pewnością mogą żyć razem. To nie jest gra typu wszystko albo żadna.
Aby uzyskać dostęp do plików Swift w Objective-C, wystarczy dodać to wywołanie do pliku Obj-C (w pliku .m / implementacji):
(Gdzie {nazwa_modułu_produktu} reprezentuje nazwę modułu produktu twojego projektu). Zamiast próbować odgadnąć nazwę modułu produktu lub dowiedzieć się, jakie są narożniki ze spacjami i znakami specjalnymi, po prostu przejdź do karty ustawień kompilacji w projekcie i wpisz „nazwa modułu produktu” - inspektor ujawni ci twoje. Mój był czymś, czego się nie spodziewałem. Sprawdź ten zrzut ekranu, jeśli jesteś zdezorientowany.
Aby kod Obj-c działał w Swift, wystarczy dodać plik nagłówka pomostowego i zaimportować tam odpowiednie nagłówki Obj-C.
źródło
#import
?Najważniejsze, że ten plik jest niewidoczny !!! Przynajmniej jest w Xcode6 beta5. W twoim obszarze roboczym nie będzie takiego pliku o nazwie „YourModule-Swift.h”. Upewnij się tylko, że masz nazwę modułu i zdefiniowano moduł ustawiony na tak, i użyj go w swojej klasie Objective-C.
źródło
Ok, oto wszystkie rzeczy, których naprawdę potrzebujesz!
1. Usuń wszystkie dodane przez siebie szybkie pliki i skompiluj kod bez żadnych błędów.
----------
----------
2. Przejdź do ustawień kompilacji „Projekty” i ustaw nazwę modułu produktu. Projekt musi mieć nazwę modułu produktu, która nie zawiera spacji.
----------
----------
3.Defines Moduł musi być ustawiony na Tak w Ustawieniach kompilacji, w Pakowaniu, w twoim projekcie, a nie docelowy!
----------
----------
4. Teraz utwórz szybki plik lub kontroler widoku w pliku-> nowy plik->
----------
----------
Poprosi o utworzenie nagłówka pomostowego, pozwoli mu to zrobić. Jeśli raz go odrzuciłeś, będziesz musiał ręcznie dodać -Bridging-Header.h
5. Dodaj @objc w kontrolerze, aby poinformować kompilator, że istnieje jakiś szybki plik, który musi zostać udostępniony ObjectiveC
----------
----------
6.Zbuduj projekt i zaimportuj #import „-Swift.h” do dowolnego kontrolera ObjectC, a on zadziała! Możesz kliknąć go klawiszem Command, aby zobaczyć rzeczywisty plik!
----------
----------
Mam nadzieję że to pomoże!
źródło
Ta odpowiedź dotyczy przypadku użycia, w którym możesz już mieć kod Objective-C, który wywołuje klasy Swift, a następnie zaczynasz otrzymywać ten błąd.
Jak naprawić problem
Poniższe kroki ostatecznie rozwiązały wszystkie problemy dla mnie. Czytałem powyżej kogoś wspominającego o „kurczaku i jajku” i to właśnie ta koncepcja doprowadziła mnie do tej procedury. Ten jawny proces pokazuje, że należy usunąć kod Objective-C odwołujący się do klas Swift, dopóki nie zostanie wygenerowany nagłówek.
Nota Bene: Odpowiedzi na temat zmiany spacji na podkreślenia i moduł Definiowanie na TAK, jak podano powyżej, nadal obowiązują podczas wykonywania tego procesu, podobnie jak zasady określone w Dokumentacji Apple .
Bridging Header Path
W jednym błędzie nie znaleziono pliku ProductModuleName-Bridging-Header.h podczas kompilacji. Ten fakt spowodował błąd
Bliższa kontrola błędu wykazała, że plik nigdy nie istniałby w opisanej lokalizacji, ponieważ był on faktycznie zlokalizowany ( zła ścieżka )
„/Users/Shared/Working/abc/abc/abc-Bridging-Header.h”. szybkie wyszukiwanie ustawień kompilacji celu / projektów w celu ręcznej korekty, a plik abc-Swift.h został ponownie wygenerowany automatycznie.
źródło
Musisz zaimportować nagłówek do klas Objective-C, czyli:
Jest generowany automatycznie, na podstawie odwołania mówi: „Wszelkie pliki Swift w twoim celu będą widoczne w plikach .m Objective-C zawierających tę instrukcję importu”.
źródło
Rzeczywisty plik w projekcie nie jest tworzony ([ProductModuleName] -Swift.h). Polecenie Cmd + kliknięcie importu albo generuje go w locie (i w pamięci), aby można było zobaczyć, jak wykonuje się połączenie, albo otwiera plik gdzieś w katalogu pamięci podręcznej Xcode, ale nie ma go w katalogu projektu.
Musisz ustawić Prop projektu modułu (w Ustawieniach kompilacji celu) na Tak, a jeśli nazwa modułu zawiera spacje lub myślniki - użyj _ we wszystkich importach pliku [ProductModuleName] -Swift.h.
Możesz zaimportować go we wszystkich plikach .h i .m, w których używasz szybkich typów, lub możesz zaimportować go w pliku .pch.
Więc jeśli mój moduł (projekt) ma nazwę „Projekt testowy”, zaimportuję go w następujący sposób, w pliku .pch mojego projektu (tylko tam):
źródło
Tylko heads-up dla każdego, kto używał „”. w tam nazwa projektu. Xcode zastąpi „.” z podkreśleniem „_” dla wersji Swift mostkowego pliku nagłówkowego. Co dziwne, wygenerowany Bridging-Header.h nie zastępuje okresów podkreśleniami.
Na przykład projekt o nazwie My.Project miałby następujące nazwy plików nagłówka pomostowego.
Bridging-Header.h (automatycznie generowany)
My.Project-Bridging-Header.h
Swift.h
My_Project.h
Mam nadzieję, że to pomoże każdemu, kto użył kropki i utknął tak jak ja. Ten plik można znaleźć w następującej lokalizacji.
Macintosh HD / Users / user /Library/Developer/Xcode/DerivedData/My.Project-fntdulwpbhbbzdbyrkhanemcrfil/Build/Intermediates/My.Project.build/Debug-iphonesimulator/My.Project.build/DerivedSources
Dbać,
Jon
źródło
Projekt musi mieć nazwę modułu bez spacji. Definiuje Moduł musi być ustawiony na Tak w Ustawieniach kompilacji, w części Opakowanie. skomentował oświadczenie #import:
Jeśli nadal masz błąd podczas importowania pliku „ProductModuleName-Swift.h”, to
// # import "ProductModuleName-Swift.h"
co ujawniło wiele innych błędów w moim kodzie Swift.
Gdy naprawiłem te nowe błędy i udało mi się zbudować źródło, odkomentowałem #import i bingo! Nagłówek został utworzony i importowany poprawnie :)
źródło
Znalazłem sztuczkę, która zawsze na mnie działa.
Wykonaj tę pracę (usuń i utwórz plik „ProductModuleName-Swift.h” z pliku appDelegate.h i wyczyść kod) za każdym razem, gdy pojawi się ten błąd, aby go wyciszyć.
źródło
Znalazłem to rozwiązanie
Teraz możesz
zamiast ProductModuleName-Swift.h
Jest to rozwiązanie obejścia problemu. Myślę, że ten problem zostanie rozwiązany w następnej wersji Xcode. Powodzenia
źródło
#import “ProductModuleName-Swift.h”
pojawia się błąd w pliku SwiftBridge.h zamiast oryginalnego pliku kodu Objective-C.Trudno mi było określić import mojego nagłówka swift do nazwy modułu / celu-c. Przeczytałem tutaj również wiele artykułów.
Ale ostateczna odpowiedź na nazwę projektu ze wszystkimi zawartymi w niej znakami specjalnymi (czy to „.”, Cyfrą czy spacją) - możesz znaleźć tekst, który będzie dla ciebie działał w „ nazwie modułu produktu ” w Ustawieniach kompilacji celu .
Na przykład moja nazwa docelowa zaczynała się cyfrą - „1mg”, a wspomniane powyżej pole zawierało „_mg” jako nazwę mojego modułu.
więc użyłem #import „_mg-Swift.h” i zadziałało.
źródło
W moim przypadku musiałem ustawić cel wdrożenia co najmniej na „OS X 10.9”, a
-Swift.h
nagłówek został wygenerowany automatycznie. Pamiętaj, że możesz zmienić wiele ostrzeżeń o wycofaniu, gdy zmienisz docelową wersję wdrożenia, szczególnie gdy masz starszą i bardzo dużą bazę kodu Celu C. W naszym przypadku mieliśmy również dużo pracy w plikach XIB i klasach przeglądania.źródło
Jeśli wcześniej byłeś w stanie zbudować projekt, bez problemów związanych z
“ProductModuleName-Swift.h” not found
błędami, a teraz znów otrzymujesz te nieprzyjemne błędy, przyczyną mogą być ostatnie zmiany.Dla mnie było to (przypadkowe) nieprawidłowe
.swift
kodowanie pliku. Cofanie zmian i przywracanie ręczne wykonuje zadanie.źródło
To może być oczywisty punkt (może zbyt oczywisty), ale musisz mieć co najmniej jeden szybki plik w projekcie, aby nagłówek mógł zostać wygenerowany. Jeśli piszesz załącznik lub kod konfiguracji z zamiarem szybkiego pisania później, import nie będzie działać.
źródło
Musiałem usunąć szybki kod WatchOS2 z mojego projektu Celu C. I dopiero potem XCode zaproponował wygenerowanie -Swift.h
źródło
Miałem podobny problem, ale mój projekt kompilował się wcześniej i nagle pojawił się błąd po kilku zmianach kodu pliku. Dowiedziałem się, dlaczego pojawia się błąd „Nie znaleziono pliku” dla pliku myproject-swift.h. Wprowadzone przeze mnie zmiany w kodzie miały pewne błędy. Xcode nie wskazał, że zamiast tego cały czas wyświetlał błąd, pokazując „Błąd pliku nie znaleziono”. Potem dostałem kopię poprzedniego kodu i porównałem go z nowym kodem i scaliłem jeden po drugim. Po każdym scaleniu plików projekt był zgodny z projektem, aby znaleźć błąd. Więc jeśli chodzi o błąd w kodzie, Xcode może po prostu wyświetlać „błąd pliku nie znaleziono” dla pliku myproject-swift.h. Najprawdopodobniej masz błąd kompilacji w swoim projekcie. Wyczyść te błędy i będzie działać.
źródło
Jeśli używasz czegoś takiego jak Cocoapods (i pracujesz poza obszarem roboczym zamiast projektu), spróbuj otworzyć projekt i zbudować go przed otwarciem obszaru roboczego i budynku. YMMV.
źródło
Czasami wystarczy rozbroić, a następnie ponownie ustawić docelowe członkostwo w pliku obj-c .m.
źródło