Closed jakunico closed 8 years ago
Your suggestion is good.
My answer is as follow,
I don't have any good idea write now.
I do want to handle it.....How can I add to Session
the code to handle error 401 with only solid codes...
I'll check this out this week and let you know
Very ugly code. That's too bad.
I think this code can be shorten and beautified using blocks and generics.....maybe.
/**
Search subreddits by title and description.
- parameter query: The search keywords, must be less than 512 characters.
- parameter paginator: Paginator object for paging.
- parameter completion: The completion handler to call when the load request is complete.
- returns: Data task which requests search to reddit.com.
*/
public func getSubredditSearchWithErrorHandling(query: String, paginator: Paginator, completion: (Result<Listing>) -> Void) throws -> NSURLSessionDataTask? {
let parameter = paginator.addParametersToDictionary(["q":query])
guard let request = NSMutableURLRequest.mutableOAuthRequestWithBaseURL(baseURL, path:"/subreddits/search", parameter:parameter, method:"GET", token:token)
else { throw ReddiftError.URLError.error }
let task = URLSession.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
self.updateRateLimitWithURLResponse(response)
let result: Result<Listing> = resultFromOptionalError(Response(data: data, urlResponse: response), optionalError:error)
.flatMap(response2Data)
.flatMap(data2Json)
.flatMap(json2RedditAny)
.flatMap(redditAny2Object)
switch result {
case .Failure(let error):
if error.code == 401 {
let task = self.URLSession.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
self.updateRateLimitWithURLResponse(response)
let result: Result<Listing> = resultFromOptionalError(Response(data: data, urlResponse: response), optionalError:error)
.flatMap(response2Data)
.flatMap(data2Json)
.flatMap(json2RedditAny)
.flatMap(redditAny2Object)
completion(result)
})
task.resume()
} else {
completion(result)
}
case .Success:
completion(result)
}
})
task.resume()
return task
}
I got a better code?
func handleTask<T>(request: NSMutableURLRequest, closure: (data: NSData?, response: NSURLResponse?, error: NSError?) -> Result<T>, completion: (Result<T>) -> Void) throws -> NSURLSessionDataTask? {
let task = URLSession.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
let result = closure(data:data, response: response, error: error)
switch result {
case .Failure(let error):
if error.code == 401 {
do {
try self.refreshToken({ (result) -> Void in
switch result {
case .Failure:
completion(result)
case .Success:
let task = self.URLSession.dataTaskWithRequest(request, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
let result = closure(data:data, response: response, error: error)
completion(result)
})
task.resume()
}
})
} catch { print(error) }
} else {
completion(result)
}
case .Success:
completion(result)
}
})
task.resume()
return task
}
/**
Search subreddits by title and description.
- parameter query: The search keywords, must be less than 512 characters.
- parameter paginator: Paginator object for paging.
- parameter completion: The completion handler to call when the load request is complete.
- returns: Data task which requests search to reddit.com.
*/
public func getSubredditSearchWithErrorHandling(query: String, paginator: Paginator, completion: (Result<Listing>) -> Void) throws -> NSURLSessionDataTask? {
let parameter = paginator.addParametersToDictionary(["q":query])
guard let request = NSMutableURLRequest.mutableOAuthRequestWithBaseURL(baseURL, path:"/subreddits/search", parameter:parameter, method:"GET", token:token)
else { throw ReddiftError.URLError.error }
let closure = {(data: NSData?, response: NSURLResponse?, error: NSError?) -> Result<Listing> in
self.updateRateLimitWithURLResponse(response)
let result: Result<Listing> = resultFromOptionalError(Response(data: data, urlResponse: response), optionalError:error)
.flatMap(response2Data)
.flatMap(data2Json)
.flatMap(json2RedditAny)
.flatMap(redditAny2Object)
return result
}
return try! handleTask(request, closure: closure, completion: completion)
}
Looking good to me!
Now coding on auto-refresh branch.
b7d2a8ba75ba1b50035e3d9e4946d4b6688d2b02
Hi!
I noticed that token expires after some time and was wondering if you have any automatic mechanism to refresh it in place.
I noticed that you have a
refreshToken
function in theSession
class which is amazing. So this is the expected behaviour:The thing is that this mechanism should be happen inside the session object (or at some low level) and not on consumer level.
Questions:
Let me know what you think and I can give it a shot