I am trying to create a simple app that fetches a new video from Vimeo everyday. I can access Vimeo and the videos no problem, but the built in "request" function defaults to returning void and I would like to use the video info (URIs, names, .count, etc.) outside of the request function.
The request function returns something called a "RequestToken" which contains a path and a URLSessionDataTask. I thought maybe that was the key but, probably since I'm new to programming, I have been unable to effectively use this info. I've also read a lot of the Vimeo class files associated with VimeoClient and Request and so forth and it seems like it creates a dictionary object when a request has completed but I have no idea how to access that. I feel like this is just some knowledge about functions/closures/returns that I lack and can't quite find the internet search terms to answer.
let videoRequest = Request<[VIMVideo]>(path: "/user/videos")
vimeoClient.request(videoRequest) { result in
switch result {
case .success(let response):
let video: [VIMVideo] = response.model
print("retrieved videos: \(video.count)")
case .failure(let error):
print ("error retrieving video: \(error)")
Here is the full method call under VimeoClient class.
public func request<ModelType>(_ request: Request<ModelType>, completionQueue: DispatchQueue = DispatchQueue.main, completion: @escaping ResultCompletion<Response<ModelType>>.T) -> RequestToken
{
if request.useCache
{
self.responseCache.response(forRequest: request) { result in
switch result
{
case .success(let responseDictionary):
if let responseDictionary = responseDictionary
{
self.handleTaskSuccess(forRequest: request, task: nil, responseObject: responseDictionary, isCachedResponse: true, completionQueue: completionQueue, completion: completion)
}
else
{
let error = NSError(domain: type(of: self).ErrorDomain, code: LocalErrorCode.cachedResponseNotFound.rawValue, userInfo: [NSLocalizedDescriptionKey: "Cached response not found"])
self.handleError(error, request: request)
completionQueue.async {
completion(.failure(error: error))
}
}
case .failure(let error):
self.handleError(error, request: request)
completionQueue.async {
completion(.failure(error: error))
}
}
}
return RequestToken(path: request.path, task: nil)
}
else
{
let success: (URLSessionDataTask, Any?) -> Void = { (task, responseObject) in
DispatchQueue.global(qos: .userInitiated).async {
self.handleTaskSuccess(forRequest: request, task: task, responseObject: responseObject, completionQueue: completionQueue, completion: completion)
}
}
let failure: (URLSessionDataTask?, Error) -> Void = { (task, error) in
DispatchQueue.global(qos: .userInitiated).async {
self.handleTaskFailure(forRequest: request, task: task, error: error as NSError, completionQueue: completionQueue, completion: completion)
}
}
let path = request.path
let parameters = request.parameters
let task: URLSessionDataTask?
switch request.method
{
case .GET:
task = self.sessionManager?.get(path, parameters: parameters, progress: nil, success: success, failure: failure)
case .POST:
task = self.sessionManager?.post(path, parameters: parameters, progress: nil, success: success, failure: failure)
case .PUT:
task = self.sessionManager?.put(path, parameters: parameters, success: success, failure: failure)
case .PATCH:
task = self.sessionManager?.patch(path, parameters: parameters, success: success, failure: failure)
case .DELETE:
task = self.sessionManager?.delete(path, parameters: parameters, success: success, failure: failure)
}
guard let requestTask = task else
{
let description = "Session manager did not return a task"
assertionFailure(description)
let error = NSError(domain: type(of: self).ErrorDomain, code: LocalErrorCode.requestMalformed.rawValue, userInfo: [NSLocalizedDescriptionKey: description])
self.handleTaskFailure(forRequest: request, task: task, error: error, completionQueue: completionQueue, completion: completion)
return RequestToken(path: request.path, task: nil)
}
return RequestToken(path: request.path, task: requestTask)
}
}`
In the Print statement I get the correct count for the videos on the page so I know that it is working properly inside the function. The request doesn't explicitly say that it returns void but if I try to return a [VIMVideo] object the debug tells me that the expected return is Void and then will not build.
All the information I need I can get, but only inside the function. I would like to be able to use it outside the function but the only way I know how is returning the object which it isn't allowing me to do.
Thanks for your help.
After reading the provided documentation on async, it looks like the callback is the way forward here. However, when looking back at the class method in question it already has a completion handler built in. In the examples given to me by the helpful people here the completion handler would use a simple variable that could be referenced in the callback. The, seemingly, built-in VimeoNetworking Pod completion handler has a complex-looking reference to a response class (which may be part of the responseDictionary?) any ideas on how I can reference that completion handler in a callback? Or is that not the purpose and I should attempt to craft my own completion handler on top of the provided one?
Thanks much!