Как мне вызвать код Objective-C из Swift?

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

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

+928
источник поделиться
19 ответов

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

+1340
источник

См. руководство 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
источник
другие ответы

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


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

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

  1. Добавьте любой файл Objective-C в ваш проект Swift, выбрав "Файл" → "Создать" → "Новый файл" → "Файл Objective C". После сохранения XCode спросит, хотите ли вы добавить соединительный заголовок. Выберите "Да". Gif: adding empty file to project and generating bridging header
    (источник: derrrick.com)

Простыми шагами:

  1. Появится приглашение, а затем нажмите "ОК". Если оно не появится, мы создадим его вручную, как показано ниже... Создайте один файл заголовка из источника iOS и присвойте ему имя ProjectName-Bridging-Header (пример: Test -Bridging-Header), а затем перейдите к настройке сборки в коде компилятора Swift → Мост 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
}

Вот оно!

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

+59
источник

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

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

Цитата из documentation:

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

import Foundation

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

+21
источник

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

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

+21
источник

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

+11
источник

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

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

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

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

eEter image description here

+8
источник

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

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

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

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

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

+3
источник

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

import Foundation

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

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

+2
источник

В проекте 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
источник

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

  1. Добавить заголовок Objective C .h и реализацию .m
    Добавьте файлы <FileName>.m и <FileName>.h в свой проект

  2. Добавить заголовок моста
    При добавлении файла .m нажмите "Да" на приглашении Would you like to configure an Objective-C bridging header

  3. Добавить класс в заголовок моста
    В YourProject-Bridging-Header.h добавьте строку #import "<FileName>.h"

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

  1. Добавьте файл <FileName>.swift, который расширяет NSObject, в ваш проект
  2. Импорт файлов Swift в класс ObjC
    Добавьте #import "<#YourProjectName#>-Swift.h" в файл Objective-C
  3. Отметить общедоступный код Swift [@objc and @objcMembers]

Подробнее здесь

+1
источник

Первый шаг: -

Если вы добавляете объективный файл 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

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

1

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

2

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

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

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
источник

Ответ 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
источник

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