Как вызвать код Objective-C из Swift

864

На новом языке Swift от Apple, как вы вызываете Objective-C код?

Apple упомянула, что они могут сосуществовать в одном приложении, но означает ли это, что можно технически повторно использовать старые классы, сделанные в Objective-C, при создании новых классов в Swift?

Рассуждение

Objective-C - независимый от платформы язык, тогда как Swift зависит от платформы. Таким образом, писать не-платформенно-зависимый код (библиотеки бизнес-логики) в Swift не было бы разумным. Однако писать код, зависящий от платформы, в нем (например, связанный с интерфейсом) было бы прекрасно. Не сказать, что это будет хорошая идея, однако это определенно интерес.

  • 12
    См. Руководство Apple по использованию Swift с какао и Objective-C .
  • 2
    developer.apple.com/library/prerelease/ios/documentation/Swift/...
Показать ещё 9 комментариев
Теги:

17 ответов

1269
Лучший ответ

Использование классов Objective C в Swift

** Если у вас есть существующий класс, который вы хотели бы использовать, выполните шаг 2, а затем перейдите к шагу 5. (В некоторых случаях мне пришлось добавить явный #import <Foundation/Foundation.h в более старый файл Objective-C.) **

Шаг 1: Добавить реализацию Objective-C -.m

Добавьте файл .m к своему классу и назовите его CustomObject.m.

Шаг 2: Добавьте заголовок моста

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

Изображение 1553

Нажмите ДА !

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

В некоторых ситуациях, особенно при работе со средами Objective C, вы не добавляете класс Objective C явно, и XCode не может найти компоновщик. В этом случае создайте файл .h именем, указанным выше, а затем убедитесь, что вы связали его путь в настройках целевого проекта следующим образом:

Изображение 1554

Заметка

Рекомендуется связывать ваш проект с помощью макроса $(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 = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
println(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()

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

Использование Swift-классов в Objective-C

Шаг 1: Создайте новый класс Swift

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

В MySwiftObject.swift:

import Foundation

class MySwiftObject : NSObject {

    var someProperty: AnyObject = "Some Initializer Val"

    init() {}

    func someFunction(someArg:AnyObject) -> String {
        var returnVal = "You sent me \(someArg)"
        return returnVal
    }   
}

Шаг 2: Импорт файлов Swift в класс 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);

// original
NSString * retString = [myOb someFunction:@"Arg"];
// xcode10 expands the external arg here
NSString * retString = [myOb someFunctionWithSomeArg:@"Arg"];|

NSLog(@"RetString: %@", retString);

Замечания:

1. CodeCompletion вел себя не так точно, как хотелось бы. В моей системе запуск быстрой сборки с помощью "cmd + r", казалось, помог Swift найти некоторый код Objective-C и наоборот.

2. Если вы добавляете файл .swift в более старый проект и получаете сообщение об ошибке: dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib, попробуйте полностью перезапустить Xcode.

3. Хотя изначально было возможно использовать чистые классы Swift в Objective-C с помощью префикса @objc, после Swift 2.0 это уже невозможно. Смотрите историю изменений для оригинального объяснения. Если эта функция будет включена в будущих версиях Swift, ответ будет обновлен соответствующим образом.

  • 5
    Важно, что вам нужно аннотировать методы с помощью методов @objc или Swift, которые не будут видны из Objective-C.
  • 0
    @ TomášLinhart - я не нашел в этом необходимости, есть ли конкретный вариант использования, на который вы ссылаетесь?
Показать ещё 25 комментариев
109

См. руководство Apple в Использование Swift с Cocoa и Objective-C. В этом руководстве описывается использование Objective-C и кода C из Swift и наоборот, а также рекомендации по преобразованию проекта или его смешению и соответствия Objective-C/C и деталям Swift в существующем проекте.

Компилятор автоматически генерирует синтаксис Swift для вызова функций C и методов Objective-C. Как видно из документации, этот Objective-C:

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

превращается в этот код Swift:

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

Xcode также выполняет этот перевод "на лету" - вы можете использовать "Открыть быстро" при редактировании файла Swift и ввести имя класса Objective-C, и оно перенесет вас в версию заголовка класса Swift. (Вы также можете получить это, нажав cmd на символ API в файле Swift.) И вся справочная документация API в iOS 8 и OS X v10.10 (Yosemite) библиотеки разработчиков видны как в формах Objective-C, так и в Swift (например, UIView).

54

Ниже приведены пошаговые инструкции по использованию кода Objective-C (в данном случае, рамки, предоставленной сторонней стороной) в проекте Swift:

В простых шагах:

  • Появится приглашение, а затем нажмите OK... Если он не появится, мы создадим его вручную, как в следующем... Создайте один заголовочный файл из источника iOS и укажите имя ProjectName-Bridging -Header (пример: Test-Bridging-Header), а затем перейдите к настройке сборки в коде компилятора Swift → Objective-C bridge add Objective-C имя моста.. (Test/Test-Bridging-Header.h). Да, это завершено.

  • Необязательно удалите добавленный Objective-C файл (названный "ничего" в изображении GIF выше). Вам это больше не нужно.

  • Откройте файл заголовка моста. Имя файла имеет вид [YourProject] -Bridging-Header.h. Он содержит комментарий, предоставленный Xcode. Добавьте строку кода для файла Objective-C, который вы хотите включить, например, стороннюю структуру. Например, чтобы добавить Mixpanel в ваш проект, вам нужно будет добавить следующую строку кода в заголовочный файл моста:

    #import "Mixpanel.h"
  • Теперь в любом файле 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
}

Что это!

Примечание. Если вы удаляете заголовочный файл моста из вашего проекта, обязательно зайдите в "Настройки сборки" и удалите значение для " Objective-C" Мостовой заголовок "в" Быстрый компилятор - генерация кода".

35

Вы можете прочитать хороший пост 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 с Cocoa и Objective-C.

23

Я написал простой проект Xcode 6, который показывает, как смешивать С++, Objective-C и код Swift:

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

В частности, пример вызывает функцию Objective-C и С++ из Swift.

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

Пожалуйста, загрузите проект в качестве полного примера.

19

Цитата из documentation:

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

import Foundation

Этот импорт делает все базовые API-интерфейсы, включая NSDate, NSURL, NSMutableData и все их методы, свойства и категорий, доступных непосредственно в Swift.

18

Еще одна вещь, которую я хотел бы добавить здесь:

Я очень благодарен за ответ @Logan. Он очень помогает создавать файл моста и настройки.

Но после выполнения всех этих шагов я все еще не получаю класс Objective-C в Swift.

Я использовал библиотеку cocoapods и интегрировал ее в свой проект. Что такое pod "pop".

Поэтому, если вы используете объекты Objective-C в Swift, тогда может возникнуть вероятность того, что вы не сможете получить или import классы в Swift.

Простая вещь, которую вы должны сделать, это:

  1. Перейдите в <YOUR-PROJECT>-Bridging-Header file и
  2. Заменить оператор #import <ObjC_Framework> на @import ObjC_Framework

Например: (поп-библиотека)

замещать

#import <pop/POP.h>

с

@import pop;

Использовать clang import когда #import не работает.

  • 0
    Используйте импорт clang, когда #import не работает. что? Разве не сказали, что мы должны использовать @import ?!
10

Просто обратите внимание на тех, кто пытается добавить библиотеку Objective-C в Swift: вы должны добавить -ObjC в настройках сборки → Связывание → Другие флаги компоновщика.

  • 0
    Зачем? Пожалуйста, добавьте информацию о том, что делает этот флаг и почему он должен быть добавлен.
6

После того, как вы создали заголовок Bridging, перейдите в Build Setting => Search для "Objective-C Bridging Header".

Чуть ниже вы найдете файл "" Имя заголовка сгенерированного интерфейса Objective-C ".

Импортируйте этот файл в свой контроллер представления.

Пример: в моем случае: "Dauble-Swift.h"

Изображение 1555

4

Нажмите меню "Новый файл" и выберите язык выбора файла Цель. В это время он автоматически генерирует файл Objective-C Bridging Header ", который используется для определения некоторого имени класса.

"Objective-C Мостовой заголовок" в разделе "Быстрый компилятор - генерация кода".

3
  • Создайте файл .h из файла NewFile → Source → header
  • Затем сохраните имя файла Your_Target_Name-Bridging-Header.h. Люди здесь часто ошибаются, беря имя своего проекта, но это должно быть имя проекта, если в обоих случаях разные, как правило, они одинаковы.
  • Затем в настройках сборки найдите Objective-C флаг заголовка Bridging Header и поместите адрес вашего вновь созданного файла моста, вы можете сделать его правой кнопкой мыши по файлу → показать в finder → перетащить файл в текстовую область, затем адрес будет заполнен.
  • Использование #import Your_Objective-C_file.h
  • В быстром файле вы можете получить доступ к файлу ObjC, но только по быстрому языку.
2

Изображение 1556 Я добавил проект на github, который включает небольшой образец для вызова объектного кода c из swift.

Вызов класса ObjectiveC из swift

  • 0
    ПРИМЕЧАНИЕ: - Когда вы создаете класс Objc в проекте swift, xcode запрашивает автоматическое соединение класса. Не волнуйтесь :)
