正确使用 RxSwift 和 TableView
Correct usage of RxSwift with TableView
我不知道如何在 ModelView 和 ViewController 之间传输数据。在
选择模型ViewController
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 {
func get() -> Observable<Result<[Mark]>> {
return URLSession.shared.rx.json(url: URL(string: API.BaseURL)!)
.retry(3)
.map {
var marks = [Mark]()
guard let json = [=12=] 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))
}}
首先,我们可以 return Observable<Result<[Mark]>>
来自 MarkService
而不是 Any
。这将有助于稍后显示它们。
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 = [=10=] 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))
}
}
然后,让我们在MarkViewModel
中删除对data
的订阅。我们还会将标记转换为更适合展示的内容。
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))
}
}
现在,在视图控制器中,我们可以使用 RxSwift 的 table 视图绑定来显示这些数据
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)
}
这显然只是您如何操作的示例,代码会根据特定视图的要求而改变。
我不知道如何在 ModelView 和 ViewController 之间传输数据。在
选择模型ViewController
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 {
func get() -> Observable<Result<[Mark]>> {
return URLSession.shared.rx.json(url: URL(string: API.BaseURL)!)
.retry(3)
.map {
var marks = [Mark]()
guard let json = [=12=] 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))
}}
首先,我们可以 return Observable<Result<[Mark]>>
来自 MarkService
而不是 Any
。这将有助于稍后显示它们。
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 = [=10=] 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))
}
}
然后,让我们在MarkViewModel
中删除对data
的订阅。我们还会将标记转换为更适合展示的内容。
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))
}
}
现在,在视图控制器中,我们可以使用 RxSwift 的 table 视图绑定来显示这些数据
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)
}
这显然只是您如何操作的示例,代码会根据特定视图的要求而改变。