Swift'ten Objective-C kodunu nasıl arayabilirim?


974

Swift'te kişi Objective-C kodunu nasıl çağırır?

Apple, bir uygulamada birlikte var olabileceklerini belirtti, ancak bu, Swift'te yeni sınıflar oluştururken Objective-C'de yapılan eski sınıfları teknik olarak yeniden kullanabileceği anlamına mı geliyor?


13
Apple'ın Swift'i Kakao ve Objective-C ile Kullanma kılavuzuna bakın .
rickster


10
İlginçtir ki bu soru çok sayıda oy ve ödül kazanıyor. İlk gördüğümde düşündüm: RTFM. Şu anda olduğu gibi gerçekten hiçbir araştırma göstermiyor, çünkü Swift'i resmen belgeleyen sadece iki veya üç kaynak var ve bunlardan biri tam olarak buna adanmış (ve ilk yorumda bağlantılı).
Analog Dosya

6
@EvolGate: Platformdan bağımsız bir dil olmasını engelleyen Objective C'de tam olarak eksik olan şey nedir? Dil ve dil standart kütüphaneleri açık kaynak kodludur. Objective C'yi Windows, Os X, Linux, BSD, Solaris ve GCC veya LLVM tarafından desteklenen diğer herhangi bir platformda ve için kullanabilirsiniz. Ne GCC ne de LLVM tarafından desteklense bile Objective C'yi iyi bir C derleyicisine sahip herhangi bir platforma kolayca taşıyabilirsiniz. Bundan daha platformdan nasıl bağımsız olabileceğini görmüyorum.
Analog Dosya

2
@DavidMulder: "Akıl Yürütme" bölümüne hala ihtiyaç var mı?
franck

Yanıtlar:


1394

Swift'te Objective-C Sınıflarını Kullanma

Kullanmak istediğiniz mevcut bir sınıfınız varsa, Adım 2'yi gerçekleştirin ve ardından Adım 5'e geçin . (Bazı durumlarda, #import <Foundation/Foundation.hdaha eski bir Objective-C Dosyasına açık bir şey eklemek zorunda kaldım .)

Adım 1: Hedef-C Uygulaması Ekleme - .m

.mSınıfınıza bir dosya ekleyin ve dosyayı adlandırın CustomObject.m.

2. Adım: Köprüleme Üstbilgisi Ekleme

.mDosyanızı eklerken, muhtemelen şuna benzer bir istemle karşılaşırsınız:

Xcode'dan "Objective-C köprüleme üstbilgisi yapılandırmak isteyip istemediğinizi" soran bir macOS sayfa stili iletişim kutusu

Evet'i tıklayın !

İstemi görmediyseniz veya köprüleme başlığınızı yanlışlıkla sildiyseniz .h, projenize yeni bir dosya ekleyin ve adlandırın <#YourProjectName#>-Bridging-Header.h.

Bazı durumlarda, özellikle Objective-C çerçeveleriyle çalışırken, Objective-C sınıfını açıkça eklemezsiniz ve Xcode bağlayıcıyı bulamaz. Bu durumda, .hyukarıda belirtildiği gibi bir dosya oluşturun , ardından yolunu hedefinizin proje ayarlarında aşağıdaki gibi bağladığınızdan emin olun:

Yukarıdaki paragrafı gösteren bir animasyon

Not:

Projenizi $(SRCROOT)makro kullanarak bağlamak en iyi yöntemdir, böylece projenizi taşırsanız veya uzak bir depo kullanan başkalarıyla çalışırsanız, yine de çalışır. $(SRCROOT).xcodeproj dosyanızı içeren dizin olarak düşünülebilir. Şöyle görünebilir:

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

Adım 3: Objective-C Üstbilgisi - .h ekle

Başka bir .hdosya ekleyin ve adlandırın CustomObject.h.

4. Adım: Objective-C Sınıfınızı oluşturun

İçinde CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

İçinde CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

- (void) someMethod {
    NSLog(@"SomeMethod Ran");
}

@end

Adım 5: Köprüleme Başlığına Sınıf Ekleme

İçinde YourProject-Bridging-Header.h:

#import "CustomObject.h"

6. Adım: Nesnenizi kullanın

İçinde SomeSwiftFile.swift:

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

Açıkça içe aktarmaya gerek yoktur; köprüleme başlığı bunun için.

Swift Sınıflarını Objective-C'de Kullanma

Adım 1: Yeni Swift Sınıfı Oluşturun

.swiftProjenize bir dosya ekleyin ve dosyayı adlandırın MySwiftObject.swift.

İçinde 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)"
    }
}

