小碼哥-玩轉【鬥魚直播APP】系列之請求展示推薦數據

請求推薦數據

請求方式: AFNetworking&Alamofire?

  • 目前在iOS開發中, 請求網絡數據, 我們經常會使用第三方框架. 而比較出名的莫過於AFNetworking
  • 不過AFNetworking是使用OC開發的框架,作者又專門針對Swift開發了另外一個框架就是:Alamofire。
  • 因爲我們該項目是Swift版本,所有直接採用Alamofire
    • 注:其實Alamofire非常強大,不過我們這裏只是發送請求,使用起來是非常方便的。

集成Alamofire

  • 在iOS開發中,如果我們集成一個第三方框架,通常會使用Cocoapods
  • 因此,我們這裏通過Cocoapods進行集成
  • 找到項目所在目錄:
  • 打開終端:
    • 進入項目目錄,執行:pod init操作
    • 之後會生成Profile文件,打開Profile文件(記事本、Xcode打開即可,推薦Xcode打開)
    • 將下面代碼粘貼過去
    • 回到終端,執行pod install --no-repo-update命令
    • 關閉程序,通過工作空間打開項目
  1. platform :ios, '8.0'
  2. use_frameworks!
  3. target 'DYZB' do
  4. pod 'Alamofire'
  5. end

工具類的封裝

  • 在實際開發中,爲了不過於依賴某一個第三方框架,我們經常會在使用的方式封裝到某一個工具類中,以便於某天該框架不更新時不至於很多地方都需要修改。
    • 比如之前的ASIHTTPRequest就出現了不更新的情況
  • 因此,我們在使用之前先封裝一個簡單的工具類。之後在其它任何地方發送網絡請求,都依賴於自己的工具類。如果某一天該框架不再更新,我們希望更換框架,只修改工具類中代碼即可。
  • 創建工具類:NetworkTools
    • 爲工具類提供類方法,方便調用
    • 請求時,需要傳入請求方式、地址(URL)、參數(parameters)、回調閉包
    • 在請求方法中,使用Alamofire發送網絡請求
  1. import UIKit
  2. import Alamofire
  3. enum MethodType {
  4. case GET
  5. case POST
  6. }
  7. class NetworkTools {
  8. }
  9. extension NetworkTools {
  10. // 封裝請求方法
  11. class func requestData(type : MethodType, urlString : String, parameters : [String : AnyObject], finishedCallback : (result : AnyObject) -> ()) {
  12. // 判斷請求範式
  13. let method = type == .GET ? Alamofire.Method.GET : Alamofire.Method.POST
  14. // 發送請求,並且將請求到的數據回調
  15. Alamofire.request(method, urlString, parameters: parameters).responseJSON { (respose) in
  16. guard let result = respose.result.value else {
  17. print(respose.result.error)
  18. return
  19. }
  20. finishedCallback(result: result)
  21. }
  22. }
  23. }

MVVM介紹

  • 前面環境配置完成後,我們要請求首頁數據。
  • 數據請求在哪裏發送了?

MVC模式

  • Model-View-Controller是一個Apple官方推薦的權威範式。
    • 蘋果使用的MVC的定義是這麼說的:所有的對象都可以被歸類爲一個model,一個view,或是一個controller。
  • 那麼把網絡代碼放哪裏?
    • 我們知道,因爲控制器是一個大管家,那麼不知道如何安放的代碼就放置在控制器中
    • 是的,傳統的MVC方式我們經常這麼做。
  • 該做法的弊端在哪裏?
    • 由於大量的代碼被放進view controller,導致控制器變的相當臃腫。
    • 在iOS開發中有的view controller裏綿延成千上萬行代碼的事並不是前所未見的
    • 厚重的View Controller很難維護(由於其龐大的規模);包含幾十個屬性,使他們的狀態難以管理;遵循許多協議(protocol),導致協議的響應代碼和controller的邏輯代碼混淆在一起。
  • 那麼究竟應該放在哪裏?
    • 顯然MVC的3大組件根本沒有適合放這些代碼的地方。

MVVM模式

  • MVVM來自微軟。和MVC很像,並且引入新的組件ViewModel
    • view model是一個放置用戶輸入驗證邏輯,視圖顯示邏輯,發起網絡請求和其他各種各樣的代碼的極好的地方。
    • 由於展示邏輯放在了view model中(比如網絡請求、請求後的數據解析等等),視圖控制器本身就會不再臃腫。
  • 因此,該項目中的請求數據,統一交給ViewModel管理。每一個控制器對應一個屬於自己的ViewModel。

發送網絡請求

接口解析

  • 在推薦的數據展示中,有三個請求
    • 最熱數據請求
    • 顏值數據請求
    • 其它數據請求
  • 因此我們需要分別發送三個請求,並且當所有的請求數據拿到之後,對數據進行整理分組排序。(因爲界面中有用到分組)
  • 因此請求分成五步曲
    • 請求遊戲數據,並且轉成模型對象
    • 請求顏值數據,並且轉成模型對象
    • 請求熱門數據,並且轉成模型對象
    • 對數據進行整理,並且放入大的數組中
    • 將數據傳遞給外面控制器,展示數據

