我对在 swift 上搜索与此 java 代码等效的内容感到非常沮丧:
public abstract class BaseApiSubscriber<T> extends Subscriber<T> {
private WeakReference<MvpView> mvpViewWeakReference;
private WeakReference<BasePresenter> basePresenterWeakReference;
public BaseApiSubscriber(BasePresenter basePresenter, MvpView mvpView) {
this.basePresenterWeakReference = new WeakReference<>(basePresenter);
this.mvpViewWeakReference = new WeakReference<>(mvpView);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
//handle generic errors here, call also the mvpView to handle generic responses on UI
}
@Override
public void onNext(T t) {
}
基本上,我在这里扩展了 Subscriber
,因此 API 的所有通用响应都在单个文件中处理。这适用于我的 java (android),但我找不到如何使它在 swift 上工作。我尝试搜索extensions
、protocols
,但它们似乎无法扩展。我确实尝试过搜索,但我不知道这个的关键字,我尝试盲目编码(希望它会起作用)但我做不到。也许只是一个关键字、基本示例或对此的解释。我这样做对吗?也准备好接受反对票,因为我无法在 swift 上发布好的代码。它甚至离这个还差得很远。
更新: 感谢@luk2302,我以某种方式接近了它,但是我该如何实现呢?这是我的代码:
class BaseSubscriber: ObserverType {
typealias E = Response
func on(_ event: Event<Response>) {
switch event {
case .next(let _):
print("Successing")
break
case .error(let error):
print("Erorring")
if let serviceError = error as? ServiceError {
print("service error: " + serviceError.errorDescription!)
}
print(error)
break
case .completed:
print("Completing")
break
}
}
}
然后我需要从这里调用它:
let base = BaseSubscriber()
repo.login(param: loginParam).subscribe(
//Ive tried this:
//base.on: {
//}
//but got an syntax error maybe hahahaha
)
这叫什么?所以我可以搜索和阅读它。谢谢。
更新 2:
感谢@Cristik,我已经设法做到了,通过传递一个闭包
,我现在可以传递方法来为每个请求执行特定任务。我更新的代码:
func baseSubscriber<T>(mvpView: BaseMvpView, onNext: @escaping (T) -> Void, onError: @escaping (Error) -> Void, onCompleted: @escaping () -> Void) -> (RxSwift.Event<T>) -> Void {
return { [weak mvpView] event in
switch event {
case let .next(element):
mvpView?.hideLoading()
print("super next")
onNext(element)
case .completed:
mvpView?.hideLoading()
print("super completed")
onCompleted()
case let .error(error):
mvpView?.hideLoading()
print("super error")
if let serviceError = error as? ServiceError {
print("Service error: \(serviceError.errorDescription ?? "Something wrong")")
} else {
onError(error)
}
}
}
但这与我在 java 上的方法不同,在 java 中我可以override
onError()
方法,所以如果我想忽略一般错误处理,我可以做吧。如何将其应用于 swift?
更新 3:
BaseMvpView.swift
protocol BaseMvpView: class {
func showLoading(message: String)
func hideLoading()
}
BaseTableViewController.swift
class BaseTableViewController: UITableViewController, BaseMvpView {
var indicator: UIActivityIndicatorView?
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLoad() {
super.viewDidLoad()
indicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
indicator?.frame = CGRect(origin: CGPoint.init(x: 0, y: 0), size: CGSize.init(width: 40, height: 40));
indicator?.center = view.center
view.addSubview(indicator!)
indicator?.bringSubview(toFront: view)
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
func showLoading(message: String) {
indicator?.startAnimating()
}
func hideLoading() {
indicator?.stopAnimating()
}
}
最佳答案
为此您不需要专门的类,似乎您唯一需要的是一个订阅者,它弱引用 View 和演示者,并处理常见的事件处理逻辑。
由于 RxSwift 订阅者也可以是一个带有一个 event
参数的闭包,你可以实现一个创建它的自由函数:
func customSubscriber<T>(mvpView: MvpView, presenter: BasePresenter) -> (RxSwift.Event<T>) -> Void {
return { [weak mvpView, weak presenter] event in
switch event {
case let .next(element):
print("Received \(element)")
case .completed:
print("Done")
case let .error(error):
if let serviceError = error as? ServiceError {
print("Service error: \(serviceError)")
} else {
print("Some error: \(error)")
}
}
}
}
你可以这样使用它:
myObserver.subscribe(customSubscriber(mvpView: someMvpView, presenter: somePresenter))
RxSwift 范式以闭包为中心:您从闭包创建观察者,订阅者是闭包,运算符使用闭包。同样在 Swift 中,结构和枚举(也称为值类型)等其他类型优于类(也称为引用类型),它们只是在大多数情况下工作得更好。
更新 根据最新的片段,您似乎还希望允许基于接收者的不同事件处理。这可以通过使用具有默认实现的协议(protocol)来优雅地实现。
protocol Subscribable: class {
associatedtype DataType
func onNext(_ data: DataType)
func onCompleted()
func onError()
}
extension Subscribable where Self: BaseMvpView {
func onNext(_ data: DataType) {
hideLoading()
print("super next")
}
func onCompleted() {
hideLoading()
print("super completed")
}
func onError() {
hideLoading()
print("super error")
if let serviceError = error as? ServiceError {
print("Service error: \(serviceError.errorDescription ?? "Something wrong")")
}
}
}
// BaseMvpView will get all above methos implemented, child classes can implement their own version.
extension BaseMvpView: Subscribable {
typealias DataType = DataTypeThatIsUsedByMvpView
}
// the subscriber function got simplifier as it no longer needs
// the callback parameters, as those are not part of the protocol
// this also makes the function more flexible as it's not tied to a
// concrete class
func baseSubscriber<S: Subscribable, T>(_ subscribable: S) -> (RxSwift.Event<T>) -> Void where S.DataType == T {
return { [weak subscribable] event in
switch event {
case let .next(element):
subscribable?.onNext(element)
case .completed:
subscribable.onCompleted()
case let .error(error):
subscribable.onError(error)
}
}
}
你可以这样调用新函数:
baseSubscriber(someMvpView)
关于java - 快速覆盖方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49029439/