Adım 2: Swift Dosyalarını ObjC Sınıfına Aktarın

İçinde SomeRandomClass.m:

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

Dosya: <#YourProjectName#>-Swift.hgöremeseniz bile projenizde otomatik olarak oluşturulmuş olmalıdır.

3. Adım: Sınıfınızı kullanın

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

Notlar:

  1. Kod Tamamlama beklediğiniz gibi davranmıyorsa, RXcode'un Swift içeriğinden bazı Objective-C kodlarını bulmasına yardımcı olmak için hızlı bir derleme çalıştırmayı deneyin veya bunun tersi de geçerlidir.

  2. .swiftEski bir projeye dosya ekler ve hatayı alırsanız, Xcode'udyld: Library not loaded: @rpath/libswift_stdlib_core.dylib tamamen yeniden başlatmayı deneyin .

  3. Başlangıçta NSObjectObjective-C tarafından görülebilen saf Swift sınıflarını (torunları değil ) kullanmak mümkün olsa da @objc, bu artık mümkün değil. Şimdi, Objective-C'de görünür olmak için, Swift nesnesi ya uygun bir sınıf olmalıdır NSObjectProtocol(bunu yapmanın en kolay yolu miras almaktır NSObject) ya da gibi bir tamsayı türünde ham değeri olan bir enumişaret olmalıdır . Bu kısıtlamalar olmaksızın Swift 1.x kodunun bir örneğinin düzenleme geçmişini görüntüleyebilirsiniz .@objcInt@objc


5
@Objc ile yöntemlere açıklama eklemeniz önemlidir, aksi takdirde Swift yöntemleri Objective-C'den görünmez.
Tomáš Linhart

29
Haklısın. Yalnızca Kakao nesneleri kullanmıyorsanız belirtmeniz gerekir. Objective-C'de erişilebilir ve kullanılabilir olması için, Swift sınıfı Objective-C sınıfının soyundan olmalı veya @objc olarak işaretlenmelidir.
Tomáš Linhart


2
Ayrıca bkz: WWDC 2014 Oturum 406: Swift'i Objective-C ile Entegre Etme
Stuart M

6
Bir Objective C çerçevesini Swift'e içe aktarıyorsanız, Obj C çerçevesinin bağlı olduğu tüm çerçeveleri projenize aldığınızdan emin olun (Derleme Aşamaları -> İkili Kitaplıklarıyla Bağla), ardından bir önek başlık dosyasına # import ekleyin derleme ayarlarında projenize eklenmelidir (Önek Başlığı alanında). Bu, Swift içinde zaten kullanılmış olsalar bile, UIKit ve Foundation gibi çerçeveleri içerir. Bu beni saatlerce çalıştırdı ve kimse bu adımları belgelememiş gibi görünüyor.
user1021430

121

Apple'ın Swift'i Kakao ve Objective-C ile Kullanma kılavuzuna bakın . Bu kılavuz Swift'ten Objective-C ve C kodunun nasıl kullanılacağını ve tam tersi bir projenin dönüştürülmesi veya mevcut bir projede Objective-C / C ve Swift parçalarının nasıl karıştırılacağı ve eşleştirileceği hakkında önerilere sahiptir.

Derleyici otomatik olarak C işlevlerini ve Objective-C yöntemlerini çağırmak için Swift sözdizimini oluşturur. Belgelerde görüldüğü gibi, bu Hedef-C:

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

bu Swift koduna dönüşür:

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

Xcode ayrıca bu çeviriyi anında yapar - bir Swift dosyasını düzenlerken Hızlı Aç'ı kullanabilir ve bir Objective-C sınıf adı yazabilirsiniz ve sizi sınıf başlığının Swift-ified sürümüne götürür. (Bunu Swift dosyasındaki bir API sembolüne cmd tıklayarak da alabilirsiniz.) Ve iOS 8 ve OS Xv10.10 (Yosemite) geliştirici kitaplıklarındaki tüm API referans belgeleri Objective-C ve Swift'te görülebilir formlar (örn. UIView).


3
Apple belgesine Swift'in mevcut projeye nasıl entegre edileceğine doğrudan bağlantı : developer.apple.com/library/prerelease/ios/documentation/Swift/…
skywinder

