https://www.jianshu.com/p/173915b943af

  1. use_frameworks!
  2. target 'RXDemo' do
  3. pod 'RxSwift'
  4. pod 'RxCocoa'
  5. pod 'Moya-ObjectMapper/RxSwift'
  6. pod 'Moya/RxSwift'
  7. end
  1. import Moya
  2. let DouBanProvider = MoyaProvider<DouBanAPI>()
  3. public enum DouBanAPI {
  4. case channels //获取频道列表
  5. case playlist(String) //获取歌曲
  6. }
  7. extension DouBanAPI: TargetType {
  8. public var baseURL: URL {
  9. switch self {
  10. case .channels:
  11. return URL(string: "https://www.douban.com")!
  12. case .playlist(_):
  13. return URL(string: "https://douban.fm")!
  14. }
  15. }
  16. public var path: String {
  17. switch self {
  18. case .channels:
  19. return "/j/app/radio/channels"
  20. case .playlist(_):
  21. return "/j/mine/playlist"
  22. }
  23. }
  24. public var method: Moya.Method {
  25. return .get
  26. }
  27. public var task: Task {
  28. switch self {
  29. case .playlist(let channel):
  30. var params: [String: Any] = [:]
  31. params["channel"] = channel
  32. params["type"] = "n"
  33. params["from"] = "mainsite"
  34. return .requestParameters(parameters: params,
  35. encoding: URLEncoding.default)
  36. default:
  37. return .requestPlain
  38. }
  39. }
  40. public var validate: Bool {
  41. return false
  42. }
  43. public var sampleData: Data {
  44. return "{}".data(using: String.Encoding.utf8)!
  45. }
  46. public var headers: [String: String]? {
  47. return nil
  48. }
  49. }
  1. import UIKit
  2. import ObjectMapper
  3. //豆瓣接口模型
  4. struct Douban: Mappable {
  5. //频道列表
  6. var channels: [Channel]?
  7. init?(map: Map) { }
  8. // Mappable
  9. mutating func mapping(map: Map) {
  10. channels <- map["channels"]
  11. }
  12. }
  13. //频道模型
  14. struct Channel: Mappable {
  15. var name: String?
  16. var nameEn:String?
  17. var channelId: String?
  18. var seqId: Int?
  19. var abbrEn: String?
  20. init?(map: Map) { }
  21. // Mappable
  22. mutating func mapping(map: Map) {
  23. name <- map["name"]
  24. nameEn <- map["name_en"]
  25. channelId <- map["channel_id"]
  26. seqId <- map["seq_id"]
  27. abbrEn <- map["abbr_en"]
  28. }
  29. }
  30. //歌曲列表模型
  31. struct Playlist: Mappable {
  32. var r: Int!
  33. var isShowQuickStart: Int!
  34. var song:[Song]!
  35. init?(map: Map) { }
  36. // Mappable
  37. mutating func mapping(map: Map) {
  38. r <- map["r"]
  39. isShowQuickStart <- map["is_show_quick_start"]
  40. song <- map["song"]
  41. }
  42. }
  43. //歌曲模型
  44. struct Song: Mappable {
  45. var title: String!
  46. var artist: String!
  47. init?(map: Map) { }
  48. // Mappable
  49. mutating func mapping(map: Map) {
  50. title <- map["title"]
  51. artist <- map["artist"]
  52. }
  53. }
  1. let data = DouBanProvider.rx.request(.channels)
  2. .mapObject(Douban.self)
  3. .map { $0.channels ?? [] }
  4. .asObservable()
  5. data.bind(to: self.tableView.rx.items) { tableView, _, channel in
  6. let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier")!
  7. cell.textLabel?.text = channel.name
  8. cell.accessoryType = .disclosureIndicator
  9. return cell
  10. }.disposed(by: self.disposeBag)
  11. tableView.rx.modelSelected(Channel.self)
  12. .map{ $0.channelId ?? "" }
  13. .flatMap { DouBanProvider.rx.request(.playlist($0)) }
  14. .mapObject(Playlist.self)
  15. .subscribe(onNext: { [weak self] (playList) in
  16. if playList.song != nil && playList.song.count > 0 {
  17. let artist = playList.song[0].artist!
  18. let title = playList.song[0].title!
  19. let message = "歌手:\(artist)\n歌曲:\(title)"
  20. self?.showAlert(title: "歌曲信息", message: message)
  21. }
  22. }).disposed(by: self.disposeBag)
  1. import RxSwift
  2. import RxCocoa
  3. import ObjectMapper
  4. class DoubanService {
  5. //获取频道数据
  6. func loadChannels() -> Observable<[Channel]> {
  7. return DouBanProvider.rx.request(.channels)
  8. .mapObject(Douban.self)
  9. .map{ $0.channels ?? [] }
  10. .asObservable()
  11. }
  12. //获取歌曲列表数据
  13. func loadPlaylist(channelId: String) -> Observable<Playlist> {
  14. return DouBanProvider.rx.request(.playlist(channelId))
  15. .mapObject(Playlist.self)
  16. .asObservable()
  17. }
  18. //获取频道下第一首歌曲
  19. func loadFirstSong(channelId: String) -> Observable<Song> {
  20. return loadPlaylist(channelId: channelId)
  21. .filter{ $0.song != nil && $0.song.count > 0}
  22. .map{ $0.song[0] }
  23. }
  24. }
  1. import UIKit
  2. import RxSwift
  3. import RxCocoa
  4. class MusicViewController: UIViewController {
  5. private var viewModel = MusicListViewModel()
  6. private var disposeBag = DisposeBag()
  7. private lazy var tableView: UITableView = {
  8. let tableView = UITableView(frame: self.view.bounds)
  9. tableView.register(UITableViewCell.self, forCellReuseIdentifier: "CellIdentifier")
  10. tableView.tableFooterView = UIView()
  11. return tableView
  12. }()
  13. override func viewDidLoad() {
  14. super.viewDidLoad()
  15. self.view.backgroundColor = .white
  16. self.view.addSubview(self.tableView)
  17. let service = DoubanService()
  18. //获取列表数据
  19. let data = service.loadChannels()
  20. //将数据绑定到表格
  21. data.bind(to: tableView.rx.items) { (tableView, row, element) in
  22. let cell = tableView.dequeueReusableCell(withIdentifier: "CellIdentifier")!
  23. cell.textLabel?.text = "\(element.name!)"
  24. cell.accessoryType = .disclosureIndicator
  25. return cell
  26. }.disposed(by: disposeBag)
  27. //单元格点击
  28. tableView.rx.modelSelected(Channel.self)
  29. .map{ $0.channelId ?? "" }
  30. .flatMap(service.loadFirstSong)
  31. .subscribe(onNext: {[weak self] song in
  32. //将歌曲信息弹出显示
  33. let message = "歌手:\(song.artist!)\n歌曲:\(song.title!)"
  34. self?.showAlert(title: "歌曲信息", message: message)
  35. }).disposed(by: disposeBag)
  36. }
  37. //显示消息
  38. func showAlert(title:String, message:String) {
  39. let alertController = UIAlertController(title: title,
  40. message: message, preferredStyle: .alert)
  41. let cancelAction = UIAlertAction(title: "确定", style: .cancel, handler: nil)
  42. alertController.addAction(cancelAction)
  43. self.present(alertController, animated: true, completion: nil)
  44. }
  45. }

