RxSwift + Moya + ObjectMapper
https://www.jianshu.com/p/173915b943af
use_frameworks!
target 'RXDemo' do
pod 'RxSwift'
pod 'RxCocoa'
pod 'Moya-ObjectMapper/RxSwift'
pod 'Moya/RxSwift'
end
import Moya
let DouBanProvider = MoyaProvider<DouBanAPI>()
public enum DouBanAPI {
case channels //获取频道列表
case playlist(String) //获取歌曲
}
extension DouBanAPI: TargetType {
public var baseURL: URL {
switch self {
case .channels:
return URL(string: "https://www.douban.com")!
case .playlist(_):
return URL(string: "https://douban.fm")!
}
}
public var path: String {
switch self {
case .channels:
return "/j/app/radio/channels"
case .playlist(_):
return "/j/mine/playlist"
}
}
public var method: Moya.Method {
return .get
}
public var task: Task {
switch self {
case .playlist(let channel):
var params: [String: Any] = [:]
params["channel"] = channel
params["type"] = "n"
params["from"] = "mainsite"
return .requestParameters(parameters: params,
encoding: URLEncoding.default)
default:
return .requestPlain
}
}
public var validate: Bool {
return false
}
public var sampleData: Data {
return "{}".data(using: String.Encoding.utf8)!
}
public var headers: [String: String]? {
return nil
}
}
import UIKit
import ObjectMapper
//豆瓣接口模型
struct Douban: Mappable {
//频道列表
var channels: [Channel]?
init?(map: Map) { }
// Mappable
mutating func mapping(map: Map) {
channels <- map["channels"]
}
}
//频道模型
struct Channel: Mappable {
var name: String?
var nameEn:String?
var channelId: String?
var seqId: Int?
var abbrEn: String?
init?(map: Map) { }
// Mappable
mutating func mapping(map: Map) {
name <- map["name"]
nameEn <- map["name_en"]
channelId <- map["channel_id"]
seqId <- map["seq_id"]
abbrEn <- map["abbr_en"]
}
}
//歌曲列表模型
struct Playlist: Mappable {
var r: Int!
var isShowQuickStart: Int!
var song:[Song]!
init?(map: Map) { }
// Mappable
mutating func mapping(map: Map) {
r <- map["r"]
isShowQuickStart <- map["is_show_quick_start"]
song <- map["song"]
}
}
//歌曲模型
struct Song: Mappable {
var title: String!
var artist: String!
init?(map: Map) { }
// Mappable
mutating func mapping(map: Map) {
title <- map["title"]
artist <- map["artist"]
}
}
let data = DouBanProvider.rx.request(.channels)
.mapObject(Douban.self)
.map { $0.channels ?? [] }
.asObservable()
data.bind(to: self.tableView.rx.items) { tableView, _, channel in
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier")!
cell.textLabel?.text = channel.name
cell.accessoryType = .disclosureIndicator
return cell
}.disposed(by: self.disposeBag)
tableView.rx.modelSelected(Channel.self)
.map{ $0.channelId ?? "" }
.flatMap { DouBanProvider.rx.request(.playlist($0)) }
.mapObject(Playlist.self)
.subscribe(onNext: { [weak self] (playList) in
if playList.song != nil && playList.song.count > 0 {
let artist = playList.song[0].artist!
let title = playList.song[0].title!
let message = "歌手:\(artist)\n歌曲:\(title)"
self?.showAlert(title: "歌曲信息", message: message)
}
}).disposed(by: self.disposeBag)
import RxSwift
import RxCocoa
import ObjectMapper
class DoubanService {
//获取频道数据
func loadChannels() -> Observable<[Channel]> {
return DouBanProvider.rx.request(.channels)
.mapObject(Douban.self)
.map{ $0.channels ?? [] }
.asObservable()
}
//获取歌曲列表数据
func loadPlaylist(channelId: String) -> Observable<Playlist> {
return DouBanProvider.rx.request(.playlist(channelId))
.mapObject(Playlist.self)
.asObservable()
}
//获取频道下第一首歌曲
func loadFirstSong(channelId: String) -> Observable<Song> {
return loadPlaylist(channelId: channelId)
.filter{ $0.song != nil && $0.song.count > 0}
.map{ $0.song[0] }
}
}
import UIKit
import RxSwift
import RxCocoa
class MusicViewController: UIViewController {
private var viewModel = MusicListViewModel()
private var disposeBag = DisposeBag()
private lazy var tableView: UITableView = {
let tableView = UITableView(frame: self.view.bounds)
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
tableView.tableFooterView = UIView()
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
self.view.addSubview(self.tableView)
let service = DoubanService()
//获取列表数据
let data = service.loadChannels()
//将数据绑定到表格
data.bind(to: tableView.rx.items) { (tableView, row, element) in
let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier")!
cell.textLabel?.text = "\(element.name!)"
cell.accessoryType = .disclosureIndicator
return cell
}.disposed(by: disposeBag)
//单元格点击
tableView.rx.modelSelected(Channel.self)
.map{ $0.channelId ?? "" }
.flatMap(service.loadFirstSong)
.subscribe(onNext: {[weak self] song in
//将歌曲信息弹出显示
let message = "歌手:\(song.artist!)\n歌曲:\(song.title!)"
self?.showAlert(title: "歌曲信息", message: message)
}).disposed(by: disposeBag)
}
//显示消息
func showAlert(title:String, message:String) {
let alertController = UIAlertController(title: title,
message: message, preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
alertController.addAction(cancelAction)
self.present(alertController, animated: true, completion: nil)
}
}
RxSwift + Moya + ObjectMapper的更多相关文章
- 基于Moya、RxSwift和ObjectMapper优雅实现REST API请求
在Android开发中有非常强大的 Retrofit 请求,结合RxJava可以非常方便实现 RESTful API 网络请求.在 iOS开发中也有非常强大的网络请求库 Moya ,Moya是一个基于 ...
- Moya 与 RxSwift 使用
如在OC中使用AFNetworking一般,Swift我们用Alamofire来做网络库.而Moya在Alamofire的基础上又封装了一层: 1.关于moya moya 官方说moya有以下特性-_ ...
- 移动APP开发框架盘点
移动APP开发框架盘点 总体概述 现在比较流行的移动APP开发框架有以下六种:网页.混合.渐进.原生.桥接.自绘.前三种体验与Web的体验相似,后三种与原生APP的体验相似.这六种框架形式,都有自己适 ...
- Moya/RxSwift/ObjectMapper/Alamofire开发
废话不多说直接上代码 // // MoyaNetWorking.swift // GreenAir // // Created by BruceAlbert on 2017/9/18. // Copy ...
- Swift网络封装库Moya中文手册之RxSwift
RxSwift Maya提供了一个可选的MoyaProvider 子类 - RxMoyaProvider.在网络请求完成时,我们不再使用 request() 函数的回调闭包,而是使用 Observab ...
- Swift高仿iOS网易云音乐Moya+RxSwift+Kingfisher+MVC+MVVM
效果 列文章目录 因为目录比较多,每次更新这里比较麻烦,所以推荐点击到主页,然后查看iOS Swift云音乐专栏. 目简介 这是一个使用Swift(还有OC版本)语言,从0开发一个iOS平台,接近企业 ...
- Moya 浅析
Moya是一个高度抽象的网络库,他的理念是让你不用关心网络请求的底层的实现细节,只用定义你关心的业务.且Moya采用桥接和组合来进行封装(默认桥接了Alamofire),使得Moya非常好扩展,让你不 ...
- 从nsurlsession、Alamofire到moya
更好的理解(抽象).更少的构建(配置).更方便的表达(语言) 一.iOS系统的网络编程(DSL概念) ios缺省的网络编程只是给出了网络编程的基本概念: urlsession.request.resp ...
- Jackson ObjectMapper类使用解析
/** * Jackson ObjectMapper类 */ //ObjectMapper类是Jackson库的主要类.它提供一些功能将转换成Java对象匹配JSON结构,反之亦然.它使用JsonPa ...
随机推荐
- torch.utils.data.DataLoader对象中的迭代操作
关于迭代器等概念参考:https://www.cnblogs.com/zf-blog/p/10613533.html 关于pytorch中的DataLoader类参考:https://blog.csd ...
- 分享超好用的截动图工具ScreenToGif
安装很简单,首先看看本地是否安装了.Net Framework 4.6.1,没有就在微软官网搜一下,选[离线安装包]版本 下载安装后,直接安装ScreenToGif即可使用(有绿色版,免安装) htt ...
- zabbix3.2监控mongodb
模板地址:https://share.zabbix.com/databases/mongodb/mongodb-for-zabbix-3-2 .安装jq依赖 # yum install jq -y . ...
- kafka知识点详解
第一部分:kafka概述 一.定义(消息引擎系统) 一句话概括kafka的核心功能就是:高性能的消息发送与高性能的消息消费. kafka刚推出的时候是以消息引擎的身份出现的,它具有强大的消息传输效率和 ...
- djjango安装及其 操作命令
一 首先掌握HTTP协议 HTTP四大特性: 1 基于tcp/IP作用在应用层之上的协议 2 基于请求响应 3 无状态(不识别来的用户的状态) 4 无连接(请求完返回响应后就断开) 数据格式: 请求 ...
- 金蝶K3 WISE BOM多级展开_销售成本表
/****** Object: StoredProcedure [dbo].[pro_bobang_SaleCost] Script Date: 07/29/2015 16:13:43 ******/ ...
- 安装 Docker <一>
一.docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制, ...
- Python WMI获取Windows系统信息
#!/usr/bin/env python # -*- coding: utf-8 -*- #http://www.cnblogs.com/liu-ke/ import wmi import os i ...
- 【转】Spring总结以及在面试中的一些问题
[转]Spring总结以及在面试中的一些问题. 1.谈谈你对spring IOC和DI的理解,它们有什么区别? IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建 ...
- docker 常用启动命令
数据库 # mongo sudo docker run -d -p 27017:27017 -v mongo_configdb:/data/configdb -v mongo_db:/data/db ...