Mixing Swift & ObjectiveC
零、 Into
Apple 已经建议开发者今后不再提交纯 Objective-C 书写的程序。而是提交纯 Swift 或者 Swift 与 Objective-C 混编的程序
在 SDK 还是 Objective-C 的前提下,还是可以使用 Swift 进行开发的。这就涉及到了在 Swift 文件中调用 Objective-C 代码的问题。
关于怎样混编 Swift 和 Objective-C 的代码,Apple 的 iOS Developer Library 的这篇文章讲得要比我清楚地多…
一、步骤
首先,需要建立
.pch
文件,这是桥接文件,用于导入需要调用的 Objective-C 代码的头文件。
然后,需要在工程中设置 Objective-C Bridging Header 这一项。在
.pch
文件导入 Objective-C 的头文件以后,就可以愉快地在 Swift 中调用已经写好的 Objective-C 代码了。StackOverflow 上的这个答案步骤要更加完整一些。
二、我遇到的几个坑
1. Block 语法问题
对于下面这个 Block:
[[EaseMob sharedInstance].chatManager asyncRegisterNewAccount:@"8001" password:@"111111"
withCompletion:^(NSString *username, NSString *password, EMError *error) {
if (!error) {
NSLog(@"注册成功");
}
} onQueue:nil];
翻译成 Swift 闭包是这样的:
EaseMob.sharedInstance().chatManager.asyncRegisterNewAccount(userName, password: password,
withCompletion: {userName, password, error in
if error == nil {
println("注册成功")
}
}, onQueue: nil)
2. enum 问题
用 Objective-C 定义了如此的 enum:
typedef enum : NSUInteger {
EMErrorServerNotReachable,
EMErrorServerTimeout,
EMErrorServerAuthenticationFailure,
} EMErrorType;
比如我在调用注册代码以后,需要判断错误类型,根据错误种类做出相应的措施,用 Objective-C 判断是这样的:
switch (error.errorCode) {
case EMErrorServerNotReachable:
// Do something
break;
case EMErrorServerAuthenticationFailure:
// Do something
break;
case EMErrorServerTimeout:
// Do something
break;
default: break;
}
然而用 Swift 做 Switch 操作需要这样:
switch error.errorCode.value {
case EMErrorServerNotReachable.value:
// Do something
case EMErrorServerAuthenticationFailure.value:
// Do something
case EMErrorServerTimeout.value:
// Do something
default: break
}
3. BOOL 的 setter 问题
这个问题我也不知道算不算是个问题,原因是什么我也不太了解。
在接触环信 SDK,有一个设置用户自动登录的方法:
// 设置自动登录
[[EaseMob sharedInstance].chatManager setIsAutoLoginEnabled:YES];
我在 Swift 文件中不管怎样写都实现不了这段代码。我的解决方案是,新建一个 Objective-C 的类,其中一个类方法为:
+ (void)setIsAutoLoginEnabled:(BOOL)flag {
[[EaseMob sharedInstance].chatManager setIsAutoLoginEnabled:flag];
}
这样,我在 Swift 文件中就可以愉快地调用了。
参考资料:
1. http://stackoverflow.com/questions/24168612/working-with-objective-c-blocks-with-swift
2. http://stackoverflow.com/questions/24544712/how-do-i-access-an-enum-in-swift-from-objective-c 3. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_25 4. http://stackoverflow.com/questions/24002369/how-to-call-objective-c-code-from-swift