В Swift, как можно назвать код Objective-C?
Apple упомянула, что они могут сосуществовать в одном приложении, но означает ли это, что можно технически повторно использовать старые классы, созданные в Objective-C, при создании новых классов в Swift?
В Swift, как можно назвать код Objective-C?
Apple упомянула, что они могут сосуществовать в одном приложении, но означает ли это, что можно технически повторно использовать старые классы, созданные в Objective-C, при создании новых классов в Swift?
Ответы:
Если у вас есть существующий класс, который вы хотите использовать, выполните Шаг 2, а затем перейдите к Шаг 5 . (В некоторых случаях мне пришлось добавить явное
#import <Foundation/Foundation.h
в более старый файл Objective-C.)
Добавьте .m
файл в ваш класс и назовите его CustomObject.m
.
При добавлении .m
файла вы, скорее всего, получите приглашение, которое выглядит следующим образом:
Нажмите Да !
Если вы не увидели подсказку или случайно удалили соединительный заголовок, добавьте новый .h
файл в свой проект и назовите его <#YourProjectName#>-Bridging-Header.h
.
В некоторых ситуациях, особенно при работе со средами Objective C, вы не добавляете класс Objective C явно, и XCode не может найти компоновщик. В этом случае создайте свой .h
файл с именем, как указано выше, затем убедитесь, что вы связали его путь в настройках проекта вашей цели следующим образом:
Замечания:
Рекомендуется связывать ваш проект с помощью $(SRCROOT)
макроса, чтобы при перемещении проекта или работе над ним с другими с помощью удаленного репозитория он продолжал работать. $(SRCROOT)
может рассматриваться как каталог, содержащий ваш файл .xcodeproj. Это может выглядеть так:
$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
Добавьте другой .h
файл и назовите его CustomObject.h
.
В 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
В YourProject-Bridging-Header.h
:
#import "CustomObject.h"
В SomeSwiftFile.swift
:
var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()
Нет необходимости явно импортировать; это то, для чего предназначен соединительный заголовок.
Добавьте .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)"
}
}
В SomeRandomClass.m
:
#import "<#YourProjectName#>-Swift.h"
Файл: <#YourProjectName#>-Swift.h
уже должен автоматически создаваться в вашем проекте, даже если вы его не видите.
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);
Если завершение кода ведет себя не так, как вы ожидаете, попробуйте запустить быструю сборку, ⌘⇧Rчтобы помочь Xcode найти часть кода Objective-C из контекста Swift и наоборот.
Если вы добавляете .swift
файл в более старый проект и получаете сообщение об ошибке dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
, попробуйте полностью перезапустить XCode .
Хотя изначально было возможно использовать чистые классы Swift (не потомки NSObject
), которые видимы для Objective-C с помощью @objc
префикса, это больше невозможно. Теперь, чтобы быть видимым в Objective-C, объект Swift должен быть либо классом, соответствующим NSObjectProtocol
(самый простой способ сделать это наследовать от NSObject
), либо быть enum
помеченным @objc
с необработанным значением некоторого целочисленного типа, такого как Int
. Вы можете просмотреть историю редактирования для примера использования кода Swift 1.x @objc
без этих ограничений.
См. Руководство 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 Quickly при редактировании файла Swift и ввести имя класса Objective-C, и это приведет вас к Swift-версии заголовка класса. (Вы также можете получить это, нажав cmd на символ API в файле Swift.) И вся справочная документация по API в библиотеках для разработчиков iOS 8 и OS X v10.10 (Yosemite) видна как в Objective-C, так и в Swift. формы (например UIView
).
Ниже приведены пошаговые инструкции по использованию кода Objective-C (в данном случае, среды, предоставленной сторонней организацией) в проекте Swift:
В простых шагах:
Появится приглашение, а затем нажмите «ОК». Если оно не появится, мы создадим его вручную, как показано ниже ... Создайте один файл заголовка из источника iOS и присвойте ему имя ProjectName-Bridging-Header (пример: Test -Bridging-Header), а затем перейдите к настройке сборки в коде компилятора Swift -> Мост Objective-C добавьте имя моста 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 Bridging Header » в «Swift Compiler - Generation Code».
Вы можете прочитать хороший пост 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» .
Я написал простой проект для 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.
Пожалуйста, скачайте проект как полный пример.
Я очень благодарен за ответ @ Logan. Это очень помогает для создания файла моста и настроек.
Но после выполнения всех этих шагов я все еще не получаю класс Objective-C в Swift.
Я использовал cocoapods
библиотеку и интегрировал ее в свой проект. Который есть pod "pop"
.
Так что, если вы используете модули Objective-C в Swift, то есть вероятность, что вы не сможете получить import
эти классы в Swift.
Простая вещь, которую вы должны сделать, это:
<YOUR-PROJECT>-Bridging-Header
файлу и#import <ObjC_Framework>
на@import ObjC_Framework
Например: (поп-библиотека)
замещать
#import <pop/POP.h>
с
@import pop;
Используйте, clang import
когда #import
не работает.
Цитата из документации :
Любая среда Objective-C (или библиотека C), доступная в виде модуля, может быть импортирована непосредственно в Swift. Это включает в себя все системные платформы Objective-C, такие как Foundation, UIKit и SpriteKit, а также общие библиотеки C, поставляемые с системой. Например, чтобы импортировать Foundation, просто добавьте этот оператор импорта в начало файла Swift, в котором вы работаете:
import Foundation
Этот импорт делает все API-интерфейсы Foundation, включая NSDate, NSURL, NSMutableData и все их методы, свойства и категории, непосредственно доступными в Swift.
Просто примечание для тех, кто пытается добавить библиотеку Objective-C в Swift: Вы должны добавить -ObjC в Настройки сборки -> Связывание -> Другие флаги компоновщика .
После того, как вы создали заголовок Bridging, перейдите в Build Setting => Search для «Objective-C Bridging Header».
Чуть ниже вы найдете файл "" Имя заголовка сгенерированного интерфейса Objective-C ".
Импортируйте этот файл в свой контроллер представления.
Пример: в моем случае: "Dauble-Swift.h"
Нажмите на меню « Новый файл» и выберите файл, выберите язык. В это время он автоматически генерирует файл "Objective-C Bridging Header", который используется для определения некоторого имени класса.
«Заголовок моста Objective-C» в разделе «Компилятор Swift - Генерация кода».
Я добавил проект на GitHub, который включает в себя небольшой пример для вызова объективного кода C из Swift.
В проекте 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
?
Step_04: выберите опцию:
Create Bridging Header
,
Шаг_05: Будет создан соответствующий файл с именем:
Objc-Bridging-Header.h
,
Шаг_06: Теперь вам нужно настроить путь к файлу моста в заголовке моста. В Project Navigator нажмите на проект с именем objc
и затем выберите:
Build Settings
> Objective-C Bridging Header
> Objc-Bridging-Header.h
.
Шаг_07: Перетащите курсор Objc-Bridging-Header.h
в это поле, чтобы сгенерировать путь к файлу.
Шаг_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)
}
Ответ Logans работает нормально, за исключением последнего, 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
}
}
Добавьте заголовок .h
и .m
файлы реализации - файл класса какао (Objective-C),
напримерMyFileName
настроить заголовок моста
Когда вы видите Would you like to configure an Objective-C bridging header
нажмите - Да
<target_name>-Bridging-Header.h
будет сгенерирован автоматическиДобавить класс в Bridging-Header
In <target_name>-Bridging-Header.h
добавить строку#import "<MyFileName>.h"
PS Если вам нужно добавить существующие файлы Objective-C в проект Swift, добавьте Bridging-Header.h
заранее
Добавить <MyFileName>.swift
и расширяетNSObject
Импорт файлов Swift в класс ObjC
Добавьте #import "<#YourProjectName#>-Swift.h"
в свой файл Objective-C
Отметить общедоступный код Swift [@objc and @objcMembers]
В этом документе 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:
Все общедоступные заголовки Objective-C, перечисленные в заголовке моста, видны Swift.
Двухсторонний подход к использованию target-c target-c
1
2
Теперь хорошо идти Спасибо