2017-02-19 6 views
0

ModelViewとViewControllerの間でどのようにデータを転送するのか分かりません。TableViewでRxSwiftの正しい使い方

SelectModelViewController

class SelectModelViewController: UIViewController { 

@IBOutlet weak var tableView: UITableView! 
@IBOutlet weak var errorLabel: UILabel! 
@IBOutlet weak var activityIndicator: UIActivityIndicatorView! 

var markViewModel : MarkViewModel? 
let markService = MarkService() 
let disposeBag = DisposeBag() 



override func viewDidLoad() { 
    super.viewDidLoad() 
    markViewModel = MarkViewModel(markService: markService) 
    markViewModel?.data.asObservable() 
     .bindTo(tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (_, element, cell) in 
      cell.textLabel?.text = element 
     } 
     .addDisposableTo(disposeBag) 
} 
} 

でMarkViewModelは、エラーが発生しました。構造体MarkViewModel {

let markService: MarkService 
var data: Driver<[Mark]> 

init(markService: MarkService) { 
    self.markService = markService 

    data = markService.get() 
     .map { result in 
      switch result { 
      case.success(let marks): 
       return marks.map { mark in 
        return mark 
       } 
      case .error(let error): 
       print(error) 
      } 

     }.asDriver(onErrorJustReturn: .error(.other)) 
}} 

MarkService

構造体MarkService {

func get() -> Observable<Result<[Mark]>> { 
    return URLSession.shared.rx.json(url: URL(string: API.BaseURL)!) 
     .retry(3) 
     .map { 
      var marks = [Mark]() 
      guard let json = $0 as? [String: Any], 
       let items = json["RBMarks"] as? [[String : Any]] else { 
        return .error(.badJSON) 
      } 
      for item in items { 
       if let mark = Mark(json: item) { 
        marks.append(mark) 
       } else { 
        return .error(.badJSON) 
       } 
      } 
      return .success(marks) 
     } 
     .catchErrorJustReturn(.error(.noInternet)) 
}} 
+0

これがなぜ機能しないのかについていくつか詳しく説明してください。何がうまくいかず、何が起こると思いますか? –

+0

@StefanDorunga私はちょうどModelViewとViewControllerの間でデータを転送する方法を理解していません – expertgames

答えて

0

まず

何か間違ったことI'amは、我々は MarkService代わりの Anyから Observable<Result<[Mark]>>を返すことができます。これはあとで表示するのに便利です。

struct MarkService { 

    func get() -> Observable<Result<[Mark]>> { 
     return URLSession.shared.rx.json(url: URL(string: API.BaseURL)!) 
      .retry(3) 
      .map { 
       var marks = [Mark]() 
       guard let json = $0 as? [String: Any], 
        let items = json["RBMarks"] as? [[String : Any]] else { 
         return .error(.badJSON) 
       } 
       for item in items { 
        if let mark = Mark(json: item) { 
         marks.append(mark) 
        } else { 
         return .error(.badJSON) 
        } 
       } 
       return .success(marks) 
      } 
      .catchErrorJustReturn(.error(.noInternet)) 
    } 
} 

それでは、MarkViewModeldataへのサブスクリプションを削除してみましょう。また、マークをプレゼンテーションに適したものに変換します。

struct MarkViewModel { 

    let markService: MarkService 
    var data: Driver<[String]> 
    var marks: Variable<[Mark]> 
    let disposeBag = DisposeBag() 

    init(markService: MarkService) { 
     self.markService = markService 


     data = markService.get() 
      .map { result in 
       guard case .success(let marks) = result else { 
        return ["Error while getting marks"] 
       } 

       return marks.map { mark in 
        "For assignment \(mark.assignmentName), you were marked with \(mark.grade)/10" 
       } 
      } 
      .asDriver(onErrorJustReturn: .error(.other)) 
    } 
} 

さて、ビューコントローラでは、我々は、これは明らかにあなたがそれを行うことができ、コードが依存どのように変化するかの一例に過ぎない

let disposeBag = DisposeBag() 

func viewDidLoad() { 
    viewModel.data 
     .bindTo(tableView.rx.items(cellIdentifier: "Cell", cellType: UITableViewCell.self)) { (_, element, cell) in 
      cell.textLabel?.text = element 
     } 
     .addDisposableTo(disposeBag) 
} 

それらのデータを表示するためにRxSwiftのテーブルビューのバインディングを使用することができます特定のビューに対する要件。

+0

返信いただきありがとうございます!私はハンドラエラーのために 'MarkService'からジェネリックenumの' Result 'を返していました。 'MarkService'が 'Result ' – expertgames

+0

を返す場合、そのコードはどのように見えるのでしょうか? 'Result'の強さは、実際には型やエラーを保持できることです。だからここで 'Any'を使う必要はありません。しかし、本当に必要な場合は、View Controllerの 'guard 'を' guard case .success(let anyMarks)= resultに変更すると、mark = anyMarksを? [Mark] else {' – tomahh

+0

viewModelでエラーが発生しました。 'SharedSequence '型の値を割り当てることができません 'SharedSequence '(別名SharedSequence > ')' ' – expertgames

関連する問題