Як зателефонувати коду Objective-C від Swift?


974

Як у Swift, як один виклик коду Objective-C?

Apple зазначила, що вони можуть співіснувати в одній програмі, але чи означає це, що технічно можна повторно використовувати старі класи, створені в Objective-C, будуючи при цьому нові класи в Swift?


13
Дивіться посібник Apple щодо використання Swift з какао та Objective-C .
рикстер


10
Цікаво, що це питання отримує стільки відгуків та щедрості. Коли я вперше побачив це, я просто подумав: RTFM. Що стосується цього, то насправді немає досліджень, оскільки наразі існує лише два-три ресурси, які офіційно документують Свіфт, і один з них повністю присвячений саме цьому (і пов'язаний з цим у першому коментарі).
Аналоговий файл

6
@EvolGate: саме того, чого не вистачає в Objective C, що заважає йому бути незалежною від платформи мовою? Мова та бібліотеки стандартних мов є відкритим кодом. Ви можете використовувати Objective C для Windows, Os X, Linux, BSD, Solaris та будь-якої іншої платформи, підтримуваної або GCC, або LLVM. Ви можете легко перенести Objective C на будь-яку платформу з гідним компілятором C, навіть якщо він не підтримується ні GCC, ні LLVM. Я не бачу, як це могло бути більш незалежним від цієї платформи.
Аналоговий файл

2
@DavidMulder: Чи потрібен розділ "Розум"?
франк

Відповіді:


1393

Використання класів Objective-C у Swift

Якщо у вас є існуючий клас, який ви хочете використовувати, виконайте крок 2 та перейдіть до кроку 5 . (У деяких випадках мені довелося додати явний текст #import <Foundation/Foundation.hдо старого файлу Objective-C.)

Крок 1: Додати реалізацію Objective-C - .m

Додайте .mфайл до свого класу та назвіть його CustomObject.m.

Крок 2: Додайте мостиковий заголовок

Додаючи .mфайл, ви, швидше за все, отримаєте запит, який виглядає приблизно так:

Діалогове вікно аркуша macOS від Xcode із запитанням, чи не хочете ви "налаштувати мостиковий заголовок" Objective-C "

Натисніть Так !

Якщо ви не побачили підказку або випадково видалили мостиковий заголовок, додайте новий .hфайл до свого проекту та назвіть його <#YourProjectName#>-Bridging-Header.h.

У деяких ситуаціях, особливо під час роботи з рамками Objective-C, ви не додаєте явно клас Objective-C і Xcode не може знайти лінкер. У цьому випадку створіть .hфайл, названий вище, і переконайтеся, що ви пов’язали його шлях у налаштуваннях проекту вашої цілі так:

Анімація, що демонструє вищевказаний абзац

Примітка:

Найкраще зв'язати проект за допомогою $(SRCROOT)макросу, щоб, якщо ви перемістили проект або працювали над ним з іншими, використовуючи віддалений сховище, він все одно буде працювати. $(SRCROOT)можна розглядати як каталог, що містить ваш .xcodeproj файл. Це може виглядати приблизно так:

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

Крок 3: Додайте заголовок Objective-C - .h

Додайте інший .hфайл і назвіть його CustomObject.h.

Крок 4: Створіть свій клас Objective-C

В CustomObject.h

#import <Foundation/Foundation.h>

@interface CustomObject : NSObject

@property (strong, nonatomic) id someProperty;

- (void) someMethod;

@end

В CustomObject.m

#import "CustomObject.h"

@implementation CustomObject 

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

@end

Крок 5: Додайте клас до Bridging-Header

В YourProject-Bridging-Header.h:

#import "CustomObject.h"

Крок 6: Використовуйте свій об’єкт

В SomeSwiftFile.swift:

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

Не потрібно явно імпортувати; ось для чого призначений мостовий заголовок.

Використання класів Swift в Objective-C

Крок 1: Створіть новий клас Swift

Додайте .swiftфайл до свого проекту та назвіть його MySwiftObject.swift.

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

Крок 2: Імпорт швидких файлів у клас ObjC

В SomeRandomClass.m:

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

Файл: <#YourProjectName#>-Swift.hвже має бути створено автоматично у вашому проекті, навіть якщо ви не можете його побачити.

Крок 3: Використовуйте свій клас

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

Примітки:

  1. Якщо завершення коду не веде себе так, як ви очікували, спробуйте запустити швидку збірку, Rщоб допомогти Xcode знайти частину коду Objective-C з контексту Swift і навпаки.

  2. Якщо ви додали .swiftфайл до старого проекту і отримуєте помилку dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, спробуйте повністю перезапустити Xcode .

  3. Хоча спочатку можна було використовувати чисті класи Swift (Не нащадки NSObject), які видимі для Objective-C за допомогою @objcпрефікса, це вже неможливо. Тепер, щоб бути видимим в Objective-C, об'єкт Swift повинен бути або класом, відповідним NSObjectProtocol(найпростіший спосіб зробити це успадковувати NSObject), або бути enumпозначеним знаком @objcнеобробленого типу якогось цілого типу типу Int. Ви можете переглянути історію редагування для прикладу коду Swift 1.x, використовуючи @objcбез цих обмежень.


5
Важливо, що вам потрібно коментувати методи за допомогою методів @objc, або Swift не буде видно з Objective-C.
Томаш Лінхарт

29
Ти правий. Вказувати його потрібно лише в тому випадку, якщо ви не використовуєте об'єкти какао. Щоб бути доступним і корисним у Objective-C, клас Swift повинен бути нащадком класу Objective-C або він повинен бути позначений @objc.
Томаш Лінхарт

2
@MarkusRautopuro - Отримав це звідси: developer.apple.com/library/prerelease/ios/documentation/Swift/… "
Логан

2
Дивіться також: WWDC 2014 Session 406: Інтеграція Swift з Objective-C
Stuart M

6
Якщо ви імпортуєте рамку Objective C в Swift, переконайтесь, що імпортуєте всі рамки, від яких залежить рамка Obj C, у ваш проект (у фазах збірки -> Посилання бінарних із бібліотеками), а потім додайте # імпорт для них до файлу заголовка префікса, який повинні бути додані до вашого проекту в налаштуваннях збірки (у полі заголовка префікса). Сюди входять рамки, такі як UIKit та Foundation, навіть якщо вони вже використовуються в Swift. Це спалахнуло мене годинами, і, схоже, ніхто не задокументував ці кроки.
користувач1021430

121

Дивіться посібник Apple щодо використання Swift з какао та Objective-C . У цьому посібнику висвітлено, як використовувати код Objective-C та C від Swift, і навпаки, а також рекомендації щодо перетворення проекту або змішування та співпадіння частин Objective-C / C та Swift у існуючий проект.

Компілятор автоматично генерує синтаксис Swift для виклику функцій C та методів Objective-C. Як видно з документації, цей Ціль-C:

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

перетворюється на цей код Swift:

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

Xcode також робить цей переклад на льоту - ви можете скористатись функцією Open Quick під час редагування файлу Swift та ввести ім'я класу Objective-C, і він перенесе вас до Swift-версії заголовка класу. (Ви також можете отримати це, натиснувши cmd на символ API у файлі Swift.) А вся довідкова документація API у бібліотеках розробників iOS 8 та OS X v10.10 (Yosemite) видно як у Objective-C, так і у Swift форми (наприклад UIView).


3
Пряме посилання на документацію Apple, як інтегрувати Swift у існуючий проект: developer.apple.com/library/prerelease/ios/documentation/Swift/…
skywinder

Якщо нас цікавить, для чого потрібні файли заголовків та як він використовується під час фази зв’язування, переконайтеся, що ви прочитали цей посібник Swift: Розуміння
Honey

62

Ось покрокові вказівки щодо використання коду Objective-C (у даному випадку - рамки, наданої третьою стороною) у проекті Swift:

  1. Додайте будь-який файл Objective-C до свого проекту Swift , вибравши Файл -> Новий -> Новий файл -> Файл Objective-C. Після збереження Xcode запитає, чи потрібно додати мостиковий заголовок . Виберіть " Так ". (джерело: derrrick.com )Gif: додавання порожнього файлу до проекту та створення мостового заголовка

Простими кроками:

  1. З'являється підказка, а потім натисніть кнопку ОК ... Якщо вона не з'являється, ми створюємо її вручну, як у наступному ... Створіть один заголовок з джерела iOS та дайте ім'я ProjectName-Bridging-Header (приклад: Тест -Bridging-Header), а потім перейдіть до створення параметра в коді компілятора Swift -> Bridge-Objective-C додайте назву моста Objective-C .. (Test / Test-Bridging-Header.h). Так, це повно.

  2. За бажанням видаліть доданий вами файл Objective-C (з ім'ям "що-небудь" на GIF-зображенні вище). Вам це вже не потрібно.

  3. Відкрийте файл мостового заголовка - ім'я файлу має форму [YourProject] -Bridging-Header.h . Він включає коментар, наданий Xcode. Додайте рядок коду до файлу Objective-C, який ви хочете включити , наприклад, стороннього фрейму. Наприклад, щоб додати Mixpanel до свого проекту, вам потрібно буде додати наступний рядок коду до файлу мосту, який знаходиться в мості:

    #import "Mixpanel.h"
  4. Тепер у будь-якому файлі Swift ви можете використовувати наявний код Objective-C у синтаксисі Swift (у разі цього прикладу, і ви можете зателефонувати за методом Mixpanel SDK тощо). Потрібно ознайомитись із тим, як Xcode перекладає Objective-C на Swift. Посібник Apple - це швидке читання. Або дивіться цю відповідь для неповного резюме.

Приклад для Mixpanel:

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

Це воно!

Примітка: Якщо ви видалите файл мостового заголовка зі свого проекту , не забудьте зайти в «Налаштування збірки» та вилучити значення для « Об’єктивного заголовка об'єктива-C » у розділі «Швидкий компілятор - генерація коду».


39

Ви можете прочитати хороший пост Swift & Cocoapods . В основному нам потрібно створити містковий файл заголовка і помістити туди всі заголовки Objective-C. І тоді нам потрібно посилатися на це з наших параметрів збірки. Після цього ми можемо скористатися кодом 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)
  })

