請求推薦數據
請求方式: 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
命令 - 關閉程序,通過
工作空間
打開項目
- 進入項目目錄,執行:
platform :ios, '8.0'
use_frameworks!
target 'DYZB' do
pod 'Alamofire'
end
工具類的封裝
- 在實際開發中,爲了不過於依賴某一個第三方框架,我們經常會在使用的方式封裝到某一個工具類中,以便於某天該框架不更新時不至於很多地方都需要修改。
- 比如之前的ASIHTTPRequest就出現了不更新的情況
- 因此,我們在使用之前先封裝一個簡單的工具類。之後在其它任何地方發送網絡請求,都依賴於自己的工具類。如果某一天該框架不再更新,我們希望更換框架,只修改工具類中代碼即可。
- 創建工具類:NetworkTools
- 爲工具類提供類方法,方便調用
- 請求時,需要傳入請求方式、地址(URL)、參數(parameters)、回調閉包
- 在請求方法中,使用Alamofire發送網絡請求
import UIKit
import Alamofire
enum MethodType {
case GET
case POST
}
class NetworkTools {
}
extension NetworkTools {
// 封裝請求方法
class func requestData(type : MethodType, urlString : String, parameters : [String : AnyObject], finishedCallback : (result : AnyObject) -> ()) {
// 判斷請求範式
let method = type == .GET ? Alamofire.Method.GET : Alamofire.Method.POST
// 發送請求,並且將請求到的數據回調
Alamofire.request(method, urlString, parameters: parameters).responseJSON { (respose) in
guard let result = respose.result.value else {
print(respose.result.error)
return
}
finishedCallback(result: result)
}
}
}
MVVM介紹
- 前面環境配置完成後,我們要請求首頁數據。
- 數據請求在哪裏發送了?
MVC模式
- Model-View-Controller是一個Apple官方推薦的權威範式。
- 蘋果使用的MVC的定義是這麼說的:所有的對象都可以被歸類爲一個model,一個view,或是一個controller。
- 那麼把網絡代碼放哪裏?
- 我們知道,因爲控制器是一個大管家,那麼不知道如何安放的代碼就放置在控制器中
- 是的,傳統的MVC方式我們經常這麼做。
- 該做法的弊端在哪裏?
- 由於大量的代碼被放進view controller,導致控制器變的相當臃腫。
- 在iOS開發中有的view controller裏綿延成千上萬行代碼的事並不是前所未見的
- 厚重的View Controller很難維護(由於其龐大的規模);包含幾十個屬性,使他們的狀態難以管理;遵循許多協議(protocol),導致協議的響應代碼和controller的邏輯代碼混淆在一起。
- 那麼究竟應該放在哪裏?
- 顯然MVC的3大組件根本沒有適合放這些代碼的地方。
- 顯然MVC的3大組件根本沒有適合放這些代碼的地方。
MVVM模式
- MVVM來自微軟。和MVC很像,並且引入新的組件ViewModel
- view model是一個放置用戶輸入驗證邏輯,視圖顯示邏輯,發起網絡請求和其他各種各樣的代碼的極好的地方。
- 由於展示邏輯放在了view model中(比如網絡請求、請求後的數據解析等等),視圖控制器本身就會不再臃腫。
- 因此,該項目中的請求數據,統一交給ViewModel管理。每一個控制器對應一個屬於自己的ViewModel。
發送網絡請求
接口解析
- 在推薦的數據展示中,有三個請求
- 最熱數據請求
- 顏值數據請求
- 其它數據請求
- 因此我們需要分別發送三個請求,並且當所有的請求數據拿到之後,對數據進行整理分組排序。(因爲界面中有用到分組)
- 因此請求分成五步曲
- 請求遊戲數據,並且轉成模型對象
- 請求顏值數據,並且轉成模型對象
- 請求熱門數據,並且轉成模型對象
- 對數據進行整理,並且放入大的數組中
- 將數據傳遞給外面控制器,展示數據
接口描述
- 接口名稱:熱門數據(後面熱門遊戲)
- 接口地址:http://capi.douyucdn.cn/api/v1/getHotCate
- 請求參數:
參數名稱 | 參數說明 |
---|---|
time | 獲取當前時間的字符串 |
limit | 獲取數據的個數 |
offset | 偏移的數據量 |
- 接口名稱:顏值數據(第二組顏值數據)
- 接口地址:http://capi.douyucdn.cn/api/v1/getVerticalRoom
- 請求參數:
參數名稱 | 參數說明 |
---|---|
time | 獲取當前時間的字符串 |
limit | 獲取數據的個數 |
offset | 偏移的數據量 |
- 接口名稱:大數據數據(第一組熱門數據)
- 接口地址:http://capi.douyucdn.cn/api/v1/getbigDataRoom
- 請求參數:</br>
參數名稱 | 參數說明 |
---|---|
time | 獲取當前時間的字符串 |
class RecommendViewModel: NSObject {
lazy var anchorGroups = [AnchorGroup]()
private lazy var hotAnchorGroup = AnchorGroup()
private lazy var prettyAnchorGroup = AnchorGroup()
}
extension RecommendViewModel {
func requestRecommendData(RecommendDataCallback : () -> ()) {
// 0.定義處理閉包
func parserData(result : AnyObject) -> [[String : NSObject]]? {
// 1.將結果轉成字典
guard let resultDict = result as? [String : NSObject] else { return nil }
// 2.通過data的key取出對應的數組
return resultDict["data"] as? [[String : NSObject]]
}
// 1.請求熱門數據
let group = dispatch_group_create()
dispatch_group_enter(group)
NetworkTools.requestData(.GET, urlString: "http://capi.douyucdn.cn/api/v1/getbigDataRoom", parameters: ["time" : NSDate.getNowTimeString()]) { (result) in
// 1.獲取解析的字典數據
guard let dictArray = parserData(result) else { return }
// 2.創建對象
self.hotAnchorGroup.tag_name = "熱門"
self.hotAnchorGroup.icon_name = "home_header_hot"
var tempArray = [AnchorModel]()
for dict in dictArray {
tempArray.append(AnchorModel(dict: dict))
}
self.hotAnchorGroup.anchors = tempArray
dispatch_group_leave(group)
}
// 2.請求顏值數據
dispatch_group_enter(group)
NetworkTools.requestData(.GET, urlString: "http://capi.douyucdn.cn/api/v1/getVerticalRoom", parameters: ["limit":"4", "offset" : "0", "time" : NSDate.getNowTimeString()]) { (result) in
// 1.獲取解析的字典數據
guard let dictArray = parserData(result) else { return }
// 2.創建對象
self.prettyAnchorGroup.tag_name = "顏值"
self.prettyAnchorGroup.icon_name = "home_header_phone"
var tempArray = [AnchorModel]()
for dict in dictArray {
tempArray.append(AnchorModel(dict: dict))
}
self.prettyAnchorGroup.anchors = tempArray
dispatch_group_leave(group)
}
// 3.請求遊戲數據
dispatch_group_enter(group)
NetworkTools.requestData(.GET, urlString: "http://capi.douyucdn.cn/api/v1/getHotCate", parameters: ["limit":"4", "offset" : "0", "time" : NSDate.getNowTimeString()]) { (result) in
// 1.獲取解析的字典數據
guard let dictArray = parserData(result) else { return }
// 2.解析數據
for dict in dictArray {
self.anchorGroups.append(AnchorGroup(dict: dict))
}
dispatch_group_leave(group)
}
// 4.所有數據加載完成
dispatch_group_notify(group, dispatch_get_main_queue()) {
self.anchorGroups.insert(self.prettyAnchorGroup, atIndex: 0)
self.anchorGroups.insert(self.hotAnchorGroup, atIndex: 0)
RecommendDataCallback()
}
}
}
展示數據
普通數據展示(文本數據)
- 將數據回調給控制器後,控制器拿到數據展示數據即可
- 將Cell中的控件拖入屬性
- 定義模型對象
- 在控制器中拿到模型,並且將模型傳入給Cell進行展示
圖片數據展示
- 在設置網絡圖片時,OC中經常使用SDWebImage框架。
- 相同的原因,我們使用的Swift項目,因此這裏我使用
onevcat
, 也就是喵神
寫的Kingfisher
- 在Profile中加入框架, 並且執行安裝命令
- pod install —no-repo-update
platform :ios, '8.0'
use_frameworks!
target 'DYZB' do
pod 'Alamofire'
pod 'Kingfisher'
end
- 使用代碼
srcImageView.kf_setImageWithURL(NSURL(string: anchor?.vertical_src ?? "")!)