Far*_*ruk 8 networking ios swift alamofire
我正在尝试构建一个管理我的项目的网络调用的类.到目前为止,我的意思是在全球范围内处理错误,一切都很好.我创造了两个功能; 用于发布请求postRequest(:_)和获取请求getRequests(:_).Datamaker用于返回URL,参数,标题等数据,dataparser函数用于解析响应数据,最后用于解决调用错误的函数errorHandler().
当我调用请求函数时,我给出一个参数来帮助它应该发出的请求函数.在函数中,它首先调用数据制作者获取数据,然后发出请求Alamofire,最后如果请求成功则调用dataparser和onSuccess(data:)闭包,或者如果它不是调用errorHandler(statusCode:)和onFailure(message:)关闭.
我将一个开关块放入errorHandler并为其参数提供了statusCode.在case 401我打电话,Token().refresh()并在它完成称为errorHanlder完成.在postRequest/ errorHandler的完成块中,我postRequest使用相同的参数再次调用.它没用.我不知道为什么,它每次都进入无限循环并连续提出请求.
所以我决定尝试cnoon的AuthorizationManager课程(可以在这个链接中找到; Alamofire:如何在全球范围内处理错误).我稍微改了一下(添加了一个新的参数作为标题并改变了NetworkSuccessHandler类型NSData).这是新表格:
public class AuthorizationManager: Manager {
public typealias NetworkSuccessHandler = (NSData?) -> Void
public typealias NetworkFailureHandler = (NSHTTPURLResponse?, AnyObject?, NSError) -> Void
private typealias CachedTask = (NSHTTPURLResponse?, AnyObject?, NSError?) -> Void
private var cachedTasks = Array<CachedTask>()
private var isRefreshing = false
public func startRequest(
method method: Alamofire.Method,
URLString: URLStringConvertible,
parameters: [String: AnyObject]?,
encoding: ParameterEncoding,
headers: [String:String]?,
success: NetworkSuccessHandler?,
failure: NetworkFailureHandler?) -> Request?
{
let cachedTask: CachedTask = { [weak self] URLResponse, data, error in
guard let strongSelf = self else { return }
if let error = error {
failure?(URLResponse, data, error)
} else {
strongSelf.startRequest(
method: method,
URLString: URLString,
parameters: parameters,
encoding: encoding,
headers: headers,
success: success,
failure: failure
)
}
}
if self.isRefreshing {
self.cachedTasks.append(cachedTask)
return nil
}
// Append your auth tokens here to your parameters
let request = self.request(method, URLString, parameters: parameters, encoding: encoding, headers: headers)
request.response { [weak self] request, response, data, error in
guard let strongSelf = self else { return }
if let response = response where response.statusCode == 401 {
strongSelf.cachedTasks.append(cachedTask)
strongSelf.refreshTokens()
return
}
if let error = error {
failure?(response, data, error)
} else {
success?(data)
}
}
return request
}
func refreshTokens() {
self.isRefreshing = true
// Make the refresh call and run the following in the success closure to restart the cached tasks
Token().refresh { () -> () in
let cachedTaskCopy = self.cachedTasks
self.cachedTasks.removeAll()
cachedTaskCopy.map { $0(nil, nil, nil) }
self.isRefreshing = false
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的postRequest喜欢中称它为:
func postRequest(requestType: postRequestType, additionalParameters: [String]?, onSuccess: onSuccessRequest = {_ in }, onFailure: onFailureRequest = {_ in }){
print("post")
let requestData = returnStaticDataForPostRequest(requestType, additionalParameters: additionalParameters)
let Manager = AuthorizationManager()
Manager.startRequest(method: .POST, URLString: requestData.0, parameters: requestData.2, encoding: requestData.3, headers: requestData.1, success: { (data) -> Void in
print("Manager")
let json = JSON(data: data!)
print(json)
dataParserForPostRequests(json, parseForWhat: requestType)
onSuccess(json: json)
}) { (response, message, error) -> Void in
print(error)
}
}
Run Code Online (Sandbox Code Playgroud)
并使用postRequests在ViewController:
postRequest(.LOGIN, additionalParameters: ["asdasd", "asdasd"], onSuccess: { (json) -> () in
print(">>>login_try_succeeded")
self.performSegueWithIdentifier("LoginToMain", sender: self)
}) { (errorCode) -> () in
print(">>>login_try_failed(\(errorCode))")
}
Run Code Online (Sandbox Code Playgroud)
这是目前的状态.当我运行代码并尝试登录AuthorizationManager不起作用.它只是打印;
post
Run Code Online (Sandbox Code Playgroud)
最后,我不知道它是否相关,但此行有黄色警告:
cachedTaskCopy.map { $0(nil, nil, nil) }
Run Code Online (Sandbox Code Playgroud)
说 "Result of call to 'map' is unused"
总结一下,我需要弄清楚如何处理401,我知道如何以AuthorizationManager不同的方式使用它.
编辑:
我尝试直接运行此代码,ViewController但它根本不起作用.这就像代码是不可见的.
AuthorizationManager().startRequest(method: .POST, URLString: NSURL(string: "http://server.url/token")!, parameters: ["":""], encoding: .JSON,headers: ["":""], success: { (data) -> Void in
print(data)
}) { (response, data, error) -> Void in
print(error)
print("asdasd")
}
Run Code Online (Sandbox Code Playgroud)
您的 AuthorizationManager 在首次尝试发送请求后可能不会持续存在。
通常,避免单例模式是一个很好的做法,但这并不是一个坏情况:
public class AuthorizationManager: Manager {
static let shared = AuthorizationManager()
// ...the rest of your class
}
Run Code Online (Sandbox Code Playgroud)
当调用您的请求时,请使用此单例实例,而不是实例化一个新的 AuthorizationManager,例如
AuthorizationManager.shared.startRequest(method: .POST, ...etc...
Run Code Online (Sandbox Code Playgroud)
我猜这可能是问题所在,因为当您在这两种情况下创建 AuthorizationManager 时,没有任何内容主动保留该对象。管理器可能会被创建,运行请求,然后在cachedTask之前甚至在完成处理之前被释放,在这种情况下,您guard let strongSelf = self else { return }将简单地返回而不运行任何完成或cachedTasks。
希望这有帮助。如果这就是问题所在,那么单例解决方案应该非常简单。
| 归档时间: |
|
| 查看次数: |
2202 次 |
| 最近记录: |