Apple 提到它们可以在一个应用程序中共存,但这是否意味着可以在技术上重用 Objective-C 中的旧类,同时在 Swift 中构建新类?
Objective-C 是一种独立于平台的语言,而 Swift 则依赖于平台。因此,在 Swift 中编写非平台相关代码(业务逻辑库)并不明智。但是,在其中编写与平台相关的代码(例如,与接口相关)将非常好。不是说这是一个好主意,但它肯定是一种兴趣。
** 如果您有要使用的现有课程,请执行步骤 2 ,然后跳到步骤 5 。 (在某些情况下,我必须在旧的 Objective-C 文件中添加一个显式的#import <Foundation/Foundation.h
。)**
将.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 = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
println(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()
无需明确导入; 这就是桥接头的用途。
将.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
}
}
在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);
// 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.虽然最初可以通过使用@objc
前缀在 Objective-C 中使用纯 Swift 类,但在 Swift 2.0 之后,这已不再可能。有关原始说明,请参阅编辑历史如果在将来的 Swift 版本中重新启用此功能,则答案将相应更新。
请参阅 Apple 的使用 Swift 与 Cocoa 和 Objective-C的指南。本指南介绍了如何使用 Swift 中的 Objective-C 和 C 代码,反之亦然,并提供了如何在现有项目中转换项目或混合和匹配 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 文件时使用 Open Quickly 并键入 Objective-C 类名称,它将带您进入类标题的 Swift-ified 版本。 (您也可以通过 cmd 单击 Swift 文件中的 API 符号来获取此信息。)并且在 Objective-C 和 Swift 中都可以看到iOS 8和OS X v10.10(Yosemite)开发人员库中的所有 API 参考文档。表格(例如UIView
)。
以下是在 Swift 项目中使用 Objective-C 代码(在本例中为第三方提供的框架)的分步说明:
简单的步骤:
出现提示,然后单击确定... 如果没有出现,则我们手动创建它,如下所示... 从 iOS 源创建一个头文件并命名为 ProjectName-Bridging-Header(示例:Test -Bridging-Header),然后转到 Swift 编译器代码中的构建设置 - > Objective-C bridge 添加 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
}
而已!
注意: 如果从项目中删除桥接头文件,请务必进入构建设置并删除 “Swift 编译器 - 代码生成” 下的 “ Objective-C Bridging Header ” 的值。