親歷WWDC的開發者,讓你看看WWDC的真正干貨
又是一年的 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 陌生的,因為“不約而同”的 非死book, Google, 推ter, Apple 都開始關注和推行 App Deep linking。從之前公布的 非死book 的 App linking,推ter 的 推ter 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
文章配圖來自蘋果官方網站