三害淤、將結果轉為 JSON 對象
1,實現方法
(1)如果服務器返回的數據是 json
格式的話拓售,我們可以使用iOS
內置的 JSONSerialization
將其轉成 JSON
對象窥摄,方便我們使用。
//創(chuàng)建URL對象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
//創(chuàng)建請求對象
let request = URLRequest(url: url!)
//創(chuàng)建并發(fā)起請求
URLSession.shared.rx.data(request: request).subscribe(onNext: {
data in
let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
as! [String: Any]
print("--- 請求成功础淤!返回的如下數據 ---")
print(json!)
}).disposed(by: disposeBag)
(2)當然我們在訂閱前就進行轉換也是可以的:
//創(chuàng)建URL對象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
//創(chuàng)建請求對象
let request = URLRequest(url: url!)
//創(chuàng)建并發(fā)起請求
URLSession.shared.rx.data(request: request)
.map {
try JSONSerialization.jsonObject(with: $0, options: .allowFragments)
as! [String: Any]
}
.subscribe(onNext: {
data in
print("--- 請求成功崭放!返回的如下數據 ---")
print(data)
}).disposed(by: disposeBag)
(3)還有更簡單的方法,就是直接使用 RxSwift
提供的 rx.json
方法去獲取數據鸽凶,它會直接將結果轉成 JSON
對象币砂。
//創(chuàng)建URL對象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
//創(chuàng)建請求對象
let request = URLRequest(url: url!)
//創(chuàng)建并發(fā)起請求
URLSession.shared.rx.json(request: request).subscribe(onNext: {
data in
let json = data as! [String: Any]
print("--- 請求成功!返回的如下數據 ---")
print(json )
}).disposed(by: disposeBag)
2玻侥,使用樣例
(1)效果圖
我們將獲取到的豆瓣頻道列表數據轉換成 JSON
對象决摧,并綁定到表格上顯示。
(2)樣例代碼
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
var tableView:UITableView!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創(chuàng)建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創(chuàng)建一個重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)
//創(chuàng)建URL對象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
//創(chuàng)建請求對象
let request = URLRequest(url: url!)
//獲取列表數據
let data = URLSession.shared.rx.json(request: request)
.map{ result -> [[String: Any]] in
if let data = result as? [String: Any],
let channels = data["channels"] as? [[String: Any]] {
return channels
}else{
return []
}
}
//將數據綁定到表格
data.bind(to: tableView.rx.items) { (tableView, row, element) in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(row):\(element["name"]!)"
return cell
}.disposed(by: disposeBag)
}
}
四使碾,將結果映射成自定義對象
1蜜徽,準備工作
(1)要實現數據到模型(model
)的轉換,我們首先需要引入一個第三方的數據模型轉換框架:ObjectMapper
票摇。關于它的安裝配置拘鞋,以及相關說明可以參考航ge之前寫的文章:
(2)為了讓 ObjectMapper
能夠更好地與 RxSwift
配合使用,我們對 Observable
進行擴展(RxObjectMapper.swift
)矢门,增加數據轉模型對象盆色、以及數據轉模型對象數組這兩個方法。
import ObjectMapper
import RxSwift
//數據映射錯誤
public enum RxObjectMapperError: Error {
case parsingError
}
//擴展Observable:增加模型映射方法
public extension Observable where Element:Any {
//將JSON數據轉成對象
public func mapObject< T>(type:T.Type) -> Observable<T> where T:Mappable {
let mapper = Mapper<T>()
return self.map { (element) -> T in
guard let parsedElement = mapper.map(JSONObject: element) else {
throw RxObjectMapperError.parsingError
}
return parsedElement
}
}
//將JSON數據轉成數組
public func mapArray< T>(type:T.Type) -> Observable<[T]> where T:Mappable {
let mapper = Mapper<T>()
return self.map { (element) -> [T] in
guard let parsedArray = mapper.mapArray(JSONObject: element) else {
throw RxObjectMapperError.parsingError
}
return parsedArray
}
}
}
2祟剔,使用樣例
(1)我們還是以前面的豆瓣音樂頻道數據為例隔躲。首先我定義好相關模型(需要實現 ObjectMapper
的 Mappable
協(xié)議,并設置好成員對象與 JSON
屬性的相互映射關系物延。)
//豆瓣接口模型
class Douban: Mappable {
//頻道列表
var channels: [Channel]?
init(){
}
required init?(map: Map) {
}
// Mappable
func mapping(map: Map) {
channels <- map["channels"]
}
}
//頻道模型
class Channel: Mappable {
var name: String?
var nameEn:String?
var channelId: String?
var seqId: Int?
var abbrEn: String?
init(){
}
required init?(map: Map) {
}
// Mappable
func mapping(map: Map) {
name <- map["name"]
nameEn <- map["name_en"]
channelId <- map["channel_id"]
seqId <- map["seq_id"]
abbrEn <- map["abbr_en"]
}
}
(2)下面樣例演示如何獲取數據宣旱,并轉換成對應的模型。
//創(chuàng)建URL對象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
//創(chuàng)建請求對象
let request = URLRequest(url: url!)
//創(chuàng)建并發(fā)起請求
URLSession.shared.rx.json(request: request)
.mapObject(type: Douban.self)
.subscribe(onNext: { (douban: Douban) in
if let channels = douban.channels {
print("--- 共\(channels.count)個頻道 ---")
for channel in channels {
if let name = channel.name, let channelId = channel.channelId {
print("\(name) (id:\(channelId))")
}
}
}
}).disposed(by: disposeBag)
(3)下面樣例演示將數據換成模型叛薯,并綁定到表格上顯示浑吟。
import UIKit
import RxSwift
import RxCocoa
import ObjectMapper
class ViewController: UIViewController {
var tableView:UITableView!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//創(chuàng)建表格視圖
self.tableView = UITableView(frame: self.view.frame, style:.plain)
//創(chuàng)建一個重用的單元格
self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView!)
//創(chuàng)建URL對象
let urlString = "https://www.douban.com/j/app/radio/channels"
let url = URL(string:urlString)
//創(chuàng)建請求對象
let request = URLRequest(url: url!)
//獲取列表數據
let data = URLSession.shared.rx.json(request: request)
.mapObject(type: Douban.self)
.map{ $0.channels ?? []}
//將數據綁定到表格
data.bind(to: tableView.rx.items) { (tableView, row, element) in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
cell.textLabel?.text = "\(row):\(element.name!)"
return cell
}.disposed(by: disposeBag)
}
}