Також ознайомтеся з документом Apple, що використовує Swift з какао та Objective-C .


25

Я написав простий проект Xcode 6, який показує, як змішувати код C ++, Objective-C і Swift:

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

Зокрема, у прикладі називається функція Objective-C та C ++ від Swift .

Ключовим моментом є створення спільного заголовка Project-Bridging-Header.h та розміщення там заголовків Objective-C.

Завантажте проект як повний приклад.


24

Ще одне, що я хотів би додати тут:

Я дуже вдячний за відповідь @ Логана. Це дуже допомагає створити міст-файл та налаштування.

Але виконуючи всі ці кроки, я все ще не отримую клас Objective-C у Swift.

Я використав cocoapodsбібліотеку та інтегрував її у свій проект. Який є pod "pop".

Отже, якщо ви використовуєте стручки Objective-C у Swift, то, можливо, ви не зможете потрапити або importкласи в Swift.

Просте, що вам потрібно зробити:

  1. Перейдіть до <YOUR-PROJECT>-Bridging-Headerфайлу та
  2. Замініть заяву #import <ObjC_Framework>на@import ObjC_Framework

Наприклад: (Поп-бібліотека)

Замініть

#import <pop/POP.h>

з

@import pop;

Використовуйте, clang importколи #importне працює.


