I'm so frustrated on searching what is the equivalent of this java code on swift:
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) {
}
Basically here, I'm extending Subscriber
so all of the generic response of API is handled on a single file. This works on my java (android), but I can't find how to make this work on swift. I tried searching about extensions
, protocols
but it seems they can't be extended. I did try to search, but I don't know the keyword for this, I try to code blindly (hoping it will work) but I can't. Maybe just a keyword, basic sample, or an explanation on this. Am I doing it right, right? Ready also for the downvotes because I just can't post a good code on swift. It is not even close to this.
Update: Somehow I got close to it, thanks to @luk2302, but then how can I implement this? Here's my code:
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
}
}
}
Then I need to call this from here:
let base = BaseSubscriber()
repo.login(param: loginParam).subscribe(
//Ive tried this:
//base.on: {
//}
//but got an syntax error maybe hahahaha
)
What do you call this? So I can search and read about it. Thank you.
Update 2:
Thanks to @Cristik, I've managed to do it, and by passing a closures
, I can now pass methods to do specific task per request. My updated code:
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)
}
}
}
}
But this is different to my approach on java in which I can override
the onError()
method so in case I want to disregard the generic error handling, I can do it. How can I apply it to swift?
Update 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()
}
}