2

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

import Foundation

Этот импорт включает все базовые API-интерфейсы, включая NSDate, NSURL, NSMutableData и все их методы, свойства и категории, непосредственно доступные в Swift.

Я взял это из документации Apple.

1

В проекте 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?

Изображение 1557

Step_04: Выберите параметр:

Create Bridging Header.

Step_05: Будет создан соответствующий файл с именем:

Objc-Bridging-Header.h.

Изображение 1558

Шаг_06: Теперь вам нужно установить путь к файлу Bridge в заголовке моста. В Project Navigator нажмите проект с именем objc а затем выберите:

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

Step_07: Перетащите свой Objc-Bridging-Header.h в это поле, чтобы создать путь к файлу.

Изображение 1559

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

Изображение 1560 Изображение 1561

  • 0
    xcode 9.4 не поддерживает swift 4.2
0

В этом документе Apple предоставила официальное руководство: как-звонить-цель-c-code-from-swift

Вот соответствующая часть:

Чтобы импортировать набор файлов 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 - Generation code убедитесь, что параметр сборки Objective-C Bridging Header имеет путь к файлу заголовка моста. Путь должен быть относительно вашего проекта, аналогично тому, как ваш путь Info.plist указан в настройках сборки. В большинстве случаев вам не нужно изменять этот параметр.

