如何从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代码(在这种情况下,由第三方提供的框架)的分步说明:

  1. 通过selectFile – > New – > New File – > Objective-C File, 将任何Objective-C文件添加到Swift项目中 。 保存后, Xcode会问你是否要添加一个桥接头 。 select“ ”。 Gif:将空文件添加到项目并生成桥接头http://www.derrrick.com/stackoverflow/1-empty-file.gif

简单的步骤:

  1. 出现一个提示,然后点击确定…如果它没有出现,那么我们手动创build它,如下所示…从iOS源创build一个头文件,并提供名称ProjectName-Bridging-Header(示例:Test然后在Swift编译器代码 – > Objective-C桥接器中添加Objective-C桥接名称(Test / Test-Bridging-Header.h)。 是的,这是完整的。

  2. 或者,删除您添加的Objective-C文件(在上面的GIF图像中命名为“任何东西”)。 你不需要它了。

  3. 打开桥接头文件 – 文件名的forms是[YourProject] –ridging-Header.h 。 它包含一个Xcode提供的注释。 为要包含的Objective-C文件添加一行代码 ,例如第三方框架。 例如,要将Mixpanel添加到您的项目中,您需要将以下代码行添加到桥接头文件中:

      #import“Mixpanel.h” 
  4. 现在在任何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中。

你必须做的简单的事情是:

  1. 转到<YOUR-PROJECT>-Bridging-Header文件和
  2. 将语句#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”

eEter图像描述在这里

任何可作为模块访问的Objective-C框架(或C库)都可以直接导入到Swift中。 这包括所有Objective-C系统框架(如Foundation,UIKit和SpriteKit)以及系统随附的通用C库。 例如,要导入Foundation,只需将此导入语句添加到您正在处理的Swift文件的顶部:

 import Foundation 

这个导入使得所有的基础API(包括NSDate,NSURL,NSMutableData,以及所有的方法,属性和类别)都可以直接在Swift中使用。

我从苹果公司的文档中看到了这一点。

  1. 从NewFile – > Source – >头文件创build一个.h文件
  2. 然后保存文件Your_Target_Name-Bridging-Header.h的名字。这里的人们通过获取他们的项目名称而得到常见的错误,但是如果两者不同,通常它们应该是项目的目标名称。
  3. 然后在构build设置中searchObjective-C桥接头标志,并把你新创build的桥接文件的地址,你可以右键点击文件 – >在查找器中显示 – >在文本区域拖动文件,然后地址将被填充。
  4. 使用#import Your_Objective-C_file.h
  5. 在swift文件中,您只能以快捷的语言访问ObjC文件。