Başlık dosyalarına neden ihtiyaç duyulduğunu ve bağlantı aşamasında nasıl kullanıldığını merak ediyorsanız, bu Manuel Swift'i
Honey

62

Swift projesinde Objective-C kodunu (bu durumda üçüncü tarafça sağlanan bir çerçeve) kullanmak için adım adım talimatlar:

  1. Dosya -> Yeni -> Yeni Dosya -> Objective-C Dosyası'nı seçerek Swift projenize herhangi bir Objective-C dosyası ekleyin . Kaydettikten sonra Xcode, köprüleme başlığı eklemek isteyip istemediğinizi soracaktır . ' Evet'i seçin . (kaynak: derrrick.com )Gif: Projeye boş dosya ekleme ve köprü üstbilgisi oluşturma

Basit adımlarla:

  1. Bir istem belirir ve ardından Tamam'ı tıklatın ... Görünmezse, aşağıdaki gibi manuel olarak oluştururuz ... iOS kaynağından bir başlık dosyası oluşturun ve ProjectName-Bridging-Header adını verin (örnek: Test -Bridging-Header) ve daha sonra Swift derleyici kodunda inşa ayarına gidin -> Objective-C köprü Objective-C köprü adını ekleyin .. (Test / Test-Bridging-Header.h). Evet, bu tamam.

  2. İsteğe bağlı olarak, eklediğiniz Objective-C dosyasını silin (yukarıdaki GIF görüntüsünde "herhangi bir şey" olarak adlandırılır). Artık buna ihtiyacınız yok.

  3. Köprüleme üstbilgi dosyasını açın - dosya adı [Projeniz] -Bridging-Header.h biçimindedir . Xcode tarafından sağlanan bir yorum içerir. Eklemek istediğiniz Objective-C dosyası için üçüncü taraf çerçevesi gibi bir kod satırı ekleyin . Örneğin, projenize Mixpanel eklemek için, köprüleme başlık dosyasına aşağıdaki kod satırını eklemeniz gerekir:

    #import "Mixpanel.h"
  4. Artık herhangi bir Swift dosyasında mevcut Objective-C kodunu Swift sözdiziminde kullanabilirsiniz (bu örnekte Mixpanel SDK yöntemlerini vb. Çağırabilirsiniz). Xcode'un Objective-C'yi Swift'e nasıl çevirdiğini öğrenmeniz gerekiyor. Apple'ın rehberi hızlı bir okuma. Ya da eksik bir özet için bu cevaba bakınız.

Mixpanel için örnek:

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

Bu kadar!

Not: Köprü oluşturma başlık dosyasını projenizden kaldırırsanız, Derleme Ayarları'na gidip "Swift Derleyici - Kod Üretimi" altındaki " Objective-C Köprüleme Başlığı " değerini kaldırdığınızdan emin olun .


39

Swift & Cocoapods'un güzel gönderisini okuyabilirsiniz . Temel olarak, bir köprüleme başlık dosyası oluşturmalı ve tüm Objective-C başlıklarını oraya koymalıyız. Ve sonra derleme ayarlarımızdan referans almamız gerekiyor. Bundan sonra Objective-C kodunu kullanabiliriz.

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

Ayrıca Apple'ın Swift'i Cocoa ve Objective-C ile kullanma belgesine de göz atın .



24

Buraya eklemek istediğim bir şey daha var:

@ Logan'ın cevabı için çok minnettarım. Bir köprü dosyası ve kurulumları oluşturmak için çok yardımcı olur.

Ancak tüm bu adımları uyguladıktan sonra hala Swift'te Objective-C sınıfı alamıyorum.

cocoapodsKütüphaneyi kullandım ve projeme entegre ettim. Hangi pod "pop".

Swift'te Objective-C bölmeleri kullanıyorsanız, Swift'e veya importsınıfları alamama şansınız olabilir .

Yapmanız gereken basit şey:

  1. <YOUR-PROJECT>-Bridging-HeaderDosyaya git ve
  2. Deyimi değiştirin #import <ObjC_Framework>için@import ObjC_Framework

Örneğin: (Pop kitaplığı)

değiştirmek

#import <pop/POP.h>

ile

@import pop;

Kullanım clang importsırasında #importçalışmıyor.