Все общедоступные заголовки Objective-C, перечисленные в заголовке моста, видны Swift.

0

Двусторонний подход к объективному объекту-c

1

1. Create bridge-header.h file in Xcode Project
2. import .h file in bridge-Header file
3. Set path of bridge-Header in Build settings. 
3. Clean the Project 

2

  1. Create objective-c files in project(it automatically set path in Build Settings for you )
  2. import .h file in bridge-Header file

Теперь хорошо идти Спасибо

  • 0
    Очень редкий ответ.
0

Первый шаг: -

Если вы добавляете объективный файл c, где ваш проект был создан на языке быстрой передачи, вы получаете такой вариант, как ниже

Изображение 1562

создать мостовой файл заголовка отсюда или добавить новое имя файла заголовка моста как

Имя_проекта (название проекта) -Bridging-Header.h

импортировать Objective C ".h" файл в заголовке, например,

#ifndef Test_Bridging_Header_h
#define Test_Bridging_Header_h

#import "TestViewController.h" /*Objective C file*/

#endif /* Test_Bridging_Header_h */

Второй шаг: -

Связывание заголовка моста с вашей целью

Цель проекта → Настройка сборки. Обновите эти свойства.

"Определяет модуль": ДА.

"Всегда вставлять быстрые стандартные библиотеки": ДА.

"Установить Objective-C Заголовок совместимости": ДА.

Изображение 1563

Ещё вопросы

Сообщество Overcoder
Наверх
Меню