Jak wywołać Kod Objective-C Z Swift?

W języku Swift jak wywołać Kod Objective-C?

Apple wspomniało, że mogą one współistnieć w jednej aplikacji, ale czy to oznacza, że można technicznie ponownie wykorzystać stare klasy wykonane w Objective-C podczas budowania nowych klas w Swift?

Author: TylerH, 2014-06-02

17 answers

Używanie klas Objective-C w języku Swift

Jeśli masz istniejącą klasę, której chcesz użyć, wykonaj Krok 2 , a następnie przejdź do Krok 5 . (W niektórych przypadkach musiałem dodać jawną #import <Foundation/Foundation.h do starszego pliku Objective-C.)

Krok 1: Dodaj Implementację Objective-C -- .m

Dodaj plik .m do swojej klasy i nazwij go CustomObject.m.

Krok 2: Dodaj Nagłówek Mostkowy

Podczas dodawania pliku .m prawdopodobnie zostaniesz trafiony z podpowiedzią, która wygląda tak:

Okno dialogowe w stylu arkusza macOS z Xcode z pytaniem, czy " chcesz skonfigurować nagłówek mostkowy Objective-C"

Kliknij Tak !

Jeśli nie widzisz znaku zachęty lub przypadkowo usunąłeś nagłówek pomostowy, Dodaj nowy plik .h do swojego projektu i nadaj mu nazwę <#YourProjectName#>-Bridging-Header.h.

W niektórych sytuacjach, szczególnie podczas pracy z frameworkami Objective - C, nie dodaje się jawnie klasy Objective-C i Xcode nie może znaleźć linkera. W takim przypadku utwórz plik .h o nazwie wymienionej powyżej, a następnie upewnij się, że łączysz jego ścieżka w ustawieniach projektu docelowego wygląda tak:

Animacja pokazująca powyższy akapit

Uwaga:

Najlepszą praktyką jest łączenie projektu za pomocą makra $(SRCROOT), aby przenieść projekt lub pracować nad nim z innymi przy użyciu zdalnego repozytorium, nadal będzie on działał. $(SRCROOT) może być traktowany jako katalog zawierający Twoje .plik xcodeproj. Może to wyglądać tak:

$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h

Krok 3: Dodaj Nagłówek Objective-C -- .h

Dodaj kolejny plik .h i nazwij go CustomObject.h.

Krok 4: Zbuduj swój cel-Klasa C

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

Krok 5: Dodaj klasę do Bridging-Header

W YourProject-Bridging-Header.h:

#import "CustomObject.h"

Krok 6: Użyj swojego obiektu

W SomeSwiftFile.swift:

var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

Nie ma potrzeby jawnego importowania; do tego służy nagłówek pomostowy.

Używanie klas Swift w Objective-C

Krok 1: Utwórz Nową Klasę Swift

Dodaj plik .swift do swojego projekt 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)"
    }
}

Krok 2: Import plików Swift do klasy ObjC

W SomeRandomClass.m:

#import "<#YourProjectName#>-Swift.h"

Plik: <#YourProjectName#>-Swift.h powinien być już utworzony automatycznie w Twoim projekcie, nawet jeśli go nie widzisz.

Krok 3: Użyj swojej klasy

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);

Uwagi:

  1. Jeśli uzupełnianie kodu nie działa zgodnie z oczekiwaniami, spróbuj uruchomić szybką kompilację z R aby pomóc Xcode znaleźć część kodu Objective-C z kontekstu Swift i odwrotnie.

  2. Jeśli dodasz plik .swift do starszego projektu i pojawi się błąd dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, spróbuj całkowicie ponownie uruchomić Xcode.

  3. Chociaż początkowo możliwe było użycie klas Pure Swift (Nie Potomków NSObject), które są widoczne dla Objective - C za pomocą prefiksu @objc, nie jest to już możliwe. Teraz, aby być widocznym w Objective-C, Obiekt Swift musi być klasą zgodną aby NSObjectProtocol (najprostszym sposobem na to jest dziedziczenie z NSObject), lub być enum oznaczonym @objc z surową wartością jakiegoś typu integer, takiego jak Int. możesz wyświetlić historię edycji dla przykładu Swift 1.kod x przy użyciu @objc bez tych ograniczeń.

 1455