接口描述

參數名稱 參數說明
time 獲取當前時間的字符串
limit 獲取數據的個數
offset 偏移的數據量
參數名稱 參數說明
time 獲取當前時間的字符串
limit 獲取數據的個數
offset 偏移的數據量
參數名稱 參數說明
time 獲取當前時間的字符串
  1. class RecommendViewModel: NSObject {
  2. lazy var anchorGroups = [AnchorGroup]()
  3. private lazy var hotAnchorGroup = AnchorGroup()
  4. private lazy var prettyAnchorGroup = AnchorGroup()
  5. }
  6. extension RecommendViewModel {
  7. func requestRecommendData(RecommendDataCallback : () -> ()) {
  8. // 0.定義處理閉包
  9. func parserData(result : AnyObject) -> [[String : NSObject]]? {
  10. // 1.將結果轉成字典
  11. guard let resultDict = result as? [String : NSObject] else { return nil }
  12. // 2.通過data的key取出對應的數組
  13. return resultDict["data"] as? [[String : NSObject]]
  14. }
  15. // 1.請求熱門數據
  16. let group = dispatch_group_create()
  17. dispatch_group_enter(group)
  18. NetworkTools.requestData(.GET, urlString: "http://capi.douyucdn.cn/api/v1/getbigDataRoom", parameters: ["time" : NSDate.getNowTimeString()]) { (result) in
  19. // 1.獲取解析的字典數據
  20. guard let dictArray = parserData(result) else { return }
  21. // 2.創建對象
  22. self.hotAnchorGroup.tag_name = "熱門"
  23. self.hotAnchorGroup.icon_name = "home_header_hot"
  24. var tempArray = [AnchorModel]()
  25. for dict in dictArray {
  26. tempArray.append(AnchorModel(dict: dict))
  27. }
  28. self.hotAnchorGroup.anchors = tempArray
  29. dispatch_group_leave(group)
  30. }
  31. // 2.請求顏值數據
  32. dispatch_group_enter(group)
  33. NetworkTools.requestData(.GET, urlString: "http://capi.douyucdn.cn/api/v1/getVerticalRoom", parameters: ["limit":"4", "offset" : "0", "time" : NSDate.getNowTimeString()]) { (result) in
  34. // 1.獲取解析的字典數據
  35. guard let dictArray = parserData(result) else { return }
  36. // 2.創建對象
  37. self.prettyAnchorGroup.tag_name = "顏值"
  38. self.prettyAnchorGroup.icon_name = "home_header_phone"
  39. var tempArray = [AnchorModel]()
  40. for dict in dictArray {
  41. tempArray.append(AnchorModel(dict: dict))
  42. }
  43. self.prettyAnchorGroup.anchors = tempArray
  44. dispatch_group_leave(group)
  45. }
  46. // 3.請求遊戲數據
  47. dispatch_group_enter(group)
  48. NetworkTools.requestData(.GET, urlString: "http://capi.douyucdn.cn/api/v1/getHotCate", parameters: ["limit":"4", "offset" : "0", "time" : NSDate.getNowTimeString()]) { (result) in
  49. // 1.獲取解析的字典數據
  50. guard let dictArray = parserData(result) else { return }
  51. // 2.解析數據
  52. for dict in dictArray {
  53. self.anchorGroups.append(AnchorGroup(dict: dict))
  54. }
  55. dispatch_group_leave(group)
  56. }
  57. // 4.所有數據加載完成
  58. dispatch_group_notify(group, dispatch_get_main_queue()) {
  59. self.anchorGroups.insert(self.prettyAnchorGroup, atIndex: 0)
  60. self.anchorGroups.insert(self.hotAnchorGroup, atIndex: 0)
  61. RecommendDataCallback()
  62. }
  63. }
  64. }

展示數據

普通數據展示(文本數據)

  • 將數據回調給控制器後,控制器拿到數據展示數據即可
    • 將Cell中的控件拖入屬性
    • 定義模型對象
  • 在控制器中拿到模型,並且將模型傳入給Cell進行展示

圖片數據展示

  • 在設置網絡圖片時,OC中經常使用SDWebImage框架。
  • 相同的原因,我們使用的Swift項目,因此這裏我使用onevcat, 也就是喵神寫的Kingfisher
  • 在Profile中加入框架, 並且執行安裝命令
    • pod install —no-repo-update
  1. platform :ios, '8.0'
  2. use_frameworks!
  3. target 'DYZB' do
  4. pod 'Alamofire'
  5. pod 'Kingfisher'
  6. end
  • 使用代碼
  1. srcImageView.kf_setImageWithURL(NSURL(string: anchor?.vertical_src ?? "")!)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章