#İmport çalışmadığında clang içe aktarma özelliğini kullanın. ne? @İmport kullanmamız gerektiğini söylemedi mi ?!
Bal

22

Belgelerden alıntı :

Modül olarak erişilebilen herhangi bir Objective-C çerçevesi (veya C kütüphanesi) doğrudan Swift'e aktarılabilir. Bu, Foundation, UIKit ve SpriteKit gibi tüm Objective-C sistem çerçevelerini ve sistemle birlikte verilen ortak C kütüphanelerini içerir. Örneğin, Foundation'ı içe aktarmak için bu içe aktarma ifadesini üzerinde çalıştığınız Swift dosyasının üstüne eklemeniz yeterlidir:

import Foundation

Bu içe aktarma, NSDate, NSURL, NSMutableData ve tüm yöntemlerini, özelliklerini ve kategorilerini içeren tüm Temel API'leri Swift'te doğrudan kullanılabilir hale getirir.


12

Swift bir Objective-C kütüphanesi eklemek için çalışıyor kim için sadece bir not: eklemek gerekir -ObjC içinde Yapı Ayarlar -> Bağlama -> Diğer Bağlayıcı Bayraklar .


Neden? Lütfen bu bayrağın ne yaptığı ve neden eklenmesi gerektiği hakkında bilgi ekleyin.
Johan Karlsson

9

Bir Köprüleme üstbilgisi oluşturduktan sonra, Yapı Ayarı => "Objective-C Köprüleme Üstbilgisi" araması yapın.

Hemen aşağıda "" Objective-C Oluşturulmuş Arabirim Üstbilgi Adı "dosyası bulunur.

Bu dosyayı görünüm denetleyicinize aktarın.

Örnek: Benim durumumda: "Dauble-Swift.h"

eEter görüntü açıklaması burada


5

Yeni dosya menüsünü tıklayın ve dosya seçme dilini seçin Amaç. O zaman otomatik olarak bir sınıf adını tanımlamak için kullanılan bir "Objective-C Köprüleme Başlığı" dosyası oluşturur.

"Swift Derleyici - Kod Üretimi" altında "Objective-C Bridging Header".


3
  1. NewFile -> Kaynak -> başlık dosyasından bir .h dosyası oluşturma
  2. Daha sonra Dosyanızın adını kaydedin Your_Target_Name-Bridging-Header.h Buradaki insanlar proje adlarını alarak genel bir hata alırlar, ancak her ikisi de farklıysa, genellikle aynı ise, Projenin Hedefinin adı olmalıdır.
  3. Ardından, Objective-C Bridging Header bayrağını oluşturmak ve yeni oluşturulan köprüleme dosyanızın adresini oluşturmak için, ayarları sağ tıklayın -> bulucuda göster -> dosyayı metin alanına sürükleyin, ardından adres doldurmak.
  4. # İmport Your_Objective-C_file.h kullanma
  5. Swift dosyasında ObjC dosyasına ancak hızlı dilde erişebilirsiniz.


3

Xcode 10.1'deki Swift 4.2.1 projesinde Objective-C dosyasını kolayca ekleyebilirsiniz. Objective-C dosyasını Swift projesine bağlamak için aşağıdaki adımları izleyin.

Adım_01: Swift dilini kullanarak yeni Xcode projesi oluşturun:

File> New> Project> objc.

Adım_02: Swift projesine yeni Objective-C dosyası ekleyin:

File> New> File...> macOS> Objective-C File.

Adım_03: Swift projesine ilk kez yeni bir Objective-C dosyası eklerseniz, Xcode size şunu sorar:

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

resim açıklamasını buraya girin

Adım_04: Seçeneği seçin:

Create Bridging Header.

Adım_05: Bir isim ile karşılık gelen bir dosya oluşturulacaktır:

Objc-Bridging-Header.h.

resim açıklamasını buraya girin

Adım_06: Şimdi, köprü üstbilgisinde Bridge dosya yolunu ayarlamanız gerekiyor. Proje Gezgini'nde adında projeye tıklayın objcve ardından şunları seçin:

Build Settings> Objective-C Bridging Header> Objc-Bridging-Header.h.

Adım_07: Objc-Bridging-Header.hBir dosya yolu oluşturmak için öğenizi bu kutuya sürükleyip bırakın .

resim açıklamasını buraya girin