Author: Logan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-11 19:43:13

[[3]}zobacz poradnik Apple ' a dotyczący używania języka Swift z Cocoa i Objective-C . Ten przewodnik opisuje, jak korzystać z kodu Objective-C i c z Swift i vice versa oraz zawiera zalecenia dotyczące konwersji 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, ten Objective-C:

UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];

Zamienia się w ten szybki kod:

let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)

Xcode wykonuje również to tłumaczenie w locie - możesz użyć Open Quickly podczas edycji pliku Swift i wpisać nazwę klasy Objective-C, a to zabierze cię do wersji SWIFT-ified nagłówka klasy. (Można to również uzyskać, klikając cmd na symbol API w pliku Swift.), A cała dokumentacja API w bibliotekach programistycznych iOS 8 i OS X v10.10 (Yosemite) jest widoczna zarówno w postaci Objective-C, jak i Swift (np. UIView).

 122
Author: rickster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 10:49:06

Oto instrukcje krok po kroku, jak używać kodu Objective-C (w tym przypadku framework dostarczony przez stronę trzecią) w projekcie Swift:

  1. Dodaj dowolny plik Objective - C do swojego projektu Swift wybierając File -> New -> New File -> Objective-C File. Po zapisaniu, Xcode zapyta, czy chcesz dodać nagłówek pomostowy . Wybierz " Tak ". Gif: dodanie pustego pliku do projektu i wygenerowanie nagłówka pomostowego
    (źródło: derrrick.com )

W prostym kroki:

  1. Pojawi się monit, a następnie kliknij OK... Jeśli nie pojawia się, wtedy tworzymy go ręcznie jak w poniższym... Utwórz jeden plik nagłówka ze źródła iOS i podaj nazwę ProjectName-Bridging-Header( przykład: test-Bridging-Header), a następnie przejdź do Ustawienia budowania w kodzie kompilatora Swift- > Objective-C bridge Dodaj nazwę Objective-C bridge ..(Test/Test-Bridging-Header.h). Tak, skończone.

  2. Opcjonalnie Usuń dodany plik Objective-C (nazwane "cokolwiek" na obrazku GIF powyżej). Już jej nie potrzebujesz.

  3. Otwórz plik nagłówka mostkowania -- nazwa pliku ma postać [YourProject]-Bridging-Header.h . Zawiera komentarz Xcode. Dodaj wiersz kodu dla pliku Objective-C, który chcesz dołączyć , np. framework innej firmy. Na przykład, aby dodać Mixpanel do projektu, musisz dodać następujący wiersz kodu do nagłówka mostkowego plik:

    #import "Mixpanel.h"
  4. Teraz w dowolnym pliku Swift możesz użyć istniejącego kodu Objective-C, w składni Swift (w tym przykładzie można wywołać metody Mixpanel SDK, itd.). Musisz zapoznać się z tym, jak Xcode przekłada Objective - C na Swift. Przewodnik Apple to szybka lektura. Lub zobacz tę odpowiedź dla niekompletnego podsumowania.

Przykład dla Mixpanel:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    Mixpanel.sharedInstanceWithToken("your-token")
    return true
}
To jest to!

Uwaga: Jeśli usuniesz mostek plik nagłówka z twojego projektu , przejdź do ustawień kompilacji i usuń wartość " Objective-C Bridging Header" w sekcji "Swift Compiler - Code Generation".

 62
Author: derrrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-09-25 19:49:23

Możesz przeczytać ładny post Swift & Cocoapods. Zasadniczo musimy utworzyć plik nagłówkowy i umieścić tam wszystkie nagłówki Objective-C. A potem musimy odwołać się do niego z naszych ustawień budowania. 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 też dokument Apple ' aużywanie Swift z Cocoa i Objective-C też.

 39
Author: Jake Lin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 10:51:34

Napisałem prosty projekt Xcode 6, który pokazuje jak mieszać C++, Objective - C i Swift code:

Https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console

W szczególności przykładwywołuje funkcję Objective - C i c++ z programu Swift.

Kluczem jest utworzenie współdzielonego nagłówka, Project-Bridging-Header.h i umieść tam nagłówki Objective-C.

Proszę pobrać projekt jako kompletny przykład.

 25
