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

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

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

Рассуждение

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

+912
02 июн. '14 в 20:05
источник поделиться
18 ответов

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

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

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

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

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

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

Enter image description here

Нажмите ДА !

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

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

Enter image description here

Заметка

Рекомендуется связывать ваш проект с помощью макроса $(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, ответ будет обновлен соответствующим образом.

+1321
03 июн. '14 в 0:12
источник

Связанные вопросы


Похожие вопросы

См. руководство 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).

+116
02 июн. '14 в 20:43
источник

Ниже приведены пошаговые инструкции по использованию кода 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" Мостовой заголовок "в" Быстрый компилятор - генерация кода".

+59
12 февр. '15 в 19:34
источник

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

+38
04 июн. '14 в 2:11
источник

Я написал простой проект 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.

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

+24
13 июн. '14 в 10:10
источник

Цитата из documentation:

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

import Foundation

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

+21
02 июн. '14 в 20:43
источник

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

Я очень благодарен за ответ @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 не работает.

+20
16 сент. '15 в 7:00
источник

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

+11
20 мар. '16 в 17:53
источник

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

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

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

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

eEter image description here

+8
25 нояб. '15 в 8:29
источник

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

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

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

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

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

+3
19 мая '18 в 16:27
источник

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

import Foundation

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

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

+2
28 сент. '16 в 7:12
источник

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

enter image description here

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

Create Bridging Header.

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

Objc-Bridging-Header.h.

enter image description here

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

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

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

enter image description here

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

enter image description here enter image description here

+2
12 июн. '18 в 21:43
источник

В этом документе 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
05 янв. '19 в 11:17
источник

Двухсторонний подход к использованию target-c target-c

1

  1. Создайте файл bridge-header.h в проекте Xcode
  2. импортировать файл .h в файл заголовка моста
  3. Установить путь моста-заголовка в настройках сборки.
  4. Очистить проект

2

  1. Создайте файлы target-c в проекте (он автоматически устанавливает путь в настройках сборки для вас)
  2. импортировать файл .h в файл заголовка моста

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

0
13 апр. '18 в 9:39
источник

Первый шаг: -

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

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

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

Имя_проекта (название проекта) -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 Заголовок совместимости": ДА.

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

0
05 дек. '17 в 3:30

Ответ Logans работает нормально, за исключением последнего Swift 5 который дает ошибку компилятора. Вот исправление для людей, которые работают над 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
    }
}
0
21 мая '19 в 13:48
источник

Посмотрите другие вопросы по меткам или Задайте вопрос