Використовуйте імпорт клангів, коли #import не працює. що? Чи не просто сказали, що ми повинні використовувати @import ?!
Мед

22

Цитата з документації :

Будь-який фреймворк Objective-C (або бібліотека C), доступний як модуль, можна імпортувати безпосередньо в Swift. Сюди входять усі системні системи Objective-C - такі як Foundation, UIKit та SpriteKit - а також загальні бібліотеки C, що постачаються разом із системою. Наприклад, щоб імпортувати Foundation, просто додайте цю заяву про імпорт у верхню частину файлу Swift, в якому ви працюєте:

import Foundation

Цей імпорт робить усі API API - включаючи NSDate, NSURL, NSMutableData та всі їх методи, властивості та категорії - безпосередньо доступними в Swift.


12

Лише примітка для того, хто намагається додати бібліотеку Objective-C до Swift: Вам слід додати -ObjC у Налаштуваннях збірки -> Зв'язування -> Інші прапорці Linker .


Чому? Будь ласка, додайте інформацію про те, що робить цей прапор і чому його слід додавати.
Йохан Карлссон

9

Після створення мостового заголовка перейдіть до Налаштування збірки => Пошук "Об'єктивного заголовка мостів".

Внизу ви знайдете файл "" Створений об'єктив-C ім'я заголовка інтерфейсу ".

Імпортуйте цей файл у контролер перегляду.

Приклад: У моєму випадку: "Dauble-Swift.h"

Опис зображення eEter тут


5

Клацніть на меню Новий файл і виберіть мову вибору файлу Ціль. У той час він автоматично генерує файл "Об'єктивний-C Bridging Header", який використовується для визначення деякої назви класу.

"Об’єктивний заголовок" Objective-C "під" Швидким компілятором - генерація коду ".


3
  1. Створіть .h файл із NewFile -> Source -> file header
  2. Потім збережіть ім'я файлу Your_Target_Name-Bridging-Header.h Тут люди отримують поширену помилку, приймаючи назву свого проекту, але це має бути ім'я цілі Проекту, якщо вони обоє різні, як правило, вони однакові.
  3. Потім у налаштуваннях збирання знайдіть прапор об'єктивного моста Objective-C та вставте адресу новоствореного мостового файлу, ви можете це зробити правою кнопкою миші на файл -> показати в пошуку -> перетягніть файл у текстову область, тоді адреса буде бути заселеним.
  4. Використовуючи #import Your_Objective-C_file.h
  5. У файлі swift ви можете отримати доступ до файлу ObjC, але лише швидкою мовою.


3

