Swift重写方法

问题描述 投票:1回答:1

我很沮丧地在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上完成这项工作。我试着搜索extensionsprotocols,但似乎它们无法延伸。我确实试图搜索,但我不知道关键字,我尝试盲目编码(希望它能工作),但我不能。也许只是关键字,基本样本或对此的解释。我做得对吗,对吧?也适用于downvotes,因为我无法在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,我已经设法做到了,通过传递closures,我现在可以传递方法来执行每个请求的特定任务。我的更新代码:

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上的方法不同,我可以在override中使用onError()方法,所以如果我想忽略一般错误处理,我可以做到。我怎样才能将它应用于swift?

更新3:

BaseMvpView.swift

protocol BaseMvpView: class {

   func showLoading(message: String)

   func hideLoading()
}

基表视图Controller.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()
}
}
java swift rx-java rx-swift
1个回答
1
投票

您不需要专门的类,似乎您唯一需要的是弱引用视图和演示者的订阅者,并处理常见的事件处理逻辑。

由于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 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)
© www.soinside.com 2019 - 2024. All rights reserved.