Adım_08: Dosyanızı açın Objc-Bridging-Header.hve Swift dosyanızda kullanmak istediğiniz Objective-C dosyasını içe aktarın.

#import "SpecialObjcFile.m"

İşte içeriği SpecialObjcFile.m:

#import <Foundation/Foundation.h>

@interface Person: NSObject {
@public
    bool busy;
}
@property
    bool busy;
@end

Adım_09: Şimdi Swift dosyanızda bir Objective-C sınıfı kullanabilirsiniz:

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

resim açıklamasını buraya girin resim açıklamasını buraya girin


1

Logans cevabı , en son Swift 5derleyici hatası verir dışında iyi çalışır . İşte Swift 5 üzerinde çalışan insanlar için düzeltme.

Hızlı 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

Hızlı tüketici, Objective-C üreticisi

  1. Üstbilgi .hve Uygulama .mdosyaları ekleme - Cocoa sınıf dosyası (Objective-C)
    ÖrneğinMyFileName

  2. başlığını köprüleme yapılandırmak
    gördüğünüzde Would you like to configure an Objective-C bridging headertıklayın - Evet

    • <target_name>-Bridging-Header.h otomatik olarak oluşturulacak
    • Derleme Ayarları -> Objective-C Köprüleme Başlığı
  3. Köprü-Soket Add Class
    In <target_name>-Bridging-Header.hbir satır ekleyin#import "<MyFileName>.h"

PS Swift projesine mevcut Objective-C dosyalarını eklemeniz Bridging-Header.hgerekiyorsa önceden ekleyin

Objective-C tüketici, Swift yapımcı

  1. A ekleyin <MyFileName>.swiftve genişletinNSObject

  2. Swift Dosyalarını ObjC Sınıfına Aktar Objective-C dosyanıza
    ekleyin#import "<#YourProjectName#>-Swift.h"

  3. Genel Swift kodunu işaretle [@objc ve @objcMembers]


0

Apple bu dokümanda resmi rehber sağladı: nasıl-nasıl-çağrılır-amaç-c-kodu-hızlı

İlgili bölüm:

Bir dizi Objective-C dosyasını aynı uygulama hedefi içindeki Swift koduna içe aktarmak için, bu dosyaları Swift'e göstermek için bir Objective-C köprüleme başlık dosyasına güvenirsiniz . Xcode, varolan bir Objective-C uygulamasına bir Swift dosyası veya mevcut bir Swift uygulamasına bir Objective-C dosyası eklediğinizde bu üstbilgiyi oluşturmayı önerir.

Kabul ederseniz, Xcode köprüleme üstbilgisi dosyasını oluşturduğunuz dosyayla birlikte oluşturur ve bunu ürün modülü adınızı ve ardından "-Bridging-Header.h" kullanarak adlandırır. Alternatif olarak, Dosya> Yeni> Dosya> [işletim sistemi]> Kaynak> Başlık Dosyası'nı seçerek köprü üstbilgisini kendiniz oluşturabilirsiniz.

Objective-C kodunuzu Swift kodunuza göstermek için köprüleme başlığını düzenleyin:

  1. Objective-C köprüleme başlığınızda, Swift'e göstermek istediğiniz her Objective-C üstbilgisini içe aktarın .
  2. Derleme Ayarları'nda, Swift Derleyici - Kod Üretimi'nde, Objective-C Köprüleme Üstbilgisi derleme ayarının köprüleme üstbilgisi dosyasına giden bir yol olduğundan emin olun. Yol, Oluşturma Ayarları'nda Info.plist yolunuzun belirtilmesine benzer şekilde projenize göreli olmalıdır. Çoğu durumda, bu ayarı değiştirmeniz gerekmez.

Köprü üstbilgisinde listelenen tüm genel Objective-C başlıkları Swift tarafından görülebilir.


0

Objektif-c objektif-c kullanmak için iki yönlü yaklaşım

1

  1. Xcode Project'te bridge-header.h dosyası oluşturma
  2. köprü başlık dosyasında .h dosyasını içe aktar
  3. Derleme ayarlarında köprü Başlığı yolunu ayarlayın.
  4. Projeyi Temizle

2

  1. Projede objektif-c dosyaları oluşturun (sizin için Oluşturma Ayarları'nda yolu otomatik olarak ayarlar)
  2. köprü başlık dosyasında .h dosyasını içe aktar

Şimdi gitmek güzel Teşekkürler

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.