0

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!

JamesZ
  • 35
  • 4
  • Show the actual function and how it is called. – rmaddy Apr 07 '19 at 17:28
  • And see [Returning data from async call in Swift function](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function?r=SearchResults&s=1|66.3646) – rmaddy Apr 07 '19 at 17:28
  • Just added the function. Thanks. – JamesZ Apr 07 '19 at 17:46
  • Whoops looks like I unwittingly stumbled in to a common question with async. Thanks for the articles, reading up now. – JamesZ Apr 07 '19 at 18:03
  • http://www.programmingios.net/returning-a-value-from-asynchronous-code/ (sorry, changed the URL to make it more findable!) – matt Apr 07 '19 at 19:03
  • @rmaddy Did I get the information right that you requested? Sorry if I didn’t, I’m really green. Thanks for the article, it helped my understanding along. – JamesZ Apr 07 '19 at 20:42

0 Answers0