一个才适应Swift2.2的开发者眼中的Swift 3.0和iOS 10

食用指南

Xcode 8带着Swift 3风风火火的到来了,做为一个平时使用OC为主的iOS开发来讲,Swift 3正式和OC-like语法划定了界限。您能够简单浏览本文,也能够把本文当作从Swift2.2迁移到Swift3的指南。若是您在迁移的过程当中遇到了问题,不妨直接CTRL+F来搜索一下本文,看能不能找到解决方法。
由于本文是做为公司的内部培训资料,因此若是您在阅读的时候发现了错误或者是有更好的解决方法,欢迎联系我或者在下方留下您的评论。git

1.苹果官方提供的Swift 3 更新内容(部分Objective-C语法也变动了)

1.1 语法上的形式变动

语法形式上的变动是很是方便理解的,在迁移过程当中,Xcode会自动提示您转为对应的格式,形式变动的内容以下:github

  • 系统提供的枚举类型默认转为小写 好比 UIButton(type: .Custom) -> UIButton(type: .custom)web

  • 类型判断语法变化 object.dynamicType -> type(of: object)数据库

  • UIViewController.statusBarStyle -> -(UIStatusBarStyle)preferredStatusBarStyle{}swift

  • Core Graphics API Swift化,基原本说这一部分能自动化就自动化转换,量太大了...api

  • webview的代理方法- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error须要去掉nullable不然会报错安全

1.2 逃逸闭包必须显示声明

如今swift3.0全部的函数都是默认@noescape 非逃逸闭包,而 逃逸闭包(闭包在函数调用完以后才被调用的)必须显示声明@escaping,好比:ruby

func transport(requestMethod: Alamofire.HTTPMethod, url: String, callback: @escaping (Any) -> Void) -> Void {}

1.3 typealias 支持泛型

这带来了什么?更加抽象的CollectionType,甚至是更加便捷的JSON转模型方法网络

1.4 selector支持属性的getter和setter方法

class Dog {
    var dogName: String
}

let dogNameGetter = #selector(getter: Dog.dogName)

1.5 Dispatch彻底抛弃C-like 写法

是的,您的Snippet应该更新一下了!大部分旧写法都能找到新的写法替换,不过对于dispatch_once来讲就彻底被废弃,您可使用 懒加载 来替代。闭包

DispatchQueue.global().async {
    // 异步操做
    DispatchQueue.main.async {
        // 主线程操做
    }
}

DispatchQueue.global().sync {
    // 同步操做
}

//建立队列
let serialQueue = DispatchQueue(label: "Queuename")

//延迟执行
let delay = DispatchTime.now() + DispatchTimeInterval.seconds(\Seconds)
DispatchQueue.main.asyncAfter(deadline: delay) { 
}

1.6引入系统版本判断代码

if #available(iOS 10.0,*){
    //您的代码
}

1.7Any类型会逐渐开始使用

在Swift2的项目中,可能使用AnyObject更加频繁,由于在Swift2 中编译器默认作了基本类型到OC类型的桥接。在Swift3中,这类桥接被废弃,因此须要明确Any和AnyObject的区别,也就是Any包含AnyObjectAny类型包括struct、class、selector等,而AnyObject只对应class

2. iOS 10给迁移带来的其余须要注意点

2.1 2017年1月1日以前强制使用HTTPS

在iOS9中默认HTTP是被禁止的,能够在info.plist中经过设置NSAllowsArbitraryLoadsYES打开。新iOS 10若是要访问网络也能够如iOS 9 同样设置来访问网络,可是这在2017年1月1日以后有可能会被拒绝,您能够经过NSExceptionDomains来针对特定域名开放HTTP访问。

2.2 隐私权限更严格了

iOS 10开始约束隐私权限了,若是您用到 相册、相机、位置、蓝牙、提醒事项、运动健康数据、麦克风、日历 等状况,您须要手动在info.plist中添加权限请求说明。不然很大概率会闪退,This app has crashed because it attempted to access privacy-sensitive data without a usage description.
添加的字段名以下图所示:

2.3 默认不提供网络访问权限

iOS 10默认不提供网络访问,也就是说,刚刚进入应用,在用户没有点击“赞成App访问蜂窝数据”以前是没法访问网络的。即便在用户点击确认以后,App每每没有设置自动刷新,用户体验不好的,但愿您能注意一下。

2.4 字体变大,低版本显示正常的Label在iOS10中变成“...”

iOS10使用了新字体,文字的宽度变大了,以前若是是UILabel写死宽度或者定死宽度约束的极可能就会出现文字变成“...”,须要手动处理一下。UILabel大部分时候只须要给一个Origin Point就够了,文字的大小实际上不须要写死的。

2.5 推送须要明确打开Capability

在XCode7中这里的开关不打开,推送也是能够正常使用的,可是在XCode8中,这里的开关必需要打开,否则会报错

Error Domain=NSCocoaErrorDomain Code=3000 "未找到应用程序的“aps-environment”的受权字符串" UserInfo={NSLocalizedDescription=未找到应用程序的“aps-environment”的受权字符串}
打开后会在本地生成entitlements文件

3. Xcode 8给咱们带来了哪些便利和麻烦

3.1 Xcode 8内置的Swift迁移工具

