美文网首页
Swift3+MVVM+ReactiveCocoa5实战2

Swift3+MVVM+ReactiveCocoa5实战2

作者: 蜜蜂6520 | 来源:发表于2017-05-01 12:58 被阅读252次

上一篇分享了登录界面,没有网络请求,着重理解下使用流程。这一篇给大家分享一下有网络请求的界面展示,Swift3+MVVM+ReactiveCocoa5该怎么应用。

Talk is cheap. Show me the code

需求描述:

请求豆瓣图书列表,解析并展示在界面表格中

Model

class BookDataModel: NSObject {

    var title:String = ""
    var subtitle:String = ""
    
    init(dic:[String:Any]) {
        super.init()
        self.setValuesForKeys(dic)// 字典转BookDataModel便捷方法
    }
    
    // 字典转BookDataModel,BookDataModel中没有的key重写不抛出异常
    override func setValue(_ value: Any?, forUndefinedKey key: String) {
        
    }
    
}

ViewController

class BookViewController: UIViewController {

    lazy var bookViewModel = {
        return BookViewModel()
    }()
    
    var table:UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        table = UITableView(frame: view.bounds, style: .plain)
        table.dataSource = bookViewModel
        view.addSubview(table)
        
        // 请求图书列表,观察结果,得到数据后刷新列表
        bookViewModel.bookAction.apply(()).startWithResult { (result) in
            switch result {
            case let .success(value):
                self.bookViewModel.models = value
                self.table.reloadData()
            default:
                break
            }
        }
        
    }
}

ViewModel

// 导入RAC5模块
import ReactiveCocoa
import ReactiveSwift
import Result

class BookViewModel: NSObject,UITableViewDataSource {

    let cellIdentifier = "cell"
    
    var bookAction:Action<(),[BookDataModel],AnyError>!
    
    var models = [BookDataModel]()
    
    override init() {
        super.init()
        initialBind()
    }
    
    func initialBind() {
        
        // 请求图书列表并解析业务
        bookAction = Action<(),[BookDataModel],AnyError> { (_) -> SignalProducer<[BookDataModel], AnyError> in
            SignalProducer<String, AnyError>({ (observer, _) in
                
                // MFNetworkRequest是我自己封装的网络请求,成功返回String报文,失败返回错误原因,可忽略。
                let bookRequest = MFNetworkRequest()
                bookRequest.sendDataGetRequest(url: "https://api.douban.com/v2/book/search?q=基础", successBlock: { (successStr) in
                    observer.send(value: successStr)
                    observer.sendCompleted()
                }, failedBlock: { (failedStr) in
                    
                })
                
            }).map({ (str) -> [BookDataModel] in
                
                // 将请求成功得到的String报文中的数组解析成BookDataModel数组
                let bookObject = try! JSONSerialization.jsonObject(with: str.data(using: .utf8) ?? Data(), options: .mutableContainers)
                let bookDic = bookObject as! Dictionary<String, Any>
                let bookArr = bookDic["books"] as! Array<Dictionary<String,Any>>
                
                var books = [BookDataModel]()
                for book in bookArr {
                    let model = BookDataModel(dic: book)
                    books.append(model)
                }
                
                return books
                
            })

        }
        
    }
    
    //MARK:UITableViewDataSource
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        return models.count
        
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        var cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier)
        if cell == nil {
            cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellIdentifier)
        }
        
        let book = models[indexPath.row]
        cell?.textLabel?.text = book.title
        cell?.detailTextLabel?.text = book.subtitle
        
        return cell!
        
    }
    
}

效果图

效果图.PNG

如果觉得我的文章对您有用,请点击喜欢。您的支持将鼓励我继续创作!

大家有什么不懂或我哪里写错了都可以评论留言,我一定会回复的~

相关文章

网友评论

      本文标题:Swift3+MVVM+ReactiveCocoa5实战2

      本文链接:https://www.haomeiwen.com/subject/zrbftxtx.html