RxSwift + Moya + ObjectMapper的更多相关文章

  1. 基于Moya、RxSwift和ObjectMapper优雅实现REST API请求

    在Android开发中有非常强大的 Retrofit 请求,结合RxJava可以非常方便实现 RESTful API 网络请求.在 iOS开发中也有非常强大的网络请求库 Moya ,Moya是一个基于 ...

  2. Moya 与 RxSwift 使用

    如在OC中使用AFNetworking一般,Swift我们用Alamofire来做网络库.而Moya在Alamofire的基础上又封装了一层: 1.关于moya moya 官方说moya有以下特性-_ ...

  3. 移动APP开发框架盘点

    移动APP开发框架盘点 总体概述 现在比较流行的移动APP开发框架有以下六种:网页.混合.渐进.原生.桥接.自绘.前三种体验与Web的体验相似,后三种与原生APP的体验相似.这六种框架形式,都有自己适 ...

  4. Moya/RxSwift/ObjectMapper/Alamofire开发

    废话不多说直接上代码 // // MoyaNetWorking.swift // GreenAir // // Created by BruceAlbert on 2017/9/18. // Copy ...

  5. Swift网络封装库Moya中文手册之RxSwift

    RxSwift Maya提供了一个可选的MoyaProvider 子类 - RxMoyaProvider.在网络请求完成时,我们不再使用 request() 函数的回调闭包,而是使用 Observab ...

  6. Swift高仿iOS网易云音乐Moya+RxSwift+Kingfisher+MVC+MVVM

    效果 列文章目录 因为目录比较多,每次更新这里比较麻烦,所以推荐点击到主页,然后查看iOS Swift云音乐专栏. 目简介 这是一个使用Swift(还有OC版本)语言,从0开发一个iOS平台,接近企业 ...

  7. Moya 浅析

    Moya是一个高度抽象的网络库,他的理念是让你不用关心网络请求的底层的实现细节,只用定义你关心的业务.且Moya采用桥接和组合来进行封装(默认桥接了Alamofire),使得Moya非常好扩展,让你不 ...

  8. 从nsurlsession、Alamofire到moya

    更好的理解(抽象).更少的构建(配置).更方便的表达(语言) 一.iOS系统的网络编程(DSL概念) ios缺省的网络编程只是给出了网络编程的基本概念: urlsession.request.resp ...

  9. Jackson ObjectMapper类使用解析

    /** * Jackson ObjectMapper类 */ //ObjectMapper类是Jackson库的主要类.它提供一些功能将转换成Java对象匹配JSON结构,反之亦然.它使用JsonPa ...