总的来讲,此次迁移工具帮了很大的忙。若是您打开一个Swift 2工程,迁移会主动提示您打开了一个Swift 的旧工程,问您是否是要自动进行语法转换。本人建议您进行手工迁移,反正我是历来没有一次性迁移成功过的。手动迁移也没有特别麻烦,迁移工具在局部的语法提示会快速帮您定位须要迁移的位置。在我看来,自动迁移提示存在的目的在于帮您检测了集成的第三方库是否是也是用Swift 3语法写的。

3.2 Xcode 8彻底不支持旧有的插件了

是的,彻底不支持了,也再也不支持Alcatraz提供的插件,VVDocumenter、FuzzyAutocomplete、cocoapods-plugin 手动再见~~ Xcode官方的说法是为了安全考虑。的确,疯狂装插件在崩溃的时候要找到出问题的插件仍是要花费一番功夫的。并且Xcode如今能够方便的开发编辑器插件了,只不过这些新插件的功能真心太弱了,太弱了...是的,我指的是,在座的各位新插件都是弱鸡。目前的解决办法是对Xcode进行重签名,而后生成一个“越狱版”的Xcode放在应用程序目录,教程连接地址在此。或者要不咱们仍是继续用Xcode 7.3.1吧...反正我是戒掉插件了。

3.3 Swift 2.3的使用

Xcode 7.3.1 是Swift 2.2 版本,而Xcode新建的工程默认都是基于Swift 3.0 的,若是您的工程是基于Swift2.3的版本的,您须要在Xcode 8.0 的 Build Settings - Use Legacy Swift Language Version中将参数的值设为Yes,不过须要注意的是,若是是用Swift2.3的工程,第三方的工程也须要为Swift 2.3的版本,在您创建工程的时候,您应该提前肯定您使用的第三方库是否支持Swift 2.3 。

3.4 Xcode 8如今支持图片文件名补全

Xcode 8如今支持图片文件名补全,在您键入UIImage(named: "ImageName")的时候会自动提示您工程中的图片,固然您也能够直接键入图片名称,即UIImage(named: "ImageName") -> ImageName, Xcode会在图片名称的前面创建一个小的缩略图,真的很小。

3.5 Xcode 8须要开启注释

若是遇到按CTRL + /注释没有效果了,那能够在终端里敲上~ sudo /usr/libexec/xpccachectl,而后重启电脑试试。

3.6 Xcode 8疯狂打印一大堆Log

在工程Edit Scheme中添加参数,以下图所示:

3.7 Xcode代码签名优化

总的来讲是苹果帮您把签名管理起来了,就是通常不会出现Fix issue的黄色小三角形了,没有特别须要咱们作的。

3.8 旧版本的Xcode没法打开Xcode 8保存过的storyboard和xib了

由于新的Interface Builder添加了初始化界面的功能,默认打开旧有的storyboard和xib会询问您是否将全部视图设定为一个统一的尺寸,若是您点击确认,只须要更新一下frame就能够看到结果,可是这在团队协做中会带来一个问题,在版本管理中,一旦push代码以后,团队中使用Xcode 8如下的成员就没法打开新版本的storyboard和xib了,解决方法是在Source Code层面打开storyboard或者xib,手动删除<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>便可。

3.9 在Xcode中使用相似VVdocument的功能

快捷键:option + command + /

3.10 你能够每7天建立10个APP IDs

每一个阶段能建立的App ID数量会有限制,你能够每7天建立10个APP IDs

4. 一些小的注意点

4.1 Cocoapod仍是主力的包管理工具

可能您据说过SPM(Swift Package Manager),这个相似NPM的包管理工具在很早官方就发布消息说要支持了,可是实际应用中,不少第三方库目前并不支持(至少从目前来看),工具的使用远远没有Yarn之于NPM那样的平滑迁移,因此目前仍是建议使用Cocoapod或者是Carthage吧!

4.2 RealmSwift 在Swift 3.0上要求进行数据库升级

准确的说,是当您将RealmSwift升级到3.0能支持的版本以后,在操做数据库的时候要求您升级数据库。因此仍是一步到位升级到3.0吧,别在2.3再折腾一遍了。

4.3 Alamofire 3.0再也不支持iOS 8

反正我放个图:

4.4 Cocoapods 中强制使用 Swift 3 语法

只须要在Podfile中添加:

#swift 3 adapt
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['SWIFT_VERSION'] = '3.0'
    end
  end
end

4.5 获取特定branch、tag、仓库的第三方库

在刚刚开始适配Swift 3的阶段,会遇到至关多的问题,好比:

  • 做者尚未到Cocoapods官方设置更新信息

  • 做者将Swift 3的版本创建在其余分支上,默认支持的仍是2.2或者是2.3的版本。

  • 做者根本尚未支持Swift 3 ,不过有热心的网友建了一个本身的仓库,帮忙适配了一下

这时候您能够尝试在pod后面添加一些描述信息来定位到您真正想要获取到的库的位置,好比这里就把SwiftyJSON库的获取地址转到了IBM维护的一个仓库上:

pod 'SwiftyJSON',
  :git => 'https://github.com/IBM-Swift/SwiftyJSON.git',
  :branch => 'master'
相关文章
相关标签/搜索