Apple提到它们可以在一个应用程序中共存,但这是否意味着人们可以在技术上重用Objective-C中创建的旧类。在Swift中构建新类的同时?
#1 楼
在Swift中使用Objective-C类如果要使用现有的类,请执行步骤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:在
CustomObject.h
中构建您的Objective-C类 #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
中将类添加到Bridging-Header中:
br />第6步:使用对象
在
#import "CustomObject.h"
中: SomeSwiftFile.swift
无需显式导入;这就是桥接头的用途。
在Objective-C中使用Swift类
步骤1:创建新的Swift类
在您的项目中添加一个
var instanceOfCustomObject = CustomObject()
instanceOfCustomObject.someProperty = "Hello World"
print(instanceOfCustomObject.someProperty)
instanceOfCustomObject.someMethod()
文件,并将其命名为.swift
。在
MySwiftObject.swift
中: MySwiftObject.swift
步骤2:导入Swift文件到ObjC类
在
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"
也应该已经在您的项目中自动创建。步骤3:使用您的课程
<#YourProjectName#>-Swift.h
注意:
如果代码完成不符合您的期望,请尝试使用以下命令运行快速构建⌘⇧R帮助Xcode从Swift上下文中找到一些Objective-C代码,反之亦然。
如果将
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);
文件添加到较旧的项目中并出现错误.swift
,请尝试完全重新启动Xcode。虽然最初可以使用对物镜可见的纯Swift类(不是
dyld: Library not loaded: @rpath/libswift_stdlib_core.dylib
的后代) -C通过使用NSObject
前缀,将不再可能。现在,要在Objective-C中可见,Swift对象必须是符合@objc
的类(最简单的方法是从NSObjectProtocol
继承),或者是标记为NSObject
的enum
,其原始值是某些整数类型,例如@objc
。您可以在没有这些限制的情况下使用Int
查看Swift 1.x代码示例的编辑历史记录。评论
重要的是,您需要使用@objc注释方法,否则Swift方法将无法从Objective-C中看到。
–汤玛斯·林哈特(TomášLinhart)
2014年6月3日,11:19
你是对的。如果不使用Cocoa对象,则只需指定它。为了在Objective-C中可访问和使用,Swift类必须是Objective-C类的后代,或者必须标记为@objc。
–汤玛斯·林哈特(TomášLinhart)
2014年6月3日13:48
@MarkusRautopuro-从这里获取:developer.apple.com/library/prerelease/ios/documentation/Swift/…”
–登录
2014年6月3日在16:25
另请参阅:WWDC 2014会议406:将Swift与Objective-C集成
– Stuart M
2014年6月5日7:27
如果要将Objective C框架导入Swift,请确保将Obj C框架所依赖的所有框架都导入到您的项目中(在Build Phases-> Link Binary With Libraries中),然后将这些的#import添加到前缀头文件中,必须在构建设置中(在“前缀标题”字段中)添加到项目中。这包括UIKit和Foundation之类的框架,即使它们已在Swift中使用。这使我绊了好几个小时,似乎没有人记录这些步骤。
–user1021430
2014年11月20日在21:29
#2 楼
请参阅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文件时使用“快速打开”并键入Objective-C类名称,它将带您到类头的Swift版本。 (您也可以通过cmd单击Swift文件中的API符号来获取此信息。)iOS 8和OS X v10.10(Yosemite)开发人员库中的所有API参考文档在Objective-C和Swift中都可见形式(例如
UIView
)。评论
与Apple文档的直接链接如何将Swift集成到现有项目中:developer.apple.com/library/prerelease/ios/documentation/Swift/…
–skywinder
2014年6月4日11:55
如果您对为什么需要头文件以及在链接阶段如何使用头文件感兴趣,请确保阅读此手册Swift:了解Swift / Objective-C构建管道
–蜂蜜
19年8月11日在12:16
#3 楼
以下是在Swift项目中使用Objective-C代码(在本例中为第三方提供的框架)的分步说明:添加通过选择File-> New-> New File-> Objective-C File将任何Objective-C文件添加到您的Swift项目。保存后,Xcode会询问您是否要添加桥接头。选择“是”。 (来源:derrrick.com)
通过简单的步骤:
出现提示,然后单击“确定...”。不会出现,然后我们按如下所示手动创建它...从iOS源创建一个头文件,并命名为ProjectName-Bridging-Header(例如:Test-Bridging-Header),然后在Swift编译器代码-> Objective-C桥添加Objective-C桥名称..(Test / Test-Bridging-Header.h)。是的,这是完整的。
或者,删除您添加的Objective-C文件(在上面的GIF图像中命名为“ anything”)。您不再需要它。
打开桥接头文件-文件名的格式为[YourProject] -Bridging-Header.h。它包括Xcode提供的注释。为要包括的Objective-C文件添加一行代码,例如第三方框架。例如,要将Mixpanel添加到您的项目,您需要将以下代码行添加到桥接头文件中:
#import "Mixpanel.h"
现在可以在任何Swift文件中使用在Swift语法中使用现有的Objective-C代码(在此示例中,您可以调用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桥接头”的值。
#4 楼
您可以阅读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)
})
还可以看看苹果的文档《将Swift与Cocoa和Objective-C结合使用》。 >
#5 楼
我写了一个简单的Xcode 6项目,展示了如何混合使用C ++,Objective-C和Swift代码:https://github.com/romitagl/shared/tree/master/C-ObjC-Swift / Performance_Console
特别地,该示例从Swift调用了Objective-C和C ++函数。
关键是创建一个共享头,Project-Bridging-Header .h,然后在其中放置Objective-C标头。
请下载该项目作为完整示例。
#6 楼
我想在这里添加一件事:我非常感谢@Logan的回答。创建桥文件和设置会很有帮助。
但是完成所有这些步骤后,我仍然没有在Swift中获得Objective-C类。
我使用了
cocoapods
库并将其集成到我的项目。所以是pod "pop"
。因此,如果您在Swift中使用Objective-C Pod,则可能无法将类qq1202079q放入Swift。
要做的简单事情是:
转到
import
文件,并将语句
<YOUR-PROJECT>-Bridging-Header
替换为#import <ObjC_Framework>
例如:(弹出库)
替换
#import <pop/POP.h>
与
@import pop;
当
@import ObjC_Framework
不工作时使用clang import
。评论
#import不起作用时,请使用clang import。什么?不只是说我们应该使用@import吗?
–蜂蜜
16 Dec 2'在3:44
#7 楼
从文档中引用:任何可作为模块访问的Objective-C框架(或C库)都可以直接导入到Swift中。这包括所有
Objective-C系统框架(例如Foundation,UIKit和
SpriteKit),以及系统随附的通用C库。对于
示例,要导入Foundation,只需将此导入语句添加到您正在使用的Swift文件的
顶部:
import Foundation
此导入使得所有Foundation API(包括NSDate,NSURL,
NSMutableData及其所有方法,属性和
类别)都可以直接在Swift中使用。
#8 楼
只是为试图向Swift添加Objective-C库的人提供的注释:您应该在Build Settings-> Linking-> Other Linker Flags中添加-ObjC。评论
为什么?请添加有关此标志的作用以及添加原因的信息。
–约翰·卡尔森(Johan Karlsson)
18/12/21在8:48
#9 楼
创建桥接头之后,转到Build Setting =>搜索“ Objective-C桥接头”。在下面,您将找到“ Objective-C生成的接口头名称”文件。 br />
将文件导入到视图控制器中。
示例:在我的情况下:“ Dauble-Swift.h”
#10 楼
单击新建文件菜单,然后选择文件选择语言“目标”。那时它会自动生成一个“ Objective-C桥接标头”文件,该文件用于定义某些类名。“ Swift编译器-代码生成”下的“ Objective-C桥接标头”。 />
#11 楼
从NewFile-> Source->头文件中创建一个.h文件。然后保存文件名Your_Target_Name-Bridging-Header.h。如果两者的名称不同,则项目的目标名称通常相同。
然后在构建设置中搜索“ Objective-C桥接标头”标志并放置新创建的桥接文件的地址,您可以右键单击文件->在finder中显示->将文件拖到文本区域,然后将填充地址。
使用#import Your_Objective-C_file.h
,在swift文件中,您可以访问ObjC文件,但仅使用快速语言。
#12 楼
在Xcode 10.1的Swift 4.2.1项目中,您可以轻松地添加Objective-C文件。请按照以下步骤将Objective-C文件桥接到Swift项目。Step_01:使用Swift语言创建新的Xcode项目:
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
。Step_06:现在,您需要在网桥头中设置网桥文件路径。在项目浏览器中,单击名称为
objc
的项目,然后选择:Build Settings
> Objective-C Bridging Header
> Objc-Bridging-Header.h
。Step_07:将
Objc-Bridging-Header.h
拖放到该框中以生成一个文件路径。Step_08:打开
Objc-Bridging-Header.h
文件,然后导入要在Swift文件中使用的Objective-C文件。#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)
}
#13 楼
我在github上添加了包含小样本的项目,可以从swift调用Objective C代码。从swift调用ObjectiveC类
评论
注意:-在swift项目中创建Objc类时,xcode会要求自动桥接该类。别担心 :)
– CrazyPro007
18年5月19日在16:30
#14 楼
洛根答案很好用,除非在最新的Swift 5
中它给出了一些编译器错误。这是针对使用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
}
}
#15 楼
Swift消费者,Objective-C生产者添加新的头文件
.h
和实现.m
文件-可可类文件(Objective-C)例如
MyFileName
。配置桥接头文件
当看到
Would you like to configure an Objective-C bridging header
时,单击-是<target_name>-Bridging-Header.h
将自动生成构建设置-> Objective-C桥接标头
将类添加到桥接标头
在
<target_name>-Bridging-Header.h
中添加一行#import "<MyFileName>.h"
之后,您就可以在
MyFileName
中使用Objective-C
中的Swift
PS如果您应该将现有的Objective-C文件添加到Swift项目中,请事先添加
Bridging-Header.h
并将其导入Objective-C使用者,Swift生产者
添加
<MyFileName>.swift
并将NSObject
扩展为将Swift文件导入到ObjC类中
将
#import "<target_name>-Swift.h"
添加到您的Objective-C文件中通过
@objc
[@objc和@objcMembers]公开公共Swift代码之后您可以在
Swift
中使用Objective-C
#16 楼
Apple已在此文档中提供了官方指南:如何从swift调用目标C代码
以下是相关部分:
要将一组Objective-C文件导入同一应用程序目标内的Swift代码中,您需要依靠Objective-C桥接头文件将这些文件公开给Swift。当您将Swift文件添加到现有的Objective-C应用程序或将Objective-C文件添加到现有的Swift应用程序时,Xcode会创建此头文件。
如果您接受,则Xcode会创建桥接头文件以及要创建的文件,并使用产品模块名称后跟“ -Bridging-Header.h”对其进行命名。或者,您可以通过选择File> New> File> [operating system]> Source> Header File来自己创建桥接头文件。编辑桥接头文件以将您的Objective-C代码公开给您的Swift代码:
在您的Objective-C桥接标头中,导入要公开给Swift的每个Objective-C标头。
在Build Settings中,Swift编译器-代码生成后,确保“ Objective-C桥接头”构建设置具有桥接头文件的路径。该路径应相对于您的项目,类似于在“构建设置”中指定Info.plist路径的方式。在大多数情况下,您不需要修改此设置。
Swift可以看到桥接标头中列出的任何公共Objective-C标头。
#17 楼
两种使用Objective-C的方法Objective-c1
在Xcode Project中创建bridge-header.h文件
导入.h文件在bridge-Header文件中
在Build设置中设置bridge-Header的路径。
清理项目
2
在项目中创建Objective-C文件(它会自动在Build Settings中为您设置路径)
在网桥头文件中导入.h文件
现在好了
感谢
#18 楼
制作NSObject的任何Swift类子类也很有意义,我更喜欢在Objective-C类中使用任何Swift类,例如:@objc(MySwiftClass)
@objcMembers class MySwiftClass {...}
评论
请参阅Apple关于将Swift与Cocoa和Objective-C结合使用的指南。developer.apple.com/library/prerelease/ios/documentation/Swift / ...
有趣的是,这个问题得到了很多好评和赏金。当我第一次看到它时,我只是想:RTFM。就目前而言,它并没有显示任何研究成果,因为目前只有两三个资源正式记录了Swift,而其中一个资源完全致力于此(并在第一条评论中链接了)。
@EvolGate:Objective C到底缺少什么阻止它成为平台无关的语言?语言和语言标准库是开源的。您可以在Windows,Os X,Linux,BSD,Solaris和GCC或LLVM支持的任何其他平台中以及在其中使用ObjectiveC。即使GCC和LLVM都不支持,您也可以使用像样的C编译器轻松地将Objective C移植到任何平台。我看不出有什么比这更多的平台独立性了。
@DavidMulder:是否仍需要“推理”部分?