7

据我了解Alamofire是内置的Reachability,所以我自己的处理程序看起来像:

import Alamofire

let reachabilityManager = NetworkReachabilityManager()
reachabilityManager.listener = { status in

switch status {

case .notReachable:
 print("The network is not reachable")
 self.onInternetDisconnection()

case .unknown :
 print("It is unknown whether the network is reachable")
 self.onInternetDisconnection() // not sure what to do for this case

case .reachable(.ethernetOrWiFi):
 print("The network is reachable over the WiFi connection")
 self.onInternetConnection()

case .reachable(.wwan):
 print("The network is reachable over the WWAN connection")
 self.onInternetConnection()

 }
}

我正在提出请求:

let provider = MoyaProvider<MyMoyaRequest>()
let token = provider.request(.start(
    username:self.email.value, 
    password: self.password.value) { result in

    switch result { 
    case let .success(moyaResponse):
        //handle success
    case let .failure(error):
        //handle failure
    }
}

因此,如果我想在发出每个Moya请求之前检查连接性,那么最好的方法是什么?

  1. 为 Moyas 内部的一个扩展编写一个扩展以首先检查
  2. 使用Moya插件(准备)检查
  3. 一些花哨的裤子到目前为止还没有想到……

出于可读性的原因,我特别不想为每个 API 调用添加可达性检查。但我有兴趣了解以前使用的方法。

感谢您提供的任何帮助。

4

1 回答 1

2

我特别不想为每个 API 调用添加可达性检查

将所有 API 调用包装到某个服务中可能是一个合理的决定。例如,我在上一个应用程序中是如何做到的:

public protocol NetworkServiceType: class {
    /// Cancellable request
    func observableRequest<T,C>(api: AnyApi<T>, cancel: Observable<C>, headers: [AUApi.Header: String], indicator: ActivityRelay?, logs: NetworkServiceLogs, timeout: TimeInterval, queue: DispatchQueue) -> Observable<Output<T>>
}

正如你所看到的,网络服务有一个函数可以接受所有必要的参数。当您将所有请求包装到一个函数中时 - 您可以在此函数中添加您想要的所有内容。甚至可达性检查!

我想在发出每个 Moya 请求之前检查连接性

有一些方法可以做到:

  1. 我将创建一个共享的反应式可达性服务并将该服务注入网络服务中。因此,在每次 Moya 请求之前,您都可以致电withLatestFrom并从您的可达性服务中获取最新状态。
  2. 您可以为每个请求创建可达性服务,并在请求完成后将其删除。

我很乐意向您展示如何创建第二个变体。我们需要的第一件事是ReachabilityInformer

final class ReachabilityInformer: Disposable {

    private lazy var networkReachabilityManager: NetworkReachabilityManager? = NetworkReachabilityManager(host: "www.google.com")
    private lazy var relayNetworkReachable = PublishRelay<Bool>()

    init() {
        switch networkReachabilityManager {
        case .none:
            relayNetworkReachable.accept(false)
        case .some(let manager):
            manager.listener = { [weak informer = self] status in
                switch status {
                case .notReachable:
                    informer?.relayNetworkReachable.accept(false)
                case .unknown:
                    break
                case .reachable:
                    informer?.relayNetworkReachable.accept(true)
                }
            }
        }
        networkReachabilityManager?.startListening()
    }

    func observableReachable() -> Observable<Bool> {
        return relayNetworkReachable
            .asObservable()
            .distinctUntilChanged()
    }

    func dispose() {
        networkReachabilityManager?.stopListening()
        networkReachabilityManager?.listener = nil
        networkReachabilityManager = nil
    }
}

它应该符合,Disposable因为它将被using操作员使用。

那么,如何使用它:

Observable<Bool>
    .using({ ReachabilityInformer() }, observableFactory: { (informer: ReachabilityInformer) -> Observable<Bool> in
        return informer.observableReachable()
    })

应该使用 this 启动请求Observable。如果存在连接,true您应该flatMap向您的 Moya 请求。如果是false,那么您应该返回失败或抛出错误。请求完成后,using操作员将确保ReachabilityInformer已解除分配。

PS 未测试,只是一些需要考虑的信息

于 2018-07-05T06:36:19.257 回答