Author: Gian Luigi Romita,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 11:03:32

Jeszcze jedna rzecz, którą chciałbym tu dodać:

Jestem bardzo wdzięczny za odpowiedź @ Logan. Bardzo pomaga tworzenie pliku bridge i ustawień.

Ale po wykonaniu tych wszystkich kroków nadal nie dostaję klasy Objective-C w Swift.

Użyłem biblioteki cocoapods i włączyłem ją do mojego projektu. Czyli pod "pop".

Więc jeśli używasz Objective-C pods w Swifcie to może być szansa, że nie będziesz w stanie zdobyć lub import klas do Swift.

The simple thing you have to do is:

  1. przejdź do <YOUR-PROJECT>-Bridging-Header pliku i
  2. Zastąp wypowiedź #import <ObjC_Framework> na @import ObjC_Framework

Na przykład: (Biblioteka Pop)

Zastąp

#import <pop/POP.h>

Z

@import pop;

użyj clang import, Gdy #import nie działa.

 24
Author: Kampai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Cytat z dokumentacji:

Dowolny Framework Objective - C (lub biblioteka C), który jest dostępny jako moduł można importować bezpośrednio do Swift. Obejmuje to wszystkie Ramy systemu Objective-C-takie jak Foundation, UIKit i SpriteKit-a także wspólne biblioteki C dostarczane wraz z systemem. Na przykład, aby zaimportować fundament, wystarczy dodać to polecenie import do początek pliku Swift, w którym pracujesz:

import Foundation

To import sprawia, że wszystkie API Fundacji-w tym NSDate, NSURL, NSMutableData, oraz wszystkie ich metody, właściwości i kategorie-dostępne bezpośrednio w języku Swift.

 22
Author: Gergo Erdosi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-02 20:43:55

Tylko uwaga dla tego, kto próbuje dodać bibliotekę Objective-C do Swift: powinieneś dodać - ObjC w Build Settings -> linkowanie -> inne flagi linkera .

 12
Author: david72,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 11:17:13

Po utworzeniu nagłówka mostkowego przejdź do Build Setting = > Szukaj "Objective-C Bridging Header".

Poniżej znajduje się plik" "Objective-C Generated Interface Header Name".

Zaimportuj ten plik do kontrolera widoku.

Przykład: w moim przypadku: "Dauble-Swift.h "

opis obrazu eEter tutaj

 10
Author: Avijit Nagare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 11:16:00

Kliknij w menu Plik Nowy i wybierz Plik wybierz cel językowy. W tym czasie automatycznie generuje plik "Objective - C Bridging Header", który jest używany do definiowania nazwy jakiejś klasy.

"Objective - C Bridging Header" pod "Swift Compiler-Code Generation".

 5
Author: Yogesh shelke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 11:11:45
  1. Utwórz .h Plik z NewFile -> Source - > header file
  2. następnie zapisz nazwę pliku Your_Target_Name-Bridging-Header.H ludzie tutaj często popełniają błąd, przyjmując nazwę projektu, ale powinna to być Nazwa celu projektu, jeśli w przypadku, gdy oba są różne, ogólnie są takie same.
  3. Następnie w Ustawieniach budowania wyszukaj znacznik Objective-C Bridging Header i umieść adres nowo utworzonego pliku bridging, możesz to zrobić klikając prawym przyciskiem myszy na pliku - >pokaż w Finderze - > przeciągnij plik w obszarze tekstowym, a adres zostanie wypełniony.
  4. Using #import Your_Objective-C_file.h
  5. w pliku swift można uzyskać dostęp do pliku ObjC, ale tylko w języku swift.
 3
Author: Nish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-29 07:09:37

W projekcie Swift 4.2.1 w Xcode 10.1 można łatwo dodać plik Objective-C. Wykonaj poniższe kroki, aby przenieść plik Objective-C do projektu 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 po raz pierwszy, Xcode pyta:

Would you like to configure an Objective-C bridging header?

Tutaj wpisz opis obrazka

Krok_04: wybierz opcję:

Create Bridging Header.

Krok_05: zostanie wygenerowany odpowiedni plik o nazwie:

Objc-Bridging-Header.h.

Tutaj wpisz opis obrazka

