又是一年的 WWDC,如同朝圣一般的大家又是早早就在旧金山 Moscone Center 门前排起了长队。作为第二年参加 WWDC 的我已经不如其他开发者那么激动,提早一天就来排队。但托 肃羽大神 的福(前一天晚上 9 点就来排队的大牛人,虽然他也是第二年参加,但热情不减当年),得到了非常靠前的位置。我自己凌晨四点半到了现场,排到 10 点。最后在 Keynote 坐到了第四排,基本就在舞台底下看了这一场开发者的盛宴。
总的来说今年 iOS9 和 El Capitan 对用户们来说的惊喜并不太多,可能分屏是让我觉得最有用的新功能(也有不少朋友说晃鼠标那个是最有用的)。但是其实作为 iOS 工程师来说新的内容真的还不少,而且很多都是让人挺期待和兴奋的。这里就把几个我个人认为很 Cool 的新内容做一个简单的介绍。
App Thinning
我把这个放在第一个是因为,在 3、4 个版本之前 Gogobot(编者注:作者本人开发的 app)才给自己的 iOS App 做了减肥工作,去除所有不必要的 Assets 和 Library,删除了大量的 legacy code,把所有能 Minify 的 JPG 和 PNG 文件全部做 mini 处理,不同颜色的 icons 基本只留一个用 Code 来上色,等等等等。做了很多努力才把,已经肥胖到直逼“非 WiFi 网络下可下载的临界点的” App 从 94mb 减肥到 43mb 左右。所以我深知 App 体积已经成为 App 开发者的麻烦。
在 iOS 设备碎片化日趋严重的情况下,App 里的 Assets 需要支持各种分辨率,还要为新旧设备的 32bit 和 64bit 做准备。也许 Apple 自己也意识到 App 的体积普遍变得臃肿,总算是时候给所有 App 减减肥了。
1. App Slicing
如同上面提到的,现在 App 中的 Assets 必须支持 1x/2x/3x 的分辨率,但其实每种设备能用到的分辨率就只有一种,为什么要让只需要 3x 分辨率的设备去下载 2x 和 1x 的 Assets?为什么要让只能 run 32bit 的设备下载 64bit 的 Architecture?
有了 App Slicing,只要开发者在开发的过程中使用了 Asset Catelog 并且在里面加入了正确的 Asssets。 比如:
新的 Xcode7 和 App submit 之后会对这些 1x/2x/3x 分辨率的 Assets 做一定的处理,让用户在下载的时候只下载自己所需要的 Assets,这样至少可以在 Assets 上减掉很大一部分的体积。同时用户下载的时候只会下载到自己设备所需要的 Architecture,32bit 或者 64bit。这样又能减小 App 的实际体积。
其实还有一个方法可以近一步减小体积,但并不是每个 App 都会用到。就是在 Asset catalog 中的内容可以按照不同的设备来决定是否下载。
这个可能没有比前一条来的适用面广,但是也提供了一个很好的选择。比如一些大型的游戏或者有 3D 模型的软件。完全可以根据用户设备的性能来提供内容。
2. On Demand Resource
这一条就相对容易理解一些,目前大部分 App 都是把需要的内容和数据全部封装在 App 里面,让用户一次下载到所有需要的内容。我相信很多做游戏的朋友已经知道,这个完全是没有必要的。很多游戏在初期下载只会下载游戏必要的内容,在游戏进行的过程中才会动态的下载更多的内容。
但是在以前的 setup 里面,一般我们都需要自己建立 server 去 host 那些以后需要用到的 resource,然后在用户到一定的阶段就开始多线程下载所需要的 resources,然后做一定的处理。而现在 Apple 用他们自己的 server 来帮助 App 实现这个功能,不再需要繁琐的 server 端的设置,只需要简单的在 Asset catelog 里面把内容加上各种 tag,就可以简单的实现这个功能。提交 App 的时候可以全部打包一起提交,剩下的工作 Apple 会帮你完成。
并且在 target 界面多了一个Resource Tag。可以简单的管理所有 Tag 过的 Resources。
我因为目前还没有时间去仔细测试这个功能,但是从很多 WWDC Session 里的 Demo 看来非常 promising。
不论最后采用什么方法,让 App 的体积变小是一个非常有必要的工作。可以从一定程度上提高 App 的质量。虽然不是所有用户都会在他们下载 App 之前去仔细看一个 App 的体积,但是一个 App 的体积决定了下载所需要的时间。根据不是特别完全的调查,如果下载时间过长,会让用户失去立刻打开这个 App 的兴趣。这样你在不知不觉中就损失了潜在的 pro 用户。
App Deep Linking
不知道现在还有多少开发者对 Deep linking 陌生的,因为“不约而同”的 Facebook, Google, Twitter, Apple 都开始关注和推行 App Deep linking。从之前公布的 Facebook 的 App linking,Twitter 的 Twitter cards,到最近 Google 公布的 App index,然后到 WWDC 上 Apple 公布的 Spotlight search。都是 Deep linking 的一种形势。
从几个版本之前 Gogobot 已经开始对 Deep linking 做很多处理,从邀请朋友加入 App,到分享 Postcard, Place of Internet, weekly recommendation 等等。
这次 WWDC 公布的 iOS9 中的 Spotlight 和 Safari 搜索可以直接搜到 App 内部的内容,Apple 提供了让用户更容易找到他们想要的内容,哪怕这个内容是在某个 App 内部的,从而提高 App 的使用度和曝光度。根据 WWDC 上 Apple 自己公布的数据,用户有 86% 的时间花在 App 中,仅有 14% 的时间花在 Web 上。所以提高 App 的曝光度和使用度可以大大的提高用户的粘度。
从目前公布的内容上看,他们公布了几个实现这个功能的 API,比如 “Core Spotlight”,“NSUserActivity”,”Web markup”。
1. NSUserActivity
其实 NSUserActivity 并不是一个新的概念,在 iOS8 中就已经使用它来做 Handoff,在 iOS9 讲 User Activities 变的可以搜索,并且可以在每个 Activity 里加上 Index 用的 Metadata。但是只能用在用户访问过的或者看见过的内容中。
一旦某些内容被记录进 NSUserActivity,就可以在 Spotlight 和 Safari 中同时被搜索到。而且还能通过设置 “Eligible For Public Indexing” 来让这些被 Index 的内容传到 Apple 的云端 Cloud Index 里,从而实现每个用户都能搜索到这个内容。同时 Apple 也强调了隐私的保护。并不是所有内容都是 Public 的,同一个内容需要在云端被 Index 超过一个限额(具体多少没有公布),才会最后成为 Public 的内容。所以用户不用担心自己看到的内容成为公众都能搜索的内容。
更好的是,一旦 App 中的内容被越来越多的 Index 之后,能够获得 Siri Suggestion 和 Siri smart reminder 功能,当然还有 iOS8 目前就有的 Handoff 功能。可谓是一举多得的一个做法。
2. Core Spotlight
Core Spotlight 是 iOS9 全新的一个 Api。这是一个相对简单的概念,允许 App 在 Device 本地 Index 大量的可搜索的内容,类似一个数据库一样。可以添加/修改/删除 Index 的内容。一般会是推荐 App 内用户的文档,图片,信息,等等内容。
通常可以在内容生成的时候就应该 Index,而且 Apple 还为数据量较大的内容提供了 batching 的 index 方法。
3. Web Markup
最后是 Web markup,比如网站上的内容,如果在 App 中也有的话,在搜索中可以直接显示 App 的信息。
Smart banner
Apple 推荐在每个相关网页中都加入一个 Smart banner,比如:
因为 Apple 已经建立了一个叫做 Apple bot 的爬虫在识别的各个网站内的内容,如果同时有 Smart banner 的话,Apple 就会记录下这个 Banner 内的信息,当用户搜索相关内容时就能直接看到这个 Banner。
Standards-based Markup
除了 Smart banner 还可以使用 Apple 认可的标准格式 Markup,比如 schema.org 或者 Open graph 的结构。这样的好处是可以在每个页面显示更丰富的内容,让用户更直观的看到 App 中的内容。
Universal Link
在 iOS9 中,开发者可以在自己的 App 里加入一个 App 相关的域名 “com.apple.developer.associated-domains”,然后在网站中的 “apple-app-site-association” 文件中加入一个相关的 JSON(详细信息参见: Apple iOS9 Search Universal Link Documentation )。
这样用户在打开某个链接时,如果他已经装有相对应的 App,会利用 App 中设置过的 Handoff 机制自动打开 App 中的内容。即使他没有装 App,也会顺利的进入 Safari 打开原本应该看到的网站。也是一个通过原本打开网页,而现在可以直接打开 App 的方法,给用户更好的体验,从而提高 App 使用度和曝光度。
Apple 在 WWDC 关于搜索的 Session 里面最后还推荐了几点去完善搜索体验。
- 在 NSUserActivity 和 Core Spotlight 的两种 Index 方法中,不论哪种,开发者都会需要提供一定的 Keyword,Apple 推荐每个 Index 的内容至少需要 2-5 个 Keyword。并且要关注缩写和别称等等。
- 在两种不用 Index 方法里,相同的内容要使用相同的 Unique ID。
- 在 Deep linking 到 App 里面之后尽量直接显示内容,Apple 会分析用户点击链接后点击次数和内容来提高和降低搜索结果的评分
- 在搜索的结果中加入必要的 action,比如电话,路线,短信等
- 在搜索额结果中加入合适而且好看的图片,详细的信息等。
Xcode7
其实每年新的 Xcode 都是我比较期待的,因为让我在三四年放弃 Android 认定 iOS,Xcode 在里面起到的很大的作用 (也可以说Eclipse起到了很大的反作用 ╮(╯3╰)╭ )。今年的 Xcode7 也不出意外的有了不少的新功能,除去那些常规的性能上的提升,有几点是让我觉得非常有用的。
1.Xcode Free for ALL!
我只想说还有比这个更让人高兴的么?对普通的学生来说,总算不再需要每年花上 99 美金只为了学习怎么做 iOS App 了。回想当年在留学时候帮学校做着几块钱一个小时的廉价网站开发,为了学 iOS 还必须凑钱买个 Macbook 和这个 99 块钱的 Developer Program。真的是很苦恼。现在虽然 Mac 还是不能省去,可毕竟 Mac 算是一台很不错的笔记本,而且可以使用至少几年。这个开发者 Program 真的是在学习开发阶段毫无意义(你觉得才 99 块钱没省多少?对于一贯抠门的 Apple 来说,知足吧,还要什么自行车)。
Anyway,主要想说的也不是省下这 99 块钱就能把世界变的多美好。但是不论如何降低门槛对于整个行业来说还是很有帮助的,进来的人越多,这个行业发展的速度就越快。形成一个健康的生态环境和良性循环是最重要的。
2. Address Sanitizer
我相信 90% 以上的开发者都会遇到 “EXC_ BAD_ ACCESS” 或者 signal SIGBRT 这类的”非常规” bug。或者你老板跑来说他遇到一个 Crash,但是你尝试了 100 次也不能 reproduce,然后开始痛不欲生的 debug 之旅。
现在 Xcode7 提供了一个也许可以至少提供你一些线索的工具,叫 Address Sanitizer(内存地址清洁剂?名字我随便翻译的),能够帮你找到一些常规 Compiler 没办法帮你找到的 run time bug,比如 deallocated memory,heap buffer overflow/underflow,stack memory overflow 之类的。根据 Apple 的描述,他们对每种结构都有一个独特的做法。但是简单来说,是在你每个 Allocate 的物理内存背后做一个 Shadow memory,在 Shadow memory 中将那些 deallcaoted memory 标记成 redzone,在每次指向内存地址的时候都会检查是否在指向一个 redzone 里面的内存地址,也就是他们所谓的 IsPoisoned。如果是的话就 crash。当然背后的细节做法肯定比听起来复杂的多。
撇开背后的复杂含义,对开发者来说,最有帮助的就是一旦遇到这类的 Crash,Xcode 不会像以前那样仅仅 break 在 Main class 和显示一条不是特别有帮助的 “EXC_ BAD_ ACCESS xxxxxxxx” 的错误信息。有了 Address Sanitizer 的支持 Xcode 会提供具体的 Crash trace 和 break 在具体的 line 上,和提示一条相对好理解的 Error message,比如 “Use of deallocated memory detected”
而且开发者还能看到具体 Memory allocation 和 deallocation 的具体细节。对 Debug 这类 Bug 非常有帮助。
Apple 自己的 Session 中提到,Address Sanitizer 与的 Guard Malloc 和 Valgrind 类似,但是能找到更多的 run time error,还拥有更小的 overhead。所以推荐大家在开发的时候都要打开 Address Sanitizer,这样有备无患。
打开的方法也很简答,就和之前用 Zombie 来 Debug Bad Access 一样。在 Schema->Run->Diagnostics 里面选中 Enable Address Sanitizer 然后再 Run App 就可以了。就如同上面提到过的,因为 Address SanitizerH 和 Guard Malloc 用的类似的技术,一旦选则一个,就不能用使用另一个了。
我会推荐大家同时打开 Zombie 和 Address Sanitizer,这样基本就能覆盖大部分的 Memory 相关的 Bug。Address Sanitizer 虽然并不算一个非常大的创新,但是不论如何只要能把 Debug 的效率提高,让 App 更完善更稳定,让 PM 更舒心,让老板更安心,这样对开发者,用户,PM 和老板都是一件好事。又是一个一举多得的的新功能。
2. UI Test
新的 Xcode7 中 Test Target 不光只有 Testing Bundle,还加入了 UI Testing Bundle。其实 UI Testing 也不能算是一个非常大的创新,因为早在 iOS4 的时代 Profile 里就已经有 UIAutomation,可以用来做相关的 UI 测试。还有比如像 Gogobot 利用 Javascript 写的 Test Class 其实都可以做到。但为什么 5 年之后的 iOS9,Apple 再把它重新做了一遍拿到 Xcode7 中了呢?我相信大家和我猜是一样的,因为他们自己都意识到 UIAutomation 这类不太好用吧。
在 Xcode7 中的 UI Testing 背后的技术是 XCTest 加上 Accessibility,也就是说 XCTest 会通过 Accessibility Identifier 来找到 UI 中相关的控件,然后做相应的操作。基本用过 UIAutomation 的小伙伴就不会对这套模式感到陌生了。然后再通过加上 Assertion 的方法处理一些逻辑上的判断,从而做到一个完整的测试。
至于我特地把他拿出来再写一次的原因也主要是 Record UITest 目前在 Xcode7 中还是比较好用的。简单易懂。基本完全还原了用户操作的过程,而且比较精确。只要建一个 UITest 的 Function,然后打开录制模式,任意在 Simulator 中操作,Xcode 就会顺利把操作内容转化成代码。之后只需要简单的 run 录制好的 Function,就能顺利达到测试的效果。和 Unit Testing 一样可以把他们放在 XCodeServer 中做一并的测试。
他最后生成的 Test report 也和 UIAutomation 类似。会提供简单的错误的信息,和每个步骤上提供一张截图。好好利用 Assertion 来提供更详尽的测试信息和错误提示吧。
Watch OS
Watch OS 也算是今年 WWDC 的一个重点,但其实一点也不出乎大家的意料。因为只要在这之前做过 Watch App 的小伙伴就知道,之前 Watch Kit 能做的东西实在太少,局限性太大。所以推出一个独立的 OS 是理所应当的。我之前甚至考虑是不是要把 Watch OS 做为这篇文章中的一部份,因为说实话,Watch App 现在仍是在探索期间,几乎没有找到特别实用的第三方 App。所以我不觉得单独变成一个 OS 和开放几个基本的 Api 之后能有多大的突破。毕竟穿戴式设备使用场景原本就不多,加上硬件上的局限性比较大,和 Apple 对设计 Layout 的种种的限制,让我自己对开发 Watch App 和使用 Watch App 的热情降低了很多。
之前在 Watch 上市前花了两周把 Gogobot 的 Watch App 完成后也被 Apple 在 Watch App Travel 的版块中被 Feature 了,但是用户反应平平,甚至我自己都很少使用。所以感觉 Watch OS 的改变没有到让我特别感觉到喜大普奔的意思。当然做为手表的使用者和开发者还是希望看到更多更好的 App,可能至少目前还没有特别好的 idea,希望能随着时间的推移有更多更好的 idea 出现。
但是不论如何至少随着 Watch OS 的推出,很多之前原本就应该开放的功能已经可以被开发者使用,比如麦克风,Digital Cronw,Tapic,心跳指数,UI 简单的动画,Wifi,视频等等。同时 App 从一个附属 Extension 变成一个独立的 App,性能上肯定是有不少的提升,但还没有真的装在手表中测试,也不能确定性能提高的体验有多好。
另一个优点是 Watch App 和 iPhone App 之间的交流应该会变的简单些。目前的 App 之间交流都基本是单向的,只能 Watch App 连接到 iPhone App,反过来的话需要 Hack 一个 Warmhole 才行。这一点改变会让开发的空间更大一些。
还有一点让我感到失望的是 Clock face 没有全面向开发者开发,仅仅能开发 Complications 还是没特别大的意义。因为作为手表来说,显而易见的 Watch face 是最常被使用到的,而且 Wacth face 开发的余地很大。比如 Moto 360 上面就有很多很漂亮而且很实用的第三方 Watch face。到现在还掐着这个 Api 不放,Apple 估计也是在为以后的 WWDC 留一点内容吧。
反正总的来说 Wathc OS 给我的感觉还是比较一般的,不知道小伙伴对这个有没有其他看法,或者对 Watch App 有没有好的 Idea,也可以通过微博和微信和我交流看看。
Swift 2.0
Swift 2.0 可能最大的新闻就是开源。对于以保守出名的 Apple 来说,要他们开源一个项目是非常非常困难的。因为 Swift 从去年发布到现在受到的关注大于我听说过的所有新的编程语言语言,而且在 Stackoverflow 上竟然短短一年内成为最受欢迎的语言之一。
开发者对一门语言的热切关注一般是促使这门语言发展的最好趋势,而开源更是对一门编程语言开发速度的最大助力。而且当一门语言开源之后,最常见的就是在不同的平台上的发展,以后可能 Swift 不仅仅用于 iOS 或者 OSX 软件上的开发,而 Xcode 也可能不再是唯一一个 Swift 的 IDE。或者是 Swift++,Swift lite 这类基于 Swift 而产生的扩展性编程语言。总而言之开源对一门原本就有很多关注度的语言来说是最有意义的事情。
就 Swift 语言本身在 2.0 也有了非常大的进步。Swift 1.2 已经达到了一个比较稳定的阶段,2.0 更是将一些原本没有做的特别好的区块做了更大的提升。
比如我最常吐槽的 Error Message 的问题,Swift 对 Compile 的要求非常高的,一些非常小的错误都会导致无法 Compile,但让我头疼的是不能 Compile 时显示的 Error Message 非常烂,常常词不达意或者模棱两可。在 Swift 2.0 里面已经有了很大的修复。
还有对协议的扩展,错误处理的方法,语法的提升,playground 的功能性能进步一加强,让 Comments 支持 Markdown 等等的新内容,都让 Swift 比以前更快速高效和安全。我自己目前也花很多时间在 Swift 的研究和相关内容的编写上。相信不久以后还会有不少内容和大家分享。敬请期待。
总结
连续两年参加 WWDC,都感觉到现在 Mobile 开发的风潮越来越盛。做为移动软件工程师来说还是喜闻乐见的,当然也希望这个风潮能持续。做为领头羊的 Apple 和 Google 都在竭尽所能让大家的移动设备变得越来越丰富,做为开发者的我们也在尽最大的努力把 App 的体验做的更加好。希望一个良性的生态环境让这个产业链持续升温。
最后附上我的粉丝 Tim 和我热情的合照,并且在他要求下,我勉为其难的拿出自己的 Badge 让他签下了自己的名字。(什么,你觉得是反过来的?别那么在意,意思到了就行了!)
题图来自 Techapple
文章配图来自苹果官方网站