如何使用 RxSwift 从 returns Observable 服务中获取值
How can I get the value from a service that returns an Observable using RxSwift
我正在努力理解 RxSwift
。我在下面创建了一个简单的游乐场来模拟我正在尝试的行为。这应该运行 OK。
import UIKit
import RxSwift
struct Universities: Codable {
let author: Author
let example: String
let github: String
enum CodingKeys: String, CodingKey {
case author
case example
case github
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
author = try values.decode(Author.self, forKey: .author)
example = try values.decode(String.self, forKey: .example)
github = try values.decode(String.self, forKey: .github)
}
}
struct Author: Codable {
let name: String
let website: String
enum CodingKeys: String, CodingKey {
case name
case website
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
website = try values.decode(String.self, forKey: .website)
}
}
class HTTPClient<T: Codable> {
private let baseURL = URL(string: "http://universities.hipolabs.com/")!
func call() -> Observable<T> {
return Observable<T>.create { observer in
let request = URLRequest(url: self.baseURL)
let task: URLSessionDataTask = URLSession.shared.dataTask(with: request) { data, response, error in
do {
let model: T = try JSONDecoder().decode(T.self, from: data!)
observer.onNext(model)
} catch let error {
observer.onError(error)
}
observer.onCompleted()
}
task.resume()
return Disposables.create {
task.cancel()
}
}
}
}
class SomeService {
private let client = HTTPClient<Universities>()
private let disposeBag = DisposeBag()
func getValues() {
client.call().subscribe(onNext: { print([=11=].example) }).disposed(by: disposeBag)
}
}
let service = SomeService()
service.getValues()
如您所见,SomeService
调用我的 http 客户端发出请求并 returns 响应。然后我打印出一个值。我很难理解的是如何在另一个 class 中订阅 getValues
并利用响应。
这是我目前的尝试
class SomeService {
private let client = HTTPClient<Universities>()
private let disposeBag = DisposeBag()
func getValues() -> Observable<String> {
return client.call().subscribe(onNext: { return [=12=].example }).disposed(by: disposeBag)
}
}
let service = SomeService()
service.getValues().map { print([=12=]) }
但是我得到一个错误
Cannot convert return expression of type '()' to return type
'Observable'
我是否应该创建某种主题并从我的控制器订阅它,而不是使用返回值调用 onNext
?
如果是这样,我将如何在我的控制器中构造这些调用?
func getValues() -> Observable<String> {
return client.call()
.map { [=10=].example }
.do(onNext: { print([=10=]) })
}
无需介绍中间主题。 Do onNext 将挂钩可观察对象并添加您想要的打印行为。 map 会将大学类型转换为示例字符串。然后你可以简单地从你的 ViewController 订阅 getValues()
的结果。
我正在努力理解 RxSwift
。我在下面创建了一个简单的游乐场来模拟我正在尝试的行为。这应该运行 OK。
import UIKit
import RxSwift
struct Universities: Codable {
let author: Author
let example: String
let github: String
enum CodingKeys: String, CodingKey {
case author
case example
case github
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
author = try values.decode(Author.self, forKey: .author)
example = try values.decode(String.self, forKey: .example)
github = try values.decode(String.self, forKey: .github)
}
}
struct Author: Codable {
let name: String
let website: String
enum CodingKeys: String, CodingKey {
case name
case website
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
website = try values.decode(String.self, forKey: .website)
}
}
class HTTPClient<T: Codable> {
private let baseURL = URL(string: "http://universities.hipolabs.com/")!
func call() -> Observable<T> {
return Observable<T>.create { observer in
let request = URLRequest(url: self.baseURL)
let task: URLSessionDataTask = URLSession.shared.dataTask(with: request) { data, response, error in
do {
let model: T = try JSONDecoder().decode(T.self, from: data!)
observer.onNext(model)
} catch let error {
observer.onError(error)
}
observer.onCompleted()
}
task.resume()
return Disposables.create {
task.cancel()
}
}
}
}
class SomeService {
private let client = HTTPClient<Universities>()
private let disposeBag = DisposeBag()
func getValues() {
client.call().subscribe(onNext: { print([=11=].example) }).disposed(by: disposeBag)
}
}
let service = SomeService()
service.getValues()
如您所见,SomeService
调用我的 http 客户端发出请求并 returns 响应。然后我打印出一个值。我很难理解的是如何在另一个 class 中订阅 getValues
并利用响应。
这是我目前的尝试
class SomeService {
private let client = HTTPClient<Universities>()
private let disposeBag = DisposeBag()
func getValues() -> Observable<String> {
return client.call().subscribe(onNext: { return [=12=].example }).disposed(by: disposeBag)
}
}
let service = SomeService()
service.getValues().map { print([=12=]) }
但是我得到一个错误
Cannot convert return expression of type '()' to return type 'Observable'
我是否应该创建某种主题并从我的控制器订阅它,而不是使用返回值调用 onNext
?
如果是这样,我将如何在我的控制器中构造这些调用?
func getValues() -> Observable<String> {
return client.call()
.map { [=10=].example }
.do(onNext: { print([=10=]) })
}
无需介绍中间主题。 Do onNext 将挂钩可观察对象并添加您想要的打印行为。 map 会将大学类型转换为示例字符串。然后你可以简单地从你的 ViewController 订阅 getValues()
的结果。