gpt4 book ai didi

ios - 无法将类型 X 的值转换为预期的参数类型 XX

转载 作者:行者123 更新时间:2023-11-28 07:35:45 25 4
gpt4 key购买 nike

我正在尝试使用 Generics 编写网络管理器。而我没有这样做。下面是我的代码和错误截图。这里 BaseViewController 正在实现 NetworkManagerListener。我想我让代码更复杂了,所以请帮助我理解我做错了什么以及如何摆脱这个错误

import Alamofire
import EVReflection
import Alamofire_SwiftyJSON
import SwiftyJSON

protocol NetworkManagerListener {
associatedtype RES_TYPE
func successResponse(statusCode: Int, response: RES_TYPE?)
func errorResponse(statusCode: Int, error: ErrorResponse)
}

class NetworkingManager<RES: EVNetworkingObject, ER: ErrorResponse, T: Any> {

static func registerUser<BVC: BaseViewController<T>>(baseViewController: BVC, registerUserRequest: RegisterUserRequest, checkTokenExpiry: Bool) {
handleRequest(baseViewController: baseViewController, url: API.REGISTER_USER, requestModel: registerUserRequest, checkTokenExpiry: checkTokenExpiry)
}

private static func handleRequest<BVC: BaseViewController<T>, REQ: EVNetworkingObject>(baseViewController: BVC, url: String, requestModel: REQ, checkTokenExpiry: Bool) {
if let isReachable = NetworkReachabilityManager()?.isReachable, isReachable {
if let userModelDictionary = requestModel.toDictionary() as? Dictionary<String, Any> {
var headersDictionary: HTTPHeaders?
if let user = DatabaseManager.getUser() {
headersDictionary = [String: String]()
headersDictionary?["Authorization"] = "Bearer \(user.userToken)"
headersDictionary?["Content-Type"] = "application/json"
print(headersDictionary as Any)
}

Alamofire.request(url, method: .post, parameters: userModelDictionary, encoding: JSONEncoding.default, headers: headersDictionary ?? nil).validate(statusCode: 200..<300).responseSwiftyJSON { response in
if let statusCode = response.response?.statusCode {
do {
switch response.result {
case .failure(let error):
var errorResponse: ER = ER(message: "Please try again later")
if let data = try response.result.value?.rawData(), !data.isEmpty {
errorResponse = ER(data: data)
}
if checkTokenExpiry || statusCode >= STATUS_CODE.SERVER_ERROR_RANGE_STARTING {
handleErrorGlobally(baseViewController: baseViewController, statusCode: statusCode, errorResponse: errorResponse)
} else {
handleError(baseViewController: baseViewController, statusCode: statusCode, errorResponse: errorResponse)
}
break
case .success:
if let data = try response.result.value?.rawData(), let type = response.result.value?.type {
print("data: \(data)")
switch type {
case .array:
baseViewController.successResponse(statusCode: statusCode, response: [RES](data: data))
break
case .dictionary:
baseViewController.successResponse(statusCode: statusCode, response: RES.init(data: data))
break
default:
print("unhandled type: \(type)")
break
}
} else {
baseViewController.successResponse(statusCode: statusCode, response: nil as RES?)
}
break
}
} catch(let error) {
print("error: \(error)")
}
}
}
}
} else {
baseViewController.networkFailure()
}
}

private static func handleErrorGlobally<BVC: BaseViewController<T>, ER: ErrorResponse>(baseViewController: BVC, statusCode: Int, errorResponse: ER) {
if statusCode == STATUS_CODE.UN_AUTHORIZED {
baseViewController.tokenExpired()
} else if statusCode >= STATUS_CODE.SERVER_ERROR_RANGE_STARTING {
baseViewController.serverError()
} else {
baseViewController.networkError(statusCode, errorResponse)
}
}

private static func handleError<BVC: BaseViewController<T>, ER: ErrorResponse>(baseViewController: BVC, statusCode: Int, errorResponse: ER) {
baseViewController.errorResponse(statusCode: statusCode, error: errorResponse)
}
}

基础 View Controller :

import UIKit
import EVReflection

class BaseViewController<RESPONSE_TYPE>: UIViewController, NetworkManagerListener {

typealias RES_TYPE = RESPONSE_TYPE
override func viewDidLoad() {
super.viewDidLoad()
}

func tokenExpired() {
//TODO: Need to create an alert dialog showing the user to re-login
print("Token expired")
}

func networkError(_ statusCode: Int, _ errorResponse: ErrorResponse) {
//general error with unhandled status code
let refreshAlert = UIAlertController(title: nil, message: errorResponse.message, preferredStyle: UIAlertController.Style.alert)
refreshAlert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
self.present(refreshAlert, animated: true, completion: nil)
}

func networkFailure() {
//handling no internet connection
let alert = UIAlertController(title: "Notice", message: "Please check your internet connection", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction.init(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}

func serverError() {
//TODO: Need to handle when error came from server
let alert = UIAlertController(title: "Notice", message: "Please try again later", preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction.init(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}

func successResponse(statusCode: Int, response: RESPONSE_TYPE?) {
print("unhandled response is \(String(describing: response))")
}

func errorResponse(statusCode: Int, error: ErrorResponse) {
let alert = UIAlertController(title: nil, message: error.message, preferredStyle: UIAlertController.Style.alert)
alert.addAction(UIAlertAction.init(title: "Ok", style: .default, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}

示例响应:

import EVReflection

class RegisterUserResponse: EVNetworkingObject {
var userName: String?
var email: String?
var firstName: String?
var lastName: String?

override func propertyMapping() -> [(keyInObject: String?, keyInResource: String?)] {
return [("userName", "username"), ("firstName", "first_name"), ("lastName", "last_name")]
}
}

enter image description here

最佳答案

您尝试在 .successResponse 中传递的内容必须覆盖/实现在 BaseViewController 的类型别名 RES_TYPE 中声明的 RESPONSE_TYPE。

class SomeListener: NetworkManagerListener {
typealias RES_TYPE = NSString

func successResponse(statusCode: Int, response: SomeListener.RES_TYPE?) {

}
func errorResponse(statusCode: Int, error: Int) {

}
}

class Res: NSString {

}

class Er {

}

class NetworkingManager<RES: Res, ER: Er, T: Any> {

func someCall() {
let a = SomeListener()
a.successResponse(statusCode: 1, response: Res())
}

}

在您的情况下,您应该尝试在 BaseViewController 中将 RESPONSE_TYPE 与 EVNetworkingObject 切换。

关于ios - 无法将类型 X 的值转换为预期的参数类型 XX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53208237/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com