ios - MVVM 架构使用 swift 获取数据和更新 UITableView

标签 ios swift uitableview model-view-controller mvvm

我对 MVVM 架构完全陌生。我刚刚开始研究它,这是我第一次尝试使用 MVVM 架构编写代码。我需要从服务器下载评论并将它们显示在表格 View 中。我的view是用storyboard实现的 下面是我对其他类的实现。

SECommentsViewController.swift

import UIKit

class SECommentsViewController: SEViewController, UITableViewDataSource {



    @IBOutlet weak var tableView: UITableView!
    var mediaObject: PFObject?
    var viewModel = SECommentsViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.fetchCommentsForMedia(mediaObject) { (comments, error) in
            self.tableView.reloadData()
        }
    }

    // MARK: - UITableViewDataSource

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.comments.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("SECommentCell", forIndexPath: indexPath) as! SECommentCell
        let object = viewModel.comments[indexPath.row]
        if let username = (object.objectForKey("fromUser") as? PFUser)?.objectForKey("userId") as? String {
            cell.usernameButton.setTitle(username, forState: UIControlState.Normal)
        }
        if let profileImageURLString  = ((object.objectForKey("fromUser") as? PFUser)?.objectForKey("image") as? PFFile)?.url {
            if let profileImageURL = NSURL(string: profileImageURLString) {
                cell.profileImageView.sd_setImageWithURL(profileImageURL)
            }
        }
        if let commentText = object.objectForKey("text") as? String {
            cell.commentLabel.text = commentText
        }

        return cell
    }
}

SECommentsViewModel.swift

import UIKit

class SECommentsViewModel: NSObject {

    var comments = [PFObject]()

    func fetchCommentsForMedia(mediaObject: PFObject?, completion: (comments: [PFObject]?, error: NSError?) -> Void) {
        if let media = mediaObject {
            let commentsQuery = PFQuery(className: "SEActivity")
            commentsQuery.whereKey("image", equalTo: media)
            commentsQuery.whereKey("type", equalTo: "comment")
            commentsQuery.findObjectsInBackgroundWithBlock({ (objects: [PFObject]?, error: NSError?) in
                if let theObjects = objects {
                    self.comments = theObjects
                }
                completion(comments: objects, error: error)
            })
        }
        else {
            completion(comments: nil, error: nil)
        }
    }
}

SECommentCell.swift

import UIKit

class SECommentCell: UITableViewCell {

    @IBOutlet weak var profileImageView: UIImageView!
    @IBOutlet weak var usernameButton: UIButton!
    @IBOutlet weak var commentLabel: UILabel!
    var commentUser: PFUser?
}

我觉得这与网络代码在 ViewModel 而不是 ViewController 中的 MVC 没有什么不同。所以我想我可能做得不对。如果您能告诉我我的方向是否正确以及是否有任何建议,我将不胜感激。

提前谢谢你。

注意:关于面向协议(protocol)的 MVVM 的文章给我留下了深刻的印象,但不知道如何开始我的特定示例。 Click here to see the article

最佳答案

我建议使用 ReactiveCocoa 库 ( https://github.com/ReactiveCocoa/ReactiveCocoa ),它可以让您在许多其他函数中监听信号。

然后您可以像现在一样将所有网络调用放在 ViewModel 中,但不使用回调,而是使用 SignalProducer。

所以在你的 ViewModel 中你可以做这样的事情:

func fetchData() -> SignalProducer<[PFObject], NSError> {
    return SignalProducer { event, disposable in
        // Your network code here, and on completion / error do
        event.sendNext(array)
        event.sendCompleted()
        // On error do
        event.sendError(error)
    }
}

此外,不要直接从 View 访问您的评论数组,而是实现如下方法

func getDataSourceCount()
func getItemAtIndexPath()

关于ios - MVVM 架构使用 swift 获取数据和更新 UITableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36314507/

相关文章:

ios - 自动扩展 UITextView 高度以包含动态加载的完整文本

ios - 如何制作通用顶点以便我可以创建具有混合类型的图形(集合)?

ios - UITableViewCell 中的约束更新不正确

swift - TableView didSelect 在 Swift 中响应问题

ios - 如何创建签名 url 以从 iOS 中的云端获取私有(private)内容

objective-c - NSAlert 显示错位的按钮

swift - 为什么我反转 UIImage 后 CIImage 为零?

ios - 如何以编程方式添加可重用的自定义 View ? ( swift )

Swift - 如何声明私有(private)嵌套结构?

ios - CollectionView 添加额外的单元格 "Add more"