SwiftBondでAPIからデータバインディング

データバインディングのライブラリとしてBondを初めてつかってみました。

github.com

いろいろやってみるうちに、MVVM風にViewModelからデータをバインディングする設計が良い感じで気に入りました

サンプルコードはgithubを参照

github.com

実装

iTuens search apiを使って、アーティストと曲名をTableViewに表示します

Model

import SwiftyJSON

struct List {

    let trackName: String
    let artistName: String
    
    init(json: JSON) {
        self.trackName = json["trackName"].stringValue
        self.artistName = json["artistName"].stringValue
    }

}

View Model

モデルをObservableArrayで保持し、apiコールで更新します。

import UIKit
import Bond
import Alamofire
import SwiftyJSON

class ListViewModel {

    internal let lists = ObservableArray<List>()
    
    private let urlString = "https://itunes.apple.com/search"
    private let parameters = ["term":"Swift",
                              "entity":"musicTrack",
                              "limit":"15"]

    internal func reload() {
        Alamofire.request(.GET, urlString, parameters: parameters).validate().responseJSON { response in
            switch response.result {
            case .Success:
                if let value = response.result.value {
                    let jsons = JSON(value)
                    for i in 0...jsons["results"].count {
                        let list = List(json: jsons["results"][i])
                        self.lists.append(list)
                    }
                }
            case .Failure(let error):
                print(error)
            }
        }
    }
    
}

View Controller

ObservableArray<List>をtableViewにBindします

import UIKit
import Bond

class ListViewController: UIViewController {
    
    @IBOutlet var tableView: UITableView!

    private let listViewModel = ListViewModel()
    private var list = ObservableArray<ObservableArray<List>>()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.list = [listViewModel.lists]
        listViewModel.reload()
        
        list.bindTo(tableView) { indexPath, dataSources, tableView in
            let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
            let dataSource = dataSources[indexPath.section][indexPath.row]
            cell.textLabel?.text = dataSource.trackName
            cell.detailTextLabel?.text = dataSource.artistName

            return cell
        }

    }

}

f:id:aminaura:20160604154910p:plain