无法使用闭包推断通用参数'T'-Swift 4

时间:2019-06-14 16:55:55

标签: ios swift

我正在使用Alamofire向服务器发出请求,并将其包装在我自己的具有请求功能的LMLAPI结构中。如何传递可选的编码?

我的文件/结构:

import Foundation
import Alamofire

enum RouterAPI {
  case menu(restaurantName: String)
  case placesNearby(latitude: Double, longitude: Double)
  case placesText(query: String)
  case notifications(token: String)

    var url: String {
    switch self {
    case .menu(let restaurantName):
      return "/restaurant/menu/\(restaurantName)/"
    case .placesNearby:
      return "/google/find-nearby-places/"
    case .placesText:
      return "/google/find-places-text/"
        case .notifications:
            return "/notification/token/"
        }
  }

    var parameters: Parameters? {
    switch self {
    case .menu:
      return nil
    case .placesNearby(let latitude, let longitude):
      return [
        "latitude": latitude,
        "longitude": longitude
      ]
    case .placesText(let query):
      return [
        "query": query
      ]
        case .notifications(let token):
            return [
                "token": token
            ]
        }
  }

}

struct LMLAPI {
  static let sharedInstance = LMLAPI()

  private var connectionProtocol = Environment().configuration(PlistKey.ConnectionProtocol)
  private var serverUrl = Environment().configuration(PlistKey.ServerURL)

    func request<T: Codable>(from endpoint: RouterAPI, mthd method: HTTPMethod, mdl model: T.Type? = nil, vc viewController: UIViewController? = nil, completionHandler: ((T) -> Void)? = nil) {
    viewController?.showActivityIndicator()

        let headers = ["Authorization": "Token adsfasd"]
        let requestUrl = "\(connectionProtocol)://\(serverUrl)\(endpoint.url)"
        Alamofire.request(requestUrl, method: method, parameters: endpoint.parameters, headers: headers)
            .validate()
            .responseData { (response) in

      DispatchQueue.main.async {
        viewController?.hideActivityIndicator()
      }

      switch response.result {
      case .success:
        print("✅\(method.rawValue)✅ - ?\(requestUrl)?")
      case .failure:
        print("❌\(method.rawValue)❌ - ?\(requestUrl)?")
        return
      }

      do {
        guard let data = response.data else { return }
    guard let model = model else { return }
        guard let completionHandler = completionHandler else { return }

        let object = try JSONDecoder().decode(model, from: data)
        completionHandler(object)

      } catch let error {
        print(error)
      }
    }
  }

}

调用此方法:

LMLAPI.sharedInstance.request(from: .placesText(query: query), mthd: .get, mdl: Places.self, vc: self) { (places) in
        self.places = places
        self.loadPlaces()
}

这不起作用:

LMLAPI.sharedInstance.request(from: RouterAPI.notifications(token: fcmToken), mthd: HTTPMethod.post)

错误:

Generic parameter 'T' could not be inferred

到目前为止,我所学到的是,不能推断出可调用函数是有道理的,因为我没有传递可编码的结构,所以编译器不知道该怎么做,我想呢?我的问题是如何使它正常工作,或者我需要添加/删除使其工作才能工作?我希望它能够工作的原因是,在这种情况下,我不希望像在处理其他请求时那样,在闭包中返回可编码的对象。谢谢。

1 个答案:

答案 0 :(得分:0)

所以我认为有两种方法可以使其起作用:

  1. 使用函数重载,使2个具有不同参数的函数,一个接受模型类型,另一个不接受模型类型。 (推荐)
  2. 将默认值添加到可以在函数中测试的模型类型,以放弃函数的编码部分。 (不是解决问题的干净方法)