У проекті Swift 4.2.1 в Xcode 10.1 ви можете легко додати файл Objective-C. Виконайте наведені нижче дії, щоб перенести файл Objective-C до проекту Swift.

Step_01: Створіть новий проект Xcode за допомогою мови Swift:

File> New> Project> objc.

Step_02: До проекту Swift додайте новий файл Objective-C:

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

Step_03: Якщо ви додасте новий файл Objective-C до проекту Swift в перший раз, Xcode запитує вас:

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

введіть тут опис зображення

Крок_04: Виберіть параметр:

Create Bridging Header.

Step_05: Відповідний файл буде створений з ім'ям:

Objc-Bridging-Header.h.

введіть тут опис зображення

Step_06: Тепер вам потрібно встановити шлях до файлу Bridge у заголовку мосту. У Навігаторі проектів натисніть на проект з ім'ям objcта виберіть:

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

Step_07: перетягніть і впустіть Objc-Bridging-Header.hу це поле, щоб створити шлях до файлу.

введіть тут опис зображення

Step_08: Відкрийте Objc-Bridging-Header.hфайл та імпортуйте файл Objective-C, який ви хочете використовувати у своєму файлі Swift.

#import "SpecialObjcFile.m"

Ось зміст SpecialObjcFile.m:

#import <Foundation/Foundation.h>

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

Step_09: Тепер у вашому файлі Swift ви можете використовувати клас Objective-C:

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

введіть тут опис зображення введіть тут опис зображення


1

Відповідь Logans працює чудово, за винятком того, що останнім часом Swift 5це дає деяку помилку компілятора. Ось виправлення для людей, які працюють на Swift 5.

Швидкий 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

Швидкий споживач, виробник Objective-C

  1. Додати заголовок .hі реалізація .mфайлів - файл класу какао (Objective-C) ,
    наприкладMyFileName

  2. налаштування мостового заголовка
    Коли ви бачите Would you like to configure an Objective-C bridging headerклацання - Так

    • <target_name>-Bridging-Header.h буде генеровано автоматично
    • Налаштування побудови -> Об'єктивний заголовок мосту-C
  3. Додати клас в Bridging-Header
    In <target_name>-Bridging-Header.hДодати рядок#import "<MyFileName>.h"

PS Якщо вам слід додати наявні файли Objective-C до проекту Swift, додайте Bridging-Header.hзаздалегідь

Споживач-об'єктив-C, виробник Swift

  1. Додайте а <MyFileName>.swiftта розширюєNSObject

  2. Імпорт швидких файлів до класу ObjC
    Додайте #import "<#YourProjectName#>-Swift.h"у файл Objective-C

  3. Позначити публічний код Swift [@objc та @objcMembers]


0

Apple запропонувала офіційний посібник у цьому документі: як зателефонувати-об'єктивно-c-код-від-швидкого

Ось відповідна частина:

Щоб імпортувати набір файлів Objective-C в код Swift в межах однієї цілі програми, ви покладаєтесь на файл заголовка моста Objective-C, щоб відкрити ці файли Swift . Xcode пропонує створити цей заголовок, коли ви додасте файл Swift до вже наявного додатку Objective-C або файл Objective-C до вже наявного додатку Swift.

Якщо ви приймаєте, Xcode створює файл мостового заголовка разом з файлом, який ви створили, і називає його, використовуючи назву модуля продукту, а потім "-Bridging-Header.h". Крім того, ви можете створити мостиковий заголовок самостійно, вибравши Файл> Створити> Файл> [операційна система]> Джерело> Файл заголовка

Відредагуйте мостиковий заголовок, щоб виставити код Objective-C своєму коду Swift:

  1. У своєму мостовому заголовку Objective-C імпортуйте кожен заголовок Objective-C у Swift .
  2. У Налаштуваннях збірки, у Swift Compiler - Генерація коду, переконайтесь, що в налаштуваннях об'єднання мостових заголовків Objective-C є шлях до файлу моста для заголовка. Шлях повинен відповідати вашому проекту, подібно до того, як вказано ваш шлях Info.plist у налаштуваннях збірки. У більшості випадків вам не потрібно буде змінювати це налаштування.

Будь-які загальнодоступні заголовки Objective-C, перелічені в мостовому заголовку, бачать Swift.


0

Двосторонній підхід до використання aim-c aim-c

1

  1. Створіть файл bridge-header.h в Xcode Project
  2. імпортувати .h файл у файл Bridge-Header
  3. Встановіть шлях мосту-заголовка в налаштуваннях збірки.
  4. Очистіть проект

2

  1. Створюйте файли target-c у проекті (він автоматично встановлює шлях у Налаштуваннях збірки для вас)
  2. імпортувати .h файл у файл Bridge-Header

Тепер добре йти Спасибі

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.