Step_06: teraz musisz ustawić ścieżkę pliku Bridge 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 do tego pola, aby wygenerować ścieżkę do pliku.

Tutaj wpisz opis obrazka

Krok_08: Otwórz plik Objc-Bridging-Header.h 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 pliku Swift możesz użyć klasy Objective-C:

override func viewDidLoad() {
    super.viewDidLoad()
    let myObjcContent = Person()
    print(myObjcContent.busy)
}

Tutaj wpisz opis obrazka Tutaj wpisz opis obrazka

 3
Author: Andy Fedoroff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-07 17:19:00

Logans answer działa dobrze, z wyjątkiem ostatniego Swift 5 daje jakiś błąd kompilatora. Oto poprawka dla osób, które pracują nad Swift 5.

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
    }
}
 1
Author: Sazzad Hissain Khan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Swift consumer, Objective-C producer

  1. Dodaj nowy nagłówek .h i pliki implementacji .m - plik klasy Cocoa (Objective-C)
    Na przykład MyFileName.

  2. Konfiguracja nagłówka mostkowego
    Kiedy zobaczysz Would you like to configure an Objective-C bridging header Kliknij - tak

    • <target_name>-Bridging-Header.h zostanie wygenerowany automatycznie
    • Build Settings- > Objective-C Bridging Header
  3. Add Class to Bridging-Header
    W <target_name>-Bridging-Header.h Dodaj wiersz #import "<MyFileName>.h"

Następnie możesz użyć MyFileName z Objective-C W Swift

P. S. jeśli powinieneś dodać istniejący plik Objective-C do projektu Swift, dodaj Bridging-Header.h wcześniej i zaimportuj go

Objective - C consumer, Swift producer

  1. Dodaje <MyFileName>.swift i rozszerza NSObject

  2. Import plików Swift do klasy ObjC
    Dodaj #import "<target_name>-Swift.h" do pliku Objective-C

  3. Expose public Swift code by @objc [@objc i @objcMembers]

Po tym możesz użyć Swift w Objective-C

 1
Author: yoAlex5,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-16 16:05:52

Apple udostępniło oficjalny przewodnik w tym dokumencie: how-to-call-objective-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 Objective-C bridging, aby wystawić te pliki na Swift . 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 akceptujesz, Xcode tworzy plik nagłówka mostkowania wraz z plikiem, który tworzysz, i nazywa go za pomocą nazwy modułu produktu, a następnie " - Bridging-Header.h". Alternatywnie możesz utworzyć nagłówek pomostowy samodzielnie, wybierając Plik > Nowy > plik > [system operacyjny] > źródło > plik nagłówka

Edytuj nagłówek pomostowy, aby wyeksponować kod Objective-C do kodu Swift:

  1. w nagłówku mostkowym Objective-C Importuj każdy Objective-C nagłówek, który chcesz udostępnić Swift .
  2. w Ustawieniach budowania, w generowaniu kodu kompilatora Swift upewnij się, że ustawienie budowania nagłówka mostkowego Objective-C ma ścieżkę do pliku nagłówka mostkowego. Ścieżka powinna być względem twojego projektu, podobnie jak Twoje informacje.ścieżka plist jest określona w Ustawieniach budowania. W większości przypadków nie trzeba modyfikować tego ustawienia.

Wszelkie nagłówki public Objective-C wymienione w nagłówku pomostowym są widoczne dla Swift.

 0
Author: Tibin Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-05 12:36:48

Podejście dwukierunkowe do stosowania objective-c objective-C

1

  1. Utwórz nagłówek mostu.plik h W projekcie Xcode
  2. import .h file in bridge-header file
  3. Ustaw ścieżkę nagłówka mostu w Ustawieniach budowania.
  4. Wyczyść Projekt

2

  1. tworzenie plików objective-c w projekcie (automatycznie ustawia ścieżkę w Ustawieniach budowania)
  2. import .h file in bridge-header file

Teraz good To go Thanks

 0
Author: Sanjay Mali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-08 12:22:02

Tworzenie dowolnej podklasy klasy Swift NSObject ma sens również wolę używać dowolnej klasy Swift, aby była widziana w klasach Objective-C takich jak:

@objc(MySwiftClass)
@objcMembers class MySwiftClass {...}
 0
Author: roadRunner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-09-28 17:32:32