用RxSwift仿寫知乎日報

loglay 7年前發布 | 8K 次閱讀 RxSwift

用過無數的三方庫,卻仍舊寫不好代碼。以前總會有人問:你用過最好的三方庫是什么?那個時候總是會猶豫半天,到底是哪一個呢?好像都還可以耶,直到后來遇到[ RxSwift ],哇,簡直打開了新世界的大門。現在我會毫不猶豫推薦它,雖然學習曲線有點陡峭,但是一旦你習慣上它,必深陷于其中無法自拔。

初入RxSwift

在公司項目進入版本迭代的時期,總覺得應該學點什么,不然讓拍在沙灘上怎么辦?在學習swift3一段時間后,邂逅了響應式編程方式,看了一下相關文章,毫不猶豫跳入RxSwift的坑中,其中險些放棄,還好堅持下來了,現在也算入了個門。當然只看看理論知識點,光紙上談兵是不行的,所以選擇仿寫知日報的方式來深化一下知識。

- 如果你不熟悉RxSwift相關的知識,可以先看看官方文檔 [ RxSwift ]

- 如果你不知道為什么要使用RxSwift,可以看看 [ why use rx? ]

項目實戰

整個項目持續的大概兩周,遇到不少問題,畢竟不管對于Swift還是RxSwift來說,我大概都只是個新手。

網絡請求 Moya + RxSwift

  • [ API ]:項目的開始當然是看看有沒有API呀,這里要感謝這位通過非正常手段獲取API的同學,為我們總結了完整的[知乎日報-API-分析](https://github.com/izzyleung/ZhihuDailyPurify/wiki/知乎日報-API-分析),我也無私地奉獻了star,略表感謝!

  • [ Alamofire ]:Swift版的AFNetworking。

  • [ Moya ]: 是 Artsy 團隊的 Ash Furrow 主導開發的一個網絡抽象層庫。它在 Alamofire 基礎上提供了一系列簡單的抽象接口,讓客戶端代碼不用去直接調用 Alamofire,也不用去關心 NSURLSession。同時提供了很多實用的功能,包括對RxSwift的良好擴展。

  • [ HandyJSON ]:是一個用于Swift語言中的JSON序列化/反序列化庫。與其他流行的Swift JSON庫相比,HandyJSON的特點是,它支持純swift類,使用也簡單。它反序列化時(把JSON轉換為Model)不要求Model從NSObject繼承(因為它不是基于KVC機制),也不要求你為Model定義一個Mapping函數。只要你定義好Model類,聲明它服從HandyJSON協議,HandyJSON就能自行以各個屬性的屬性名為Key,從JSON串中解析值。HandyJSON目前依賴于從Swift Runtime源碼中推斷的內存規則,任何變動我們將隨時跟進。

  • [ RxSwift ]: 響應式編程三方庫。這里主要處理網絡請求時的各種回調和異步線程。

最終實現效果:

API枚舉:

由于Moya沒有支持HandyJSON擴展,這里我自己實現了此擴展:

只要Model遵循HandyJSON協議,就能很優雅的快速實現JSON->Model,包括嵌套解析:

可以說,這是迄今為止我最滿意的網絡請求封裝,以后都可以愉快處理請求啦????

數據呈現

數據請求處理好了,就該綁定視圖顯示出來了,這里就是RxSwift的拿手好戲了。下面我們先看最簡單的展現:

這樣簡單的幾行代碼就完成網絡請求數據展現以及用戶響應一系列流程,什么代理,擴展都不用寫了,減少了一半以上的代碼,是不是看著就覺得爽炸了!我們再看看復雜一點的,分組tableview:

其實也很簡單,就是需要綁定SectionModel,當然你也可以自定義SectionModel來分組展示,上面的代碼都在項目篩選出來的,具體實現可以看文末項目鏈接。

項目難點

  • 菜單欄與主頁面的切換

由于導航欄一開始用的原生的(其實應該自定義,因為后面涉及到很多導航欄問題),所以左右平移的時候要把導航欄一起移動,所以遇到了一點問題,后來查找相關資料后解決了此問題:

菜單欄的顯示和隱藏需要配合手勢,研究官方知乎日報App后,發現存在輕掃和拖拽滑動兩個手勢,相對應UIPanGestureRecognizer和UISwipeGestureRecognizer,當把這兩個視圖分別加在視圖上的時候,只會響應一個手勢,后來設置UIGestureRecognizerDelegate后避免了這個問題:

本以為就此解決了問題,但是實際操作起來,手機很難區分這個兩個手勢,經常會搞錯,本來想拖拽滑動結果系統識別為了輕掃手勢,體驗效果很差,那怎么辦呢?后來終于找到一種可行方案:**只在視圖上添加UIPanGestureRecognizer,以手指操作時間來區分是輕掃還是拖拽滑動**

菜單欄與主頁面的切換中還有一個不好處理的點,當選中菜單欄某個主題后,要推出一個主題日報列表,與首頁不同屬于一個UINavigationController,那怎么從一個UINavigationController到另一個UINavigationController呢?試了好幾種方式來切換,始終達不到官方效果,忙碌了一天,最后靈光一現(也可能是我太蠢????)平常不是都用UITabBarController來切換UINavigationController?!真的好簡單,隱藏掉tabbar就好,幾句代碼就完美解決了這個場景切換問題:

如果你有更好的切換方法請聯系我,愿意請你喝咖啡。

2. 文章的快速切換

文章詳情是用UIWebView加載html數據來展現的,這里我自定義class DetailWebView: UIWebView,以便于兩個文章詳情的切換,用于顯示文章詳情的DetailViewController包含兩個DetailWebView,一個webview用于展示當前頁面,另一個previousWeb放在屏幕外準備隨時切換文章,當發生切換文章時,動畫呈現previousWeb,并在后續移除在屏幕外webview,把previousWeb作為新的webview,同時生成新的previousWeb

3.首頁刷新

Swift版的刷新控件三方還沒找比較好的,一度打算自己封裝一個,但是一直拖著,以后應該會寫。

知乎日報的刷新控件與一般放在tableview上不同,它應該是放在導航欄上面,配合tableview來實現刷新,這也是前面為什么說導航欄要自定義的原因之一,因為已經用了原生的導航欄,只好巧妙(偷懶)加在了view上,其實這個刷新就是一個畫圓圈的過程。

注意事項

  • 項目中關于時間的處理用的是 [ SwiftDate ]

  • .then 語法用的是 [ Then ],小而妙,很喜歡

 

 

 本文由用戶 loglay 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!