Jak w Swift wywołuje się kod celu C?
Apple wspomniał, że mogą one współistnieć w jednej aplikacji, ale czy to oznacza, że można technicznie ponownie użyć starych klas stworzonych w Objective-C, budując nowe klasy w Swift?
Jak w Swift wywołuje się kod celu C?
Apple wspomniał, że mogą one współistnieć w jednej aplikacji, ale czy to oznacza, że można technicznie ponownie użyć starych klas stworzonych w Objective-C, budując nowe klasy w Swift?
Odpowiedzi:
Jeśli masz istniejącą klasę, której chcesz użyć, wykonaj krok 2, a następnie przejdź do kroku 5 . (W niektórych przypadkach musiałem dodać jawny
#import <Foundation/Foundation.h
plik do starszego pliku Objective-C).
Dodaj .m
plik do swojej klasy i nazwij go CustomObject.m
.
Podczas dodawania .m
pliku najprawdopodobniej wyświetli się następujący monit:
Kliknij Tak !
Jeśli nie zobaczyłeś monitu lub przypadkowo usunąłeś nagłówek pomostowy, dodaj nowy .h
plik do projektu i nazwij go <#YourProjectName#>-Bridging-Header.h
.
W niektórych sytuacjach, szczególnie podczas pracy ze strukturami Objective-C, nie dodajesz wyraźnie klasy Objective-C i Xcode nie może znaleźć linkera. W takim przypadku utwórz .h
plik o nazwie jak wspomniano powyżej, a następnie upewnij się, że łączysz jego ścieżkę w ustawieniach projektu docelowego w następujący sposób:
Uwaga:
Najlepszą praktyką jest łączenie projektu za pomocą $(SRCROOT)
makra, aby przeniesienie projektu lub praca nad nim przy użyciu zdalnego repozytorium nadal działała. $(SRCROOT)
może być uważany za katalog zawierający plik .xcodeproj. Może to wyglądać tak:
$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
Dodaj kolejny .h
plik i nazwij go CustomObject.h
.
W CustomObject.h
#import <Foundation/Foundation.h>
@interface CustomObject : NSObject
@property (strong, nonatomic) id someProperty;
- (void) someMethod;
@end
W CustomObject.m
#import "CustomObject.h"
@implementation CustomObject
- (void) someMethod {
NSLog(@"SomeMethod Ran");
}
@end
W YourProject-Bridging-Header.h
:
#import "CustomObject.h"
W SomeSwiftFile.swift
:
var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()
Nie ma potrzeby jawnego importowania; po to jest nagłówek pomostowy.
Dodaj .swift
plik do projektu i nazwij go MySwiftObject.swift
.
W MySwiftObject.swift
:
import Foundation
@objc(MySwiftObject)
class MySwiftObject : NSObject {
@objc
var someProperty: AnyObject = "Some Initializer Val" as NSString
init() {}
@objc
func someFunction(someArg: Any) -> NSString {
return "You sent me \(someArg)"
}
}
W SomeRandomClass.m
:
#import "<#YourProjectName#>-Swift.h"
Plik: <#YourProjectName#>-Swift.h
powinien już zostać utworzony automatycznie w twoim projekcie, nawet jeśli go nie widzisz.
MySwiftObject * myOb = [MySwiftObject new];
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
myOb.someProperty = @"Hello World";
NSLog(@"MyOb.someProperty: %@", myOb.someProperty);
NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];
NSLog(@"RetString: %@", retString);
Jeśli uzupełnianie kodu nie działa zgodnie z oczekiwaniami, spróbuj uruchomić szybką kompilację, ⌘⇧Raby pomóc Xcode znaleźć część kodu Objective-C z kontekstu Swift i odwrotnie.
Jeśli dodasz .swift
plik do starszego projektu i otrzymasz błąd dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
, spróbuj całkowicie zrestartować Xcode .
Chociaż pierwotnie było możliwe użycie czystych klas Swift (nie potomków NSObject
), które są widoczne dla Objective-C przy użyciu @objc
prefiksu, nie jest to już możliwe. Teraz, aby być widocznym w Objective-C, obiekt Swift musi albo być klasą zgodną z NSObjectProtocol
(najprostszym sposobem na to jest dziedziczenie NSObject
), albo być enum
oznaczony @objc
surową wartością jakiegoś typu liczby całkowitej Int
. Możesz przeglądać historię edycji dla przykładu kodu Swift 1.x używającego @objc
bez tych ograniczeń.
Zobacz przewodnik Apple dotyczący używania Swift z kakao i Objective-C . Ten przewodnik obejmuje korzystanie z kodu Objective-C i C z Swift i vice versa oraz zawiera zalecenia dotyczące konwertowania projektu lub mieszania i dopasowywania części Objective-C / C i Swift w istniejącym projekcie.
Kompilator automatycznie generuje składnię Swift do wywoływania funkcji C i metod Objective-C. Jak widać w dokumentacji, cel C:
UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
zamienia się w ten kod Swift:
let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)
Xcode wykonuje również to tłumaczenie w locie - możesz użyć Otwórz szybko podczas edycji pliku Swift i wpisać nazwę klasy Objective-C, a przeniesie Cię to do nagłówka klasy Swift-ified. (Można to również uzyskać, klikając cmd symbol API w pliku Swift). Cała dokumentacja referencyjna API w bibliotekach programistów iOS 8 i OS X 10.10 (Yosemite) jest widoczna zarówno w Objective-C, jak i Swift formularze (np UIView
.).
Oto instrukcje krok po kroku dotyczące używania kodu Objective-C (w tym przypadku frameworku dostarczonego przez firmę zewnętrzną) w projekcie Swift:
W prostych krokach:
Pojawi się monit, a następnie kliknij przycisk OK ... Jeśli się nie pojawi, wówczas tworzymy go ręcznie, jak poniżej: Utwórz jeden plik nagłówka ze źródła iOS i nadaj nazwę ProjectName-Bridging-Header (przykład: Test -Bridging-Header), a następnie przejdź do kompilacji w kodzie kompilatora Swift -> Most Cel-C dodaj nazwę mostu Cel-C .. (Test / Test-Bridging-Header.h). Tak, to koniec.
Opcjonalnie usuń dodany plik Objective-C (o nazwie „cokolwiek” na powyższym obrazku GIF). Już go nie potrzebujesz.
Otwórz mostkowy plik nagłówkowy - nazwa pliku ma postać [YourProject] -Bridging-Header.h . Zawiera komentarz dostarczony przez Xcode. Dodaj wiersz kodu dla pliku Objective-C, który chcesz dołączyć , na przykład frameworku innej firmy. Na przykład, aby dodać Mixpanel do swojego projektu, musisz dodać następujący wiersz kodu do mostkowego pliku nagłówkowego:
#import „Mixpanel.h”
Teraz w dowolnym pliku Swift możesz użyć istniejącego kodu Objective-C, w składni Swift (w przypadku tego przykładu i możesz wywołać metody Mixpanel SDK itp.). Musisz zapoznać się ze sposobem, w jaki Xcode tłumaczy Objective-C na Swift. Poradnik Apple'a to szybka lektura. Lub zobacz tę odpowiedź, aby uzyskać niepełne podsumowanie.
Przykład dla Mixpanel:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
Mixpanel.sharedInstanceWithToken("your-token")
return true
}
Otóż to!
Uwaga: Jeśli usuniesz plik nagłówka pomostowego z projektu , przejdź do Ustawień kompilacji i usuń wartość „ Celujący nagłówek pomostowy C ” w „Kompilatorze Swift - Generowanie kodu”.
Możesz przeczytać miły post Swift & Cocoapods . Zasadniczo musimy utworzyć mostkowy plik nagłówkowy i umieścić tam wszystkie nagłówki Cel-C. A następnie musimy odwołać się do tego w naszych ustawieniach kompilacji. Następnie możemy użyć kodu Objective-C.
let manager = AFHTTPRequestOperationManager()
manager.GET(
"http://example.com/resources.json",
parameters: nil,
success: { (operation: AFHTTPRequestOperation!,
responseObject: AnyObject!) in
println("JSON: " + responseObject.description)
},
failure: { (operation: AFHTTPRequestOperation!,
error: NSError!) in
println("Error: " + error.localizedDescription)
})
Zobacz także dokument Apple'a Używanie Swift z kakao i Objective-C .
Napisałem prosty projekt Xcode 6, który pokazuje, jak mieszać kod C ++, Objective-C i Swift:
https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
W szczególności przykład wywołuje funkcję Objective-C i C ++ od Swift .
Kluczem jest utworzenie wspólnego nagłówka Project-Bridging-Header.h i umieszczenie tam nagłówków Objective-C.
Pobierz projekt jako kompletny przykład.
Jestem bardzo wdzięczny za odpowiedź @ Logana. Bardzo pomaga w tworzeniu pliku pomostu i ustawień.
Ale po wykonaniu wszystkich tych kroków nadal nie dostaję klasy Objective-C w Swift.
Korzystałem z cocoapods
biblioteki i zintegrowałem ją z moim projektem. Który jestpod "pop"
.
Jeśli więc używasz kapsułów Celu-C w Swift, może istnieć szansa, że nie będziesz w stanie dostać import
się do Swift lub klas.
Prostą rzeczą, którą musisz zrobić, to:
<YOUR-PROJECT>-Bridging-Header
pliku i#import <ObjC_Framework>
na@import ObjC_Framework
Na przykład: (Pop Library)
Zastąpić
#import <pop/POP.h>
z
@import pop;
Użyj, clang import
gdy #import
nie działa.
Cytat z dokumentacji :
Dowolną platformę Objective-C (lub bibliotekę C), która jest dostępna jako moduł, można zaimportować bezpośrednio do Swift. Obejmuje to wszystkie frameworki systemu Objective-C - takie jak Foundation, UIKit i SpriteKit - a także wspólne biblioteki C dostarczane z systemem. Na przykład, aby zaimportować Foundation, po prostu dodaj tę instrukcję importu na górze pliku Swift, w którym pracujesz:
import Foundation
Ten import powoduje, że wszystkie interfejsy API Fundacji - w tym NSDate, NSURL, NSMutableData oraz wszystkie ich metody, właściwości i kategorie - są bezpośrednio dostępne w Swift.
Tylko uwaga dla każdego, kto próbuje dodać bibliotekę Objective-C do Swift: Powinieneś dodać -ObjC w Ustawieniach kompilacji -> Łączenie -> Inne flagi Linkera .
Po utworzeniu nagłówka Bridging przejdź do Build Setting => Wyszukaj „Cel-C Bridging Header”.
Tuż poniżej znajduje się plik „„ Nazwa nagłówka interfejsu generowanego przez Objective-C ””.
Zaimportuj ten plik do kontrolera widoku.
Przykład: W moim przypadku: „Dauble-Swift.h”
Kliknij menu Nowy plik i wybierz plik wybierz język Cel. W tym momencie automatycznie generuje plik „Objective-C Bridging Header”, który służy do zdefiniowania nazwy klasy.
„Nagłówek mostkujący Objective-C” w „Swift Compiler - Generowanie kodu”.
W projekcie Swift 4.2.1 w Xcode 10.1 możesz łatwo dodać plik Objective-C. Wykonaj poniższe czynności, aby połączyć plik Objective-C z projektem Swift.
Krok_01: Utwórz nowy projekt Xcode za pomocą języka Swift:
File
> New
> Project
> objc
.
Krok_02: W projekcie Swift dodaj nowy plik Objective-C:
File
> New
> File...
> macOS
> Objective-C File
.
Krok_03: Jeśli dodasz nowy plik Objective-C do projektu Swift za pierwszym razem, Xcode zapyta:
Would you like to configure an Objective-C bridging header
?
Krok_04: Wybierz opcję:
Create Bridging Header
.
Krok_05: Odpowiedni plik zostanie wygenerowany o nazwie:
Objc-Bridging-Header.h
.
Krok_06: Teraz potrzebujesz ścieżki pliku mostu w nagłówku mostu. W Nawigatorze projektów kliknij projekt o nazwie, objc
a następnie wybierz:
Build Settings
> Objective-C Bridging Header
> Objc-Bridging-Header.h
.
Krok_07: Przeciągnij i upuść swoje Objc-Bridging-Header.h
w to pole, aby wygenerować ścieżkę do pliku.
Krok_08: Otwórz Objc-Bridging-Header.h
plik i zaimportuj plik Objective-C, którego chcesz użyć w pliku Swift.
#import "SpecialObjcFile.m"
Oto treść SpecialObjcFile.m
:
#import <Foundation/Foundation.h>
@interface Person: NSObject {
@public
bool busy;
}
@property
bool busy;
@end
Krok_09: Teraz w swoim pliku Swift możesz użyć klasy Objective-C:
override func viewDidLoad() {
super.viewDidLoad()
let myObjcContent = Person()
print(myObjcContent.busy)
}
Odpowiedź Logans działa dobrze, z wyjątkiem najnowszych, Swift 5
że daje błąd kompilatora. Oto poprawka dla osób pracujących nad Swift 5.
import Foundation
class MySwiftObject : NSObject {
var someProperty: AnyObject = "Some Initializer Val" as AnyObject
override init() {}
func someFunction(someArg:AnyObject) -> String {
let returnVal = "You sent me \(someArg)"
return returnVal
}
}
Dodaj nagłówek .h
i .m
pliki implementacji - plik klasy kakao (cel C)
Na przykładMyFileName
skonfiguruj nagłówek mostkujący
Kiedy zobaczysz Would you like to configure an Objective-C bridging header
kliknij - Tak
<target_name>-Bridging-Header.h
zostanie wygenerowany automatycznieDodaj klasę do Bridging-Header
W <target_name>-Bridging-Header.h
dodaj linię#import "<MyFileName>.h"
PS Jeśli chcesz dodać istniejące pliki Objective-C do projektu Swift, dodaj je Bridging-Header.h
wcześniej
Dodaj <MyFileName>.swift
i rozszerzaNSObject
Zaimportuj pliki Swift do klasy ObjC
Dodaj #import "<#YourProjectName#>-Swift.h"
do pliku Objective-C
Oznacz publiczny kod Swift [@objc i @objcMembers]
Apple przedstawił oficjalny przewodnik w tym dokumencie: how-to-call-aim-c-code-from-swift
Oto odpowiednia część:
Aby zaimportować zestaw plików Objective-C do kodu Swift w ramach tego samego celu aplikacji, polegasz na pliku nagłówkowym mostkującym Objective-C, aby udostępnić te pliki Swiftowi . Xcode oferuje utworzenie tego nagłówka po dodaniu pliku Swift do istniejącej aplikacji Objective-C lub pliku Objective-C do istniejącej aplikacji Swift.
Jeśli zaakceptujesz, Xcode tworzy plik nagłówka pomostowego wraz z plikiem, który tworzysz, i nadaje mu nazwę, używając nazwy modułu produktu, a następnie „-Bridging-Header.h”. Możesz także samodzielnie utworzyć mostkujący nagłówek, wybierając opcję Plik> Nowy> Plik> [system operacyjny]> Źródło> Plik nagłówka
Edytuj nagłówek pomostowy, aby udostępnić kod Objective-C kodowi Swift:
Wszelkie publiczne nagłówki Celu C wymienione w nagłówku pomostowym są widoczne dla Swift.
Dwukierunkowe podejście do użycia celu-c celu-c
1
2)
Teraz dobrze iść Dzięki