the - using swift with cocoa and objective-c




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

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

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

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

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

Шаг 2: Добавить заголовок перемычки

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

Нажмите ДА !

Если вы не видели приглашение или случайно удалили заголовок моста, добавьте в проект новый файл .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: добавьте класс в заголовок-заголовок

В 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);
NSString * retString = [myOb someFunction:@"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, ответ будет соответствующим образом обновлен.

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

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

Рассуждение

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


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

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

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

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

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

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

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

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

замещать

#import <pop/POP.h>

с

@import pop;

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


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


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

import Foundation

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

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


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

  1. Добавьте любой объект Objective-C в ваш проект Swift , выбрав «Файл» -> «Создать» -> «Новый файл» -> «Объектив-C-файл». После сохранения Xcode спросит, хотите ли вы добавить заголовок моста . Выберите « Да ». Gif: добавление пустого файла в проект и создание заголовка моста http://www.derrrick.com//1-empty-file.gif

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

  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 Compiler - Code Generation».


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

Ниже вы найдете файл с именем «Objective-C Generated Interface Header Name».

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

Пример: В моем случае: «Dauble-Swift.h»


См. Руководство 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 также выполняет этот перевод «на лету» - вы можете использовать Open Quickly при редактировании файла Swift и ввести имя класса Objective-C, и оно перенесет вас в версию заголовка класса Swift. (Вы также можете получить это, нажав cmd на символ API в файле Swift.) И вся справочная документация API в библиотеках разработчиков iOS 8 и OS X v.10.10 (Yosemite) видна как в Objective-C, так и в Swift форм (например, UIView ).


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

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

import Foundation

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



В проекте Swift 4.2 в Xcode 9.4 вы можете легко добавить файл 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 ?

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

Create Bridging Header .

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

Objc-Bridging-Header.h .

Шаг_06: Теперь вам нужно установить путь к файлу Bridge в заголовке моста. В Project Navigator нажмите проект с именем 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)
}







swift