如何从Swift中调用Objective-C代码
在苹果新的Swift语言中,如何调用Objective-C代码?
苹果提到,它们可以共存于一个应用程序中,但这是否意味着可以在技术上重新使用Objective-C中制作的旧类,同时在Swift中构build新类?
推理
Objective-C是一个独立于平台的语言,而Swift是平台依赖的。 因此,在Swift中编写非依赖于平台的代码(业务逻辑库)将不是明智之举。 但是,编写与平台相关的代码(例如,相关的接口)将会非常好。 不是说这是一个好主意,但它绝对是一种兴趣。
在Swift中使用Objective-C类
**如果您想要使用现有class级,请执行步骤2 ,然后跳至步骤5 。 (对于某些情况,我必须添加一个明确的#import <Foundation/Foundation.h
到一个较老的Objective-C文件。)**
第1步:添加Objective-C实现 – .m
将.m
文件添加到您的类中,并将其命名为CustomObject.m
。
步骤2:添加桥接头
在添加.m
文件时,您可能会看到如下所示的提示:
点击是 !
如果您没有看到提示,或者意外删除了桥接头,请将新的.h
文件添加到您的项目中,并将其命名为<#YourProjectName#>-Bridging-Header.h
您的项目名称<#YourProjectName#>-Bridging-Header.h
。
在某些情况下,特别是在使用Objective-C框架时,不要明确添加Objective-C类,Xcode也不能find链接器。 在这种情况下,创build如上所述的.h
文件,然后确保在目标的项目设置中链接其path,如下所示:
注意
使用$(SRCROOT)
macros链接项目是最好的实践,所以如果您移动项目或使用远程存储库与其他项目一起工作,它仍然可以工作。 $(SRCROOT)
可以被认为是包含你的.xcodeproj文件的目录。 它可能看起来像这样:
$(SRCROOT)/Folder/Folder/<#YourProjectName#>-Bridging-Header.h
第3步:添加Objective-C标题 – .h
添加另一个.h
文件并将其命名为CustomObject.h
。
第4步:build立你的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()
没有必要明确导入; 这就是桥接头的作用。
在Objective-C中使用Swift类
第1步:创build新的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
您的项目<#YourProjectName#>-Swift.h
应该已经在您的项目中自动创build,即使您看不到它。
第3步:使用你的class级
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);
注意:
CodeCompletion的行为并不像我想要的那样准确。 在我的系统上,使用“cmd + r”运行快速构build似乎有助于Swiftfind一些Objective-C代码,反之亦然。
2.如果将.swift
文件添加到较旧的项目并出现错误: dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
,请尝试完全重新启动Xcode 。
3.虽然原来可以在Objective-C中使用纯的Swift类,但是在Swift 2.0之后,这是不可能的。 请参阅编辑历史以获取原始说明 如果这个function在未来的Swift版本中被重新使用,答案会相应地更新。
请参阅Apple将C ++和Objective-C一起使用Swift的指南。 本指南介绍了如何使用Swift中的Objective-C和C代码,并提供了如何转换项目或在现有项目中混合匹配Objective-C / C和Swift部分的build议。
编译器自动生成调用C函数和Objective-C方法的Swift语法。 从文档中可以看出,这个Objective-C:
UITableView *myTableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
变成这个Swift代码:
let myTableView: UITableView = UITableView(frame: CGRectZero, style: .Grouped)
Xcode也可以随时进行这种翻译 – 编辑Swift文件时可以使用Open Quickly,然后inputObjective-C类的名称,它将带您到类头的Swift-ified版本。 (你也可以通过在一个Swift文件中用cmd单击一个API符号来得到这个)。在Objective-C和Swift中都可以看到iOS 8和OS X v10.10(Yosemite)开发库中的所有API参考文档forms(例如UIView
)。
以下是在Swift项目中使用Objective-C代码(在这种情况下,由第三方提供的框架)的分步说明:
- 通过selectFile – > New – > New File – > Objective-C File, 将任何Objective-C文件添加到Swift项目中 。 保存后, Xcode会问你是否要添加一个桥接头 。 select“ 是 ”。 Gif:将空文件添加到项目并生成桥接头http://www.derrrick.com/stackoverflow/1-empty-file.gif
简单的步骤:
-
出现一个提示,然后点击确定…如果它没有出现,那么我们手动创build它,如下所示…从iOS源创build一个头文件,并提供名称ProjectName-Bridging-Header(示例:Test然后在Swift编译器代码 – > Objective-C桥接器中添加Objective-C桥接名称(Test / Test-Bridging-Header.h)。 是的,这是完整的。
-
或者,删除您添加的Objective-C文件(在上面的GIF图像中命名为“任何东西”)。 你不需要它了。
-
打开桥接头文件 – 文件名的forms是[YourProject] –ridging-Header.h 。 它包含一个Xcode提供的注释。 为要包含的Objective-C文件添加一行代码 ,例如第三方框架。 例如,要将Mixpanel添加到您的项目中,您需要将以下代码行添加到桥接头文件中:
#import“Mixpanel.h”
-
现在在任何Swift文件中,您都可以使用现有的Objective-C代码,Swift语法 (在这个例子中,您可以调用Mixpanel SDK方法等)。 您需要熟悉Xcode如何将Objective-C转换为Swift。 苹果的指南是一个快速阅读。 或者看到这个答案不完整的总结。
Mixpanel示例:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { Mixpanel.sharedInstanceWithToken("your-token") return true }
而已!
注意: 如果您从项目中删除了桥接头文件,请务必进入“生成设置”并删除“Swift编译器 – 代码生成”下的“ Objective-C桥接头 ”的值。
你可以阅读不错的postSwift&Cocoapods 。 基本上,我们需要创build一个桥接头文件,并把所有的Objective-C头文件放在那里。 然后我们需要从我们的构build设置中引用它。 之后,我们可以使用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) })
也可以看看苹果的文档“ 使用cocoa和Objective-C的Swift” 。
我写了一个简单的Xcode 6项目,展示了如何混合使用C ++,Objective-C和Swift代码:
https://github.com/romitagl/shared/tree/master/C-ObjC-Swift/Performance_Console
特别是,这个例子从Swift中调用了一个Objective-C和一个C ++函数 。
关键是创build一个共享头文件Project-Bridging-Header.h,并将Objective-C头文件放在那里。
请下载该项目作为一个完整的例子。
从文档引用:
任何可作为模块访问的Objective-C框架(或C库)都可以直接导入到Swift中。 这包括所有Objective-C系统框架(如Foundation,UIKit和SpriteKit)以及系统随附的通用C库。 例如,要导入Foundation,只需将此导入语句添加到您正在处理的Swift文件的顶部:
import Foundation
这个导入使得所有的基础API(包括NSDate,NSURL,NSMutableData,以及所有的方法,属性和类别)都可以直接在Swift中使用。
还有一件事我想补充一下:
我非常感谢@ Logan的回答。 它有助于创build一个桥文件和设置。
但是在完成所有这些步骤之后,我仍然没有在Swift中获得Objective-C类。
我使用了cocoapods
库并将其集成到我的项目中。 哪个是pod "pop"
。
所以,如果在Swift中使用Objective-C pod,那么您可能有机会无法将类导入Swift中。
你必须做的简单的事情是:
- 转到
<YOUR-PROJECT>-Bridging-Header
文件和 - 将语句
#import <ObjC_Framework>
replace为@import ObjC_Framework
例如:(stream行音乐库)
更换
#import <pop/POP.h>
同
@import pop;
#import
不工作时使用clang import
#import
。
只要注意谁试图向Swift添加Objective-C库:您应该在Build Settings – > Linking – > Other Linker Flags中添加-ObjC 。
点击新build文件菜单,然后select文件select语言目标。 那时它会自动生成一个用来定义某个类名的“Objective-C桥接头”文件。
“Swift编译器 – 代码生成”下的“Objective-C桥接头”。
在创build桥接头之后,转到Build Setting =>search“Objective-C桥接头”。
在下面你会发现“Objective-C生成的接口标题名称”文件。
在您的视图控制器中导入该文件。
例如:在我的情况下:“Dauble-Swift.h”
任何可作为模块访问的Objective-C框架(或C库)都可以直接导入到Swift中。 这包括所有Objective-C系统框架(如Foundation,UIKit和SpriteKit)以及系统随附的通用C库。 例如,要导入Foundation,只需将此导入语句添加到您正在处理的Swift文件的顶部:
import Foundation
这个导入使得所有的基础API(包括NSDate,NSURL,NSMutableData,以及所有的方法,属性和类别)都可以直接在Swift中使用。
我从苹果公司的文档中看到了这一点。
- 从NewFile – > Source – >头文件创build一个.h文件
- 然后保存文件Your_Target_Name-Bridging-Header.h的名字。这里的人们通过获取他们的项目名称而得到常见的错误,但是如果两者不同,通常它们应该是项目的目标名称。
- 然后在构build设置中searchObjective-C桥接头标志,并把你新创build的桥接文件的地址,你可以右键点击文件 – >在查找器中显示 – >在文本区域拖动文件,然后地址将被填充。
- 使用#import Your_Objective-C_file.h
- 在swift文件中,您只能以快捷的语言访问ObjC文件。