随机推荐

  1. PowerDesigner的Table视图同时显示Code和Name的方法[转发]

    PowerDesigner中Table视图同时显示Code和Name,像下图这样的效果: 实现方法:Tools-Display Preference

  2. yum安装软件报错Segmentation fault处理

    yum安装软件报错Segmentation fault处理 在使用yum 更新软件时提示:Segmentation fault 中文错误提示: 段错误 [root@CMS-BAK:/usr/local ...

  3. php 新闻上一条下一条

    public function prevnext($table,$id,$where=[]){ $ids=db($table)->field('id,title')->order('sor ...

  4. 七.HTTP协议原理介绍

    01. 当用户访问一个网站时,都发生了事情? ①. 利用DNS服务,将输入的域名解析为相应的IP地址   a --本地主机输入域名后,会查询本地缓存信息和本地hosts文件 如果有就进行解析,如果没有 ...

  5. 【python】__import__

    函数定义 __import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module Import a module. Be ...

  6. Django + Uwsgi + Nginx 的生产环境部署

    使用runserver可以使我们的django项目很便捷的在本地运行起来,但这只能在局域网内访问,如果在生产环境部署django,就要多考虑一些问题了.比如静态文件处理,安全,效率等等,本篇文章总结归 ...

  7. 饮冰三年-人工智能-Python-23 Python PyCharm 使用中常见的问题

    一:软件工具使用中遇到的问题 1:AttributeError: module 'pip' has no attribute 'main'问题 处理方法: a:找到JetBrains\PyCharm ...

  8. 学习笔记: Expression表达式目录树详解和扩展封装

    1. 表达式链接扩展封装,ORM常用 And  Or /// <summary> /// 表达式访问者 /// </summary> public class Expressi ...

  9. 《学习之道》第八章孤军奋战or组队合作

    孤军奋战与组队合作:别再苦思冥想,拖延行为需要差别对待 对拖延我得提一个小建议,你要暂时把自己与那些会干扰你的人和事隔离开.自己到一个房间里去,或者去图书馆,这样就没什么事能让你分心了. 如果一门课让 ...

  10. Pop Star 1.2.5

    原文链接https://www.cnblogs.com/zhouzhendong/p/Pop-Star.html 是VB写的. 年代久远,代码太丑,原码不公开. 下载链接 仅支持Windows,需要解 ...