iOS10适配汇总

距离 iPhone 横空出世已经过去了 9 个年头,iOS 的版本号也跨入了两位数。在我们回顾过去四五年 iOS 系统的发展的时候,不免感叹变化速度之快,迭代周期之短。iOS 7 翻天覆地的全新设计,iOS 8 中 Size Classes 的出现,应用扩展,以及 Cloud Kit 的加入,iOS 9 里的分屏多任务特性等等。Apple 近年都是在 WWDC 发布新的系统和软件,然后在秋季和冬季 (或者来年春季) 召开硬件产品的发布会。WWDC 上每一项软件的更新其实都预示了相应的硬件的方向,相信今年也不会例外。

对于开发者来说,好消息是 iOS 10 中并没有加入太多内容。按照适配的需求,来年的 iOS 开发至少应该可以从 iOS 8 甚至 iOS 9 开始,我们将有时间对之前的版本特性进行更好的梳理,消化和实践。相比于开疆扩土,iOS 10 更专注的是对现有内容的改进,以弥补之前迅速发展所留下的一些问题,这其实正是 Apple 当下所亟需做的事情。

生态整合与 Extension 开发

在 iOS 10 里 Apple 延续了前几年的策略,那就是进行平台整合。全世界现在没有另外一家厂商在掌握了包括桌面,移动到穿戴的一系列硬件设备的同时,还掌控了相应的从操作系统,到应用软件,再到软件商店这样一套完整的布局。Apple 显然也非常明白这个优势意味着什么。所以近年来 Apple 一直强调平台整合,如果你的应用能够同时在 iOS,watchOS 以及 macOS 上工作的话,毫无疑问将会更容易吸引用户以及 Apple 的喜爱。

另外一点则是各个应用之间的整合和交互。不难发现,随着近年来 extension 开发的兴起,Apple 逐渐在从 app 是“用户体验的核心”这个理念中转移,变为用户应该也可以在通知中心,桌面挂件或者手表这样的地方完成必要交互。而应用之间的交互在以前可以说是 iOS 系统的禁区,但是去年随着 Workflow 的成功,Apple 对于应用之间的交互有助于用户生产力的提升有了清晰的认识。今年 SDK 中几个重大更新其实都是围绕这个主题来进行的。

iOS 10 中,Apple 为我们添加了茫茫多 extension 的新模板,以至于在同事之间开玩笑都是我们马上就要丢掉 iOS app 开发者的工作,而转变为 iOS extension 开发者这样了。新加入的扩展的种类和数量都足以说明使用应用扩展以及进行扩展开发在今后 iOS 开发中的重要地位。如果你对扩展开发还一无所知,可以先看看这篇入门文章,里面简单介绍了关于扩展的基本概念,不同开发 target 之间代码共享的方式,以及通用的扩展开发方法等。

SiriKit

Siri API 的开放自然是 iOS 10 SDK 中最激动人心也是亮眼的特性。SiriKit 为我们提供一全套从语音识别到代码处理,最后向用户展示结果的流程。Apple 加入了一套全新的框架 Intents.framework 来表示 Siri 获取并解析的结果。你的应用需要提供一些关键字表明可以接受相关输入,而 Siri 扩展只需要监听系统识别的用户意图 (intent),作出合适的响应,修改以及实际操作,最后通过 IntentsUI.framework 提供反馈。整个过程非常清晰明了,但是这也意味着开发者所能拥有的自由度有限。

在 iOS 10 中,我们只能用 SiriKit 来做六类事情,分别是:

语音和视频通话发送消息发送或接收付款搜索照片约车管理健身

如果你的应用恰好正在处理这些领域的问题的话,添加 Intents Extension 的支持会是很棒的选择。它将提高用户使用你的应用的可能性,也能让用户在其他像是地图这样的系统级应用中使用你的服务。

SiriKit 笔记 (待填坑)

User Notifications

通知中心向来是 iOS 上的兵家必争之地。如何提供适时有效的通知,往往决定了用户活跃和留存的可能性。在 iOS 10 上,Apple 对通知进行了加强和革新。现在,为了更好地处理和管理通知,和本地及推送通知相关的 API 被封装到了全新的框架 UserNotifications.framework 中。在 iOS 10 中,开发者的服务器有机会在本地或者远程通知发送给用户之前再进行修改。

另外,在之前加入了 notification action 以及 text input 的基础上,iOS 10 又新增了为通知添加音频,图片,甚至视频的功能。现在,你的通知不仅仅是提醒用户回到应用的入口,更成为了一个展示应用内容,向用户传递多媒体信息的窗口。

User Notifications 笔记 - iOS 10 UserNotifications 框架解析

iMessage Apps

Message 应用大概是 Apple 在宣传 iOS 10 时着力最多的部分了。虽然新的贴纸包,自动转换颜文字,发送全屏效果等功能都很酷炫,但是对于程序开发者来说,可能还是对 iMessage Apps 更感兴趣。Xcode 8 中,Apple 在 iOS Application 模板中添加了一类新的项目类型,Messages Application。同时,模拟器甚至还开发了新的双人对话模式,以供开发者调试这类 app。

虽然名义上是独立 app,但实际上工作的依然是一个 extension。在该扩展中,Messages.framework 将承担与系统的 message 界面交互的主要职责。你通过提供一个自定义的 View Controller,来获取用户在使用你的 message app 时进行对话的上下文,以及发送接收等操作,并做出合适的响应。这个扩展在用来进行直接在 Message 应用中一些自定义共享会很好玩。但是鉴于 Apple 暂时没有打算将 Message.app 跨平台的原因,可能也注定了这只会是一种补充,而无法成为主流。

iMessage Apps 笔记 (待填坑)

IDE 和工具改进

除了整合平台战略思想下的一些 SDK 改变,今年和 iOS 开发者相关的更多的是开发工具的进步和革新了。

Xcode 8

Xcode 8 展现出了很多有意思的新特性,比如更强大的 View Debugging,可以帮助我们追查内存引用问题的 Memory Debugging 等。这些工具十分强大,也将帮助我们在开发过程中及早发现问题,而不要将它们带入在最终产品中去。

在 app 签名方面,Apple 终于意识到了他们在 Xcode 7 中所犯得错误。我想可能不止一个人被证书和描述文件出问题时的 "Fix Issue" 按钮坑过。这个按钮不仅不会修正问题,反而会直接注销现有的开发者证书,然后“自作主张”地重新申请。大多数情况下,这让事情变得更加糟糕。特别是对于新加入的开发者,他们并不理解 Apple 的证书系统,错误的操作和处置,往往让开发环境变得不可挽回。Xcode 8 中,同一个开发者帐号现在允许多个开发证书,而完全重做的 app 签名系统也足够好用,并且避免了误操作的可能性。在兼顾自动配置的基础上,也为大型项目和复杂的 CI 环境提供了足够灵活的配置空间,这绝对值得点赞。

另外 Xcode 终于提供了进行代码编辑器扩展的能力。现在开发者可以创建XCSourceEditorExtension 来对 Xcode 的功能进行扩展了,在没有文档帮助和官方支持的情况下摸索着为 Xcode 制作插件的历史也即将结束。

Xcode 8 笔记 (待填坑)

Swift 3

Swift 开源已经过去半年时间。在 Swift 2.2 中我们已经看到了开源的社区力量对语言产生的深刻影响,而在 Swift 3 中这一影响的效果将更加明显。

最大的变化在于 Foundation 框架的重新导入,可能过一段时间再回头看的话,这将标志着 Swift 与 Objective-C 彻底分家。Foundation 框架中的 API 现在以更符合 Swift 的方式被导入到语言中。大体来说,这些变化包括去除 NS 前缀,将绝大部分 class 转换为 struct (虽然底层还是 copy-on-write 的引用实现,可以参看 ReferenceConvertible 协议的内容),去掉 API 中重复的语义等。如果在当前你还能看出 Swift 和 Objective-C 在使用 Foundation 或者说开发 app 时同根同源的话,Swift 3 正式发布后可能情况会大不相同。

由于引用类型向值类型的转换,也将导致我们在使用 Swift 开发时的思考方式发生变化。以往的 Foundation 框架中类型的可变性是由不可变类型和它的可变类型版本 (比如 NSData 和NSMutableData) 来进行区分的。而在 Swift 3 中,一般来说将只有作为结构体的不可变类型 (比如 Data),对于这类结构体的改变,将会是更安全的基于写时复制的行为,而不再是原来可变对象那样的危险的内存操作。这在很多时候除了保证数据共享时的安全性以外,内部的引用特性也保证了调用速度。实际上,因为减少了不必要的复制 (比如根据一个不可变对象创建相应的可变对象),实际上通过 Swift 3 的 API 使用 Foundation 的速度将比原来更快!

关于 Swift 3 的更多内容,我会在我的《Swifter - 100 个 Swift 必备 tips》一书中通过补充章节的方式进行说明。同时,该书现有的 Swift 2 相关的描述和示例也会按照 Swift 3 的语法规范和特性进行更新,以适应最新版本。您可以访问 swifter.tips 获取这本书的更多相关内容。

Apple 生态和其他

另外影响比较重大消息是,在 iOS 9 引入的 ATS 将在来年更加严格。2017 年起,新提交的 app 将不再被允许进行 http 的访问,所有的 app 内的网络请求必须加密,通过 https 完成。所以如果你家 app 的服务器或者某些访问页面还是 http 的话,需要尽早过度到 https。

另外,watchOS 3 和 tvOS 也有一些新的内容。其中最重要的当属 watchOS 中可以使用 SceneKit 和 SpriteKit。虽然这两个框架本意是做游戏,但是 watch 的小屏幕和低性能可能并不足以支撑我们在这样一个受限平台很好的作品。但是这两个框架可以为交互乏味的 watchOS 提供很好的动画效果的补充,可能会是它们在 watchOS 上更合适的用途。

最后,OS X 改名为 macOS,有些媒体和开发者将其解读为去乔布斯化,其实我更倾向于这是一种强迫症和完美主义的基本需求。不管名字如何改变,Apple 在 iOS,macOS,watchOS 和 tvOS 这四个产品线上的布局已经完成,整个生态现在看来也还十分健康。Apple 在用户权益和隐私上的重视,以及像是在 https 上的推动,无疑都是这个时代前进的动力。


随着iOS10已经发布,大家的App都需要适配iOS10,下面是我总结的一些关于iOS10适配方面的问题,如果有错误,欢迎指出.

1.系统判断方法失效:

在你的项目中,当需要判断系统版本的话,不要使用下面的方法:

  1. #define isiOS10 ([[[[UIDevice currentDevice] systemVersion] substringToIndex:1] intValue]>=10)  

它会永远返回NO,substringToIndex:1在iOS 10 会被检测成 iOS 1了,
应该使用下面的这些方法:
Objective-C 中这样写:

  1. #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)  
  2. #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)  
  3. #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)  
  4. #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)  
  5. #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)  

或者使用:

  1. if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){.majorVersion = 9, .minorVersion = 1, .patchVersion = 0}]) { NSLog(@"Hello from > iOS 9.1");}  
  2. if ([NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){9,3,0}]) { NSLog(@"Hello from > iOS 9.3");}  

或者使用:

  1. if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_9_0) { // do stuff for iOS 9 and newer} else { // do stuff for older versions than iOS 9}  

有时候会缺少一些常量,NSFoundationVersionNumber是在NSObjCRuntime.h中定义的,作为Xcode7.3.1的一部分,我们设定常熟范围从iPhone OS 2到#define NSFoundationVersionNumber_iOS_8_4 1144.17,在iOS 10(Xcode 8)中,苹果补充了缺少的数字,设置有未来的版本.

  1. #define NSFoundationVersionNumber_iOS_9_0 1240.1  
  2. #define NSFoundationVersionNumber_iOS_9_1 1241.14  
  3. #define NSFoundationVersionNumber_iOS_9_2 1242.12  
  4. #define NSFoundationVersionNumber_iOS_9_3 1242.12  
  5. #define NSFoundationVersionNumber_iOS_9_4 1280.25  
  6. #define NSFoundationVersionNumber_iOS_9_x_Max 1299  

Swift中这样写:

  1. if NSProcessInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0)) {   
  2.          // 代码块  
  3. }  

或者使用

  1. if #available(iOS 10.0, *) {   
  2.          // 代码块  
  3. else {   
  4.          // 代码块  
  5. }  

2.隐私数据访问问题:

你的项目中访问了隐私数据,比如:相机,相册,联系人等,在Xcode8中打开编译的话,统统会crash,控制台会输出下面这样的日志:

这是因为iOS对用户的安全和隐私的增强,在申请很多私有权限的时候都需要添加描述,但是,在使用Xcode 8之前的Xcode还是使用系统的权限通知框.
要想解决这个问题,只需要在info.plist添加NSContactsUsageDescription的key, value自己随意填写就可以,这里列举出对应的key(Source Code模式下):

  1.    
  2. NSPhotoLibraryUsageDescription   
  3. App需要您的同意,才能访问相册   
  4.    
  5. NSCameraUsageDescription   
  6. App需要您的同意,才能访问相机   
  7.    
  8. NSMicrophoneUsageDescription   
  9. App需要您的同意,才能访问麦克风   
  10.    
  11. NSLocationUsageDescription   
  12. App需要您的同意,才能访问位置   
  13.    
  14. NSLocationWhenInUseUsageDescription   
  15. App需要您的同意,才能在使用期间访问位置   
  16.    
  17. NSLocationAlwaysUsageDescription   
  18. App需要您的同意,才能始终访问位置   
  19.    
  20. NSCalendarsUsageDescription   
  21. App需要您的同意,才能访问日历   
  22.    
  23. NSRemindersUsageDescription   
  24. App需要您的同意,才能访问提醒事项   
  25.    
  26. NSMotionUsageDescription App需要您的同意,才能访问运动与健身   
  27.    
  28. NSHealthUpdateUsageDescription   
  29. App需要您的同意,才能访问健康更新    
  30.    
  31. NSHealthShareUsageDescription   
  32. App需要您的同意,才能访问健康分享   
  33.    
  34. NSBluetoothPeripheralUsageDescription   
  35. App需要您的同意,才能访问蓝牙   
  36.    
  37. NSAppleMusicUsageDescription   
  38. App需要您的同意,才能访问媒体资料库  

如果不起作用,可以请求后台权限,类似于这样:

  1. UIBackgroundModes  
  2.    
  3.    
  4. location  
  5. ...  

或者在Xcode里选中当前的target,选择Capabilities,找到Background Modes,打开它,在里面选择对应权限

3.UIColor的问题

官方文档中说:大多数core开头的图形框架和AVFoundation都提高了对扩展像素和宽色域色彩空间的支持.通过图形堆栈扩展这种方式比以往支持广色域的显示设备更加容易。现在对UIKit扩展可以在sRGB的色彩空间下工作,性能更好,也可以在更广泛的色域来搭配sRGB颜色.如果你的项目中是通过低级别的api自己实现图形处理的,建议使用sRGB,也就是说在项目中使用了RGB转化颜色的建议转换为使用sRGB,在UIColor类中新增了两个api:

  1. - (UIColor *)initWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);  
  2. + (UIColor *)colorWithDisplayP3Red:(CGFloat)displayP3Red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha NS_AVAILABLE_IOS(10_0);  

4.真彩色的显示

真彩色的显示会根据光感应器来自动的调节达到特定环境下显示与性能的平衡效果,如果需要这个功能的话,可以在info.plist里配置(在Source Code模式下):

  1. UIWhitePointAdaptivityStyle  

它有五种取值,分别是:

  1. UIWhitePointAdaptivityStyleStandard // 标准模式  
  2. UIWhitePointAdaptivityStyleReading // 阅读模式  
  3. UIWhitePointAdaptivityStylePhoto // 图片模式  
  4. UIWhitePointAdaptivityStyleVideo // 视频模式  
  5. UIWhitePointAdaptivityStyleStandard // 游戏模式  

也就是说如果你的项目是阅读类的,就选择UIWhitePointAdaptivityStyleReading这个模式,五种模式的显示效果是从上往下递减,也就是说如果你的项目是图片处理类的,你选择的是阅读模式,给选择太好的效果会影响性能.

5.ATS的问题

1.在iOS 9的时候,默认非HTTS的网络是被禁止的,我们可以在info.plist文件中添加NSAppTransportSecurity字典,将NSAllowsArbitraryLoads设置为YES来禁用ATS;
2.从2017年1月1日起,,所有新提交的 app 默认不允许使用NSAllowsArbitraryLoads来绕过ATS的限制,默认情况下你的 app 可以访问加密足够强的(TLS V1.2以上)HTTPS内容;
3.可以选择使用NSExceptionDomains设置白名单的方式对特定的域名开放HTTP内容来通过审核,比如说你的应用集成了第三方的登录分享SDK,可以通过这种方式来做,下面以新浪SDK作为示范(Source Code 模式下):

  1. NSAppTransportSecurity  
  2.   
  3.  NSExceptionDomains  
  4.    
  5.   sina.cn  
  6.     
  7.    NSThirdPartyExceptionMinimumTLSVersion  
  8.    TLSv1.0  
  9.    NSThirdPartyExceptionRequiresForwardSecrecy  
  10.      
  11.    NSIncludesSubdomains  
  12.      
  13.     
  14.   weibo.cn  
  15.     
  16.    NSThirdPartyExceptionMinimumTLSVersion  
  17.    TLSv1.0  
  18.    NSThirdPartyExceptionRequiresForwardSecrecy  
  19.      
  20.    NSIncludesSubdomains  
  21.      
  22.     
  23.   weibo. com  
  24.     
  25.    NSThirdPartyExceptionMinimumTLSVersion  
  26.    TLSv1.0  
  27.    NSThirdPartyExceptionRequiresForwardSecrecy  
  28.      
  29.    NSIncludesSubdomains  
  30.      
  31.     
  32.   sinaimg.cn  
  33.     
  34.    NSThirdPartyExceptionMinimumTLSVersion  
  35.    TLSv1.0  
  36.    NSThirdPartyExceptionRequiresForwardSecrecy  
  37.      
  38.    NSIncludesSubdomains  
  39.      
  40.     
  41.   sinajs.cn  
  42.     
  43.    NSThirdPartyExceptionMinimumTLSVersion  
  44.    TLSv1.0  
  45.    NSThirdPartyExceptionRequiresForwardSecrecy  
  46.      
  47.    NSIncludesSubdomains  
  48.      
  49.     
  50.   sina.com.cn  
  51.     
  52.    NSThirdPartyExceptionMinimumTLSVersion  
  53.    TLSv1.0  
  54.    NSThirdPartyExceptionRequiresForwardSecrecy  
  55.      
  56.    NSIncludesSubdomains  
  57.      
  58.     
  59.    

4.在iOS 10 中info.plist文件新加入了NSAllowsArbitraryLoadsInWebContent键,允许任意web页面加载,同时苹果会用 ATS 来保护你的app;
5.安全传输不再支持SSLv3, 建议尽快停用SHA1和3DES算法;

6.UIStatusBar的问题:

在iOS10中,如果还使用以前设置UIStatusBar类型或者控制隐藏还是显示的方法,会报警告,方法过期,如下图:


UIStatusBar的警告.png


上面方法到 iOS 10 不能使用了,要想修改UIStatusBar的样式或者状态使用下图中所示的属性或方法:

  1. @property(nonatomic, readonly) UIStatusBarStyle preferredStatusBarStyle NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarStyleDefault  
  2. @property(nonatomic, readonly) BOOL prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO  
  3. - (UIStatusBarStyle)preferredStatusBarStyle NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarStyleDefault  
  4. - (BOOL)prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO  
  5. // Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.  
  6. - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to UIStatusBarAnimationFade  

7.UITextField

在iOS 10 中,UITextField新增了textContentType字段,是UITextContentType类型,它是一个枚举,作用是可以指定输入框的类型,以便系统可以分析出用户的语义.是电话类型就建议一些电话,是地址类型就建议一些地址.可以在#import 文件中,查看textContentType字段,有以下可以选择的类型:

  1. UIKIT_EXTERN UITextContentType const UITextContentTypeName                      NS_AVAILABLE_IOS(10_0);  
  2. UIKIT_EXTERN UITextContentType const UITextContentTypeNamePrefix                NS_AVAILABLE_IOS(10_0);  
  3. UIKIT_EXTERN UITextContentType const UITextContentTypeGivenName                 NS_AVAILABLE_IOS(10_0);  
  4. UIKIT_EXTERN UITextContentType const UITextContentTypeMiddleName                NS_AVAILABLE_IOS(10_0);  
  5. UIKIT_EXTERN UITextContentType const UITextContentTypeFamilyName                NS_AVAILABLE_IOS(10_0);  
  6. UIKIT_EXTERN UITextContentType const UITextContentTypeNameSuffix                NS_AVAILABLE_IOS(10_0);  
  7. UIKIT_EXTERN UITextContentType const UITextContentTypeNickname                  NS_AVAILABLE_IOS(10_0);  
  8. UIKIT_EXTERN UITextContentType const UITextContentTypeJobTitle                  NS_AVAILABLE_IOS(10_0);  
  9. UIKIT_EXTERN UITextContentType const UITextContentTypeOrganizationName          NS_AVAILABLE_IOS(10_0);  
  10. UIKIT_EXTERN UITextContentType const UITextContentTypeLocation                  NS_AVAILABLE_IOS(10_0);  
  11. UIKIT_EXTERN UITextContentType const UITextContentTypeFullStreetAddress         NS_AVAILABLE_IOS(10_0);  
  12. UIKIT_EXTERN UITextContentType const UITextContentTypeStreetAddressLine1        NS_AVAILABLE_IOS(10_0);  
  13. UIKIT_EXTERN UITextContentType const UITextContentTypeStreetAddressLine2        NS_AVAILABLE_IOS(10_0);  
  14. UIKIT_EXTERN UITextContentType const UITextContentTypeAddressCity               NS_AVAILABLE_IOS(10_0);  
  15. UIKIT_EXTERN UITextContentType const UITextContentTypeAddressState              NS_AVAILABLE_IOS(10_0);  
  16. UIKIT_EXTERN UITextContentType const UITextContentTypeAddressCityAndState       NS_AVAILABLE_IOS(10_0);  
  17. UIKIT_EXTERN UITextContentType const UITextContentTypeSublocality               NS_AVAILABLE_IOS(10_0);  
  18. UIKIT_EXTERN UITextContentType const UITextContentTypeCountryName               NS_AVAILABLE_IOS(10_0);  
  19. UIKIT_EXTERN UITextContentType const UITextContentTypePostalCode                NS_AVAILABLE_IOS(10_0);  
  20. UIKIT_EXTERN UITextContentType const UITextContentTypeTelephoneNumber           NS_AVAILABLE_IOS(10_0);  
  21. UIKIT_EXTERN UITextContentType const UITextContentTypeEmailAddress              NS_AVAILABLE_IOS(10_0);  
  22. UIKIT_EXTERN UITextContentType const UITextContentTypeURL                       NS_AVAILABLE_IOS(10_0);  
  23. UIKIT_EXTERN UITextContentType const UITextContentTypeCreditCardNumber          NS_AVAILABLE_IOS(10_0);  

8.UserNotifications(用户通知)

iOS 10 中将通知相关的 API 都统一了,在此基础上很多用户定义的通知,并且可以捕捉到各个通知状态的回调.以前通知的概念是:大家想接受的提前做好准备,然后一下全两分发,没收到也不管了,也不关心发送者,现在的用户通知做成了类似于网络请求,先发一个request得到response的流程,还封装了error,可以在各个状态的方法中做一些额外的操作,并且能获得一些字段,比如发送者之类的.

9.UICollectionViewCell的的优化

在iOS 10 之前,UICollectionView上面如果有大量cell,当用户活动很快的时候,整个UICollectionView的卡顿会很明显,为什么会造成这样的问题,这里涉及到了iOS 系统的重用机制,当cell准备加载进屏幕的时候,整个cell都已经加载完成,等待在屏幕外面了,也就是整整一行cell都已经加载完毕,这就是造成卡顿的主要原因,专业术语叫做:掉帧.
要想让用户感觉不到卡顿,我们的app必须帧率达到60帧/秒,也就是说每帧16毫秒要刷新一次.

iOS 10 之前UICollectionViewCell的生命周期是这样的:

1.用户滑动屏幕,屏幕外有一个cell准备加载进来,把cell从reusr队列拿出来,然后调用prepareForReuse方法,在这个方法里面,可以重置cell的状态,加载新的数据;2.继续滑动,就会调用cellForItemAtIndexPath方法,在这个方法里面给cell赋值模型,然后返回给系统;3.当cell马上进去屏幕的时候,就会调用willDisplayCell方法,在这个方法里面我们还可以修改cell,为进入屏幕做最后的准备工作;4.执行完willDisplayCell方法后,cell就进去屏幕了.当cell完全离开屏幕以后,会调用didEndDisplayingCell方法.

iOS 10 UICollectionViewCell的生命周期是这样的:

1.用户滑动屏幕,屏幕外有一个cell准备加载进来,把cell从reusr队列拿出来,然后调用prepareForReuse方法,在这里当cell还没有进去屏幕的时候,就已经提前调用这个方法了,对比之前的区别是之前是cell的上边缘马上进去屏幕的时候就会调用该方法,而iOS 10 提前到cell还在屏幕外面的时候就调用;2.在cellForItemAtIndexPath中创建cell,填充数据,刷新状态等操作,相比于之前也提前了;3.用户继续滑动的话,当cell马上就需要显示的时候我们再调用willDisplayCell方法,原则就是:何时需要显示,何时再去调用willDisplayCell方法;4.当cell完全离开屏幕以后,会调用didEndDisplayingCell方法,跟之前一样,cell会进入重用队列.
在iOS 10 之前,cell只能从重用队列里面取出,再走一遍生命周期,并调用cellForItemAtIndexPath创建或者生成一个cell.
在iOS 10 中,系统会cell保存一段时间,也就是说当用户把cell滑出屏幕以后,如果又滑动回来,cell不用再走一遍生命周期了,只需要调用willDisplayCell方法就可以重新出现在屏幕中了.
iOS 10 中,系统是一个一个加载cell的,二以前是一行一行加载的,这样就可以提升很多性能;

iOS 10 新增加的Pre-Fetching预加载

这个是为了降低UICollectionViewCell在加载的时候所花费的时间,在 iOS 10 中,除了数据源协议和代理协议外,新增加了一个UICollectionViewDataSourcePrefetching协议,这个协议里面定义了两个方法:

  1. - (void)collectionView:(UICollectionView *)collectionView prefetchItemsAtIndexPaths:(NSArray *)indexPaths NS_AVAILABLE_IOS(10_0);  
  2.   
  3. - (void)collectionView:(UICollectionView *)collectionView cancelPrefetchingForItemsAtIndexPaths:(NSArray *)indexPaths  NS_AVAILABLE_IOS(10_0);  

在ColletionView prefetchItemsAt indexPaths这个方法是异步预加载数据的,当中的indexPaths数组是有序的,就是item接收数据的顺序;
CollectionView cancelPrefetcingForItemsAt indexPaths这个方法是可选的,可以用来处理在滑动中取消或者降低提前加载数据的优先级.
注意:这个协议并不能代替之前读取数据的方法,仅仅是辅助加载数据.
Pre-Fetching预加载对UITableViewCell同样适用.

10. UIRefreshControl的使用

在iOS 10 中, UIRefreshControl可以直接在UICollectionView和UITableView中使用,并且脱离了UITableViewController.现在RefreshControl是UIScrollView的一个属性.
使用方法:

  1. UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];  
  2.     [refreshControl addTarget:self action:@selector(loadData) forControlEvents:UIControlEventValueChanged];  
  3.     collectionView.refreshControl = refreshControl;  
  1. <h3 style="border-width:0px; padding:0px; margin:0px; list-style:none; color:rgb(51,51,51); font-family:宋体; line-height:28px; background-color:rgb(249,249,249)"><a name="t20"></a>11. <span style="background-color:rgb(250,247,239); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px">Xcode 8 运行一堆没用的logs解决办法</span></h3><p style="margin-top:0px; margin-bottom:8px; padding-top:0px; padding-bottom:0px; border-width:0px; list-style:none; text-indent:2em; color:rgb(51,51,51); font-family:宋体; font-size:14px; line-height:28px; background-color:rgb(249,249,249)"></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"><iframe id="iframe_0.9081770094445465" src="https://www.cnblogs.com/show-blocking-image.aspx?url=http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FfoPACGrddJ1DianjPbrjI0E1nCaCPwe1IUnMA2FnCAqG54P6zZibb24FibaEKzzVKtT7yhKaVHkXlvsLZVglmLqLQ%2F640%3Fwx_fmt%3Dpng%26wxfrom%3D5%26wx_lazy%3D1&maxWidth=916&origin=http://www.cnblogs.com&iframeId=iframe_0.9081770094445465" scrolling="no" style="margin: 0px; padding: 0px; border-width: initial; border-style: none; width: 916px;" frameborder="0" height="260"></iframe></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)">上图我们看到,自己新建的一个工程啥也没干就打印一堆烂七八糟的东西,我觉得这个应该是Xcode 8的问题,具体也没细研究,解决办法是设置OS_ACTIVITY_MODE : disable如下图:</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"><iframe id="iframe_0.9680173369304288" src="https://www.cnblogs.com/show-blocking-image.aspx?url=http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FfoPACGrddJ1DianjPbrjI0E1nCaCPwe1IokNIXSjEZUuq4R68ia7vGibkQoIhXfcf2y9wkTgFCwOCcM2e8CntbGIw%2F640%3Fwx_fmt%3Dpng%26wxfrom%3D5%26wx_lazy%3D1&maxWidth=916&origin=http://www.cnblogs.com&iframeId=iframe_0.9680173369304288" scrolling="no" style="margin: 0px; padding: 0px; border-width: initial; border-style: none; width: 916px;" frameborder="0" height="357"></iframe></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)">相关问题连接:<br style="margin:0px; padding:0px"><a target="_blank" href="http://stackoverflow.com/questions/37800790/hide-xcode-8-logs" style="margin:0px; padding:0px; color:rgb(100,102,179)">stackoverflow问答</a></p><p style="margin-top:0px; margin-bottom:8px; padding-top:0px; padding-bottom:0px; border-width:0px; list-style:none; text-indent:2em; color:rgb(51,51,51); font-family:宋体; font-size:14px; line-height:28px; background-color:rgb(249,249,249)"></p><h4 style="margin:15px auto 2px; padding:0px; font-size:14px; color:rgb(51,51,51); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; background-color:rgb(250,247,239)"><a name="t21"></a><span style="margin:0px; padding:0px">  
  2. </span></h4><h4 style="margin:15px auto 2px; padding:0px; font-size:14px; color:rgb(51,51,51); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; background-color:rgb(250,247,239)"><a name="t22"></a><span style="margin:0px; padding:0px">12.Xcode 8 插件不能用的问题</span></h4><p></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)">大家都升级了Xcode 8,但是对于插件依赖的开发者们,一边哭着一边去网上寻找解决办法。那么下面是解决办法:<br style="margin:0px; padding:0px"><a target="_blank" href="http://vongloo.me/2016/09/10/Make-Your-Xcode8-Great-Again/?utm_source=tuicool&utm_medium=referral" style="margin:0px; padding:0px; color:rgb(100,102,179)">让你的 Xcode8 继续使用插件</a></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)">但是看到文章最后的解释,我们知道如果用插件的话,可能安全上会有问题、并且提交审核会被拒绝,所以建议大家还是不要用了,解决办法总是有的,比如在Xcode中添加注释的代码块也是很方便的。</p><h4 style="margin:15px auto 2px; padding:0px; font-size:14px; color:rgb(51,51,51); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; background-color:rgb(250,247,239)"><a name="t23"></a><span style="margin:0px; padding:0px">13.iOS 10开始项目中有的文字显示不全问题</span></h4><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)">我用Xcode 8 和Xcode 7.3分别测试了下,如下图:</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"><iframe id="iframe_0.7618856801038547" src="https://www.cnblogs.com/show-blocking-image.aspx?url=http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FfoPACGrddJ1DianjPbrjI0E1nCaCPwe1IxmcvFRolia0jH1oSliaiaTIXN9tzYljzmjVFlbgkE8JbcOvtCzH462TSA%2F640%3Fwx_fmt%3Dpng%26wxfrom%3D5%26wx_lazy%3D1&maxWidth=916&origin=http://www.cnblogs.com&iframeId=iframe_0.7618856801038547" scrolling="no" style="margin: 0px; padding: 0px; border-width: initial; border-style: none; width: 916px;" frameborder="0" height="259"></iframe></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"><span style="margin:0px; padding:0px">Xcode 8<br style="margin:0px; padding:0px"></span></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"><iframe id="iframe_0.4421930347455778" src="https://www.cnblogs.com/show-blocking-image.aspx?url=http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_png%2FfoPACGrddJ1DianjPbrjI0E1nCaCPwe1IkNR35icS753MdD2KZibicY7X4ws7OfyIy5C1Kqo2Xsy8BBXkvwknw6Q4A%2F640%3Fwx_fmt%3Dpng%26wxfrom%3D5%26wx_lazy%3D1&maxWidth=916&origin=http://www.cnblogs.com&iframeId=iframe_0.4421930347455778" scrolling="no" style="margin: 0px; padding: 0px; border-width: initial; border-style: none; width: 916px;" frameborder="0" height="238"></iframe></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"><span style="margin:0px; padding:0px">Xcode 7</span></p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)">创建一个Label然后让它自适应大小,字体大小都是17最后输出的宽度是不一样的,我们再看一下,下面的数据就知道为什么升级iOS 10 之后App中有的文字显示不全了:</p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><table style="margin:0px; padding:0px; border-collapse:collapse; border-spacing:0px; border:1px solid silver; word-break:break-word; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"><thead style="margin:0px; padding:0px"><tr style="margin:0px; padding:0px"><th style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">Xxode  
  3.  8打印</th><th style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">Xcode 7.3打印</th></tr></thead><tbody style="margin:0px; padding:0px"><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">1个文字宽度:17.5</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">1个文字宽度:17</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">2个文字宽度:35</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">2个文字宽度:34</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">3个文字宽度:52</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">3个文字宽度:51</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">4个文字宽度:69.5</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">4个文字宽度:68</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">5个文字宽度:87</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">5个文字宽度:85</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">6个文字宽度:104</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">6个文字宽度:102</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">7个文字宽度:121.5</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">7个文字宽度:119</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">8个文字宽度:139</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">8个文字宽度:136</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">9个文字宽度:156</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">9个文字宽度:153</td></tr><tr style="margin:0px; padding:0px"><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">10个文字宽度:173.5</td><td style="margin:0px; padding:3px; border:1px solid silver; border-collapse:collapse">10个文字宽度:170</td></tr></tbody></table><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)"> </p><p style="margin:10px auto; padding-top:0px; padding-bottom:0px; color:rgb(57,57,57); font-family:verdana,"ms song",Arial,Helvetica,sans-serif; font-size:14px; background-color:rgb(250,247,239)">英文字母会不会也有这种问题,我又通过测试,后来发现英文字母没有问题,只有汉字有问题。目前只有一个一个修改控件解决这个问题,暂时没有其他好办法来解决。</p>  
  1. <h4 style="color:rgb(51,51,51); white-space:pre; margin:15px auto 2px; padding:0px; background-color:rgb(250,247,239)"><a name="t24"></a><span style="margin:0px; padding:0px"><span style="font-family:Microsoft YaHei"><span style="font-size:14px">14.</span><span style="font-size:14px"><a target="_blank" href="http://blog.youkuaiyun.com/itiapp_home/article/details/52537541" style="color:rgb(0,0,0); text-decoration:none">升级到Xcode8注释快捷键不能使用的解决</a>方法</span></span></span></h4><div><span style="margin:0px; padding:0px"><span style="font-family:Microsoft YaHei"><span style="font-size:14px">  
  2. </span></span></span></div><div><span style="margin:0px; padding:0px"><span style="font-family:Microsoft YaHei"><span style="font-size:14px"><span style="color:rgb(51,51,51); font-family:Arial; font-size:14px">这个是因为苹果解决xcode ghost。把插件屏蔽了。解决方法</span><br style="color:rgb(51,51,51); font-family:Arial; font-size:14px"><span style="color:rgb(51,51,51); font-family:Arial; font-size:14px">命令运行:  sudo /usr/libexec/xpccachectl </span><br style="color:rgb(51,51,51); font-family:Arial; font-size:14px"><span style="color:rgb(51,51,51); font-family:Arial; font-size:14px">然后必须重启电脑后生效</span>  
  3. </span></span></span></div>  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值