Как получить видеоданные вне функции, которая возвращает void? - PullRequest
0 голосов
/ 07 апреля 2019

Я пытаюсь создать простое приложение, которое каждый день получает новое видео с Vimeo. Я могу получить доступ к Vimeo и видео без проблем, но встроенная функция «request» по умолчанию возвращает void, и я хотел бы использовать информацию о видео (URI, имена, .count и т. Д.) Вне функции request.

Функция запроса возвращает нечто, называемое «RequestToken», которое содержит путь и URLSessionDataTask. Я подумал, что это может быть ключом, но, вероятно, поскольку я новичок в программировании, я не смог эффективно использовать эту информацию. Я также прочитал много файлов классов Vimeo, связанных с VimeoClient и Request и т. Д., И кажется, что он создает объект словаря, когда запрос завершен, но я не знаю, как получить к нему доступ. Я чувствую, что это просто некоторые знания о функциях / замыканиях / возвратах, которых мне не хватает, и я не могу найти в Интернете термины для поиска.

    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)")

Вот полный вызов метода в классе VimeoClient.

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)
    }
}`

В операторе Print я получаю правильное количество видео на странице, поэтому я знаю, что оно работает правильно внутри функции. Запрос явно не говорит о том, что он возвращает void, но если я попытаюсь вернуть объект [VIMVideo], отладка скажет мне, что ожидаемый результат равен Void, и затем не будет собираться.

Всю информацию, которая мне нужна, я могу получить, но только внутри функции. Я хотел бы иметь возможность использовать его вне функции, но единственный способ, которым я знаю, как вернуть объект, который он не позволяет мне делать.

Спасибо за вашу помощь.

После прочтения предоставленной документации по async, похоже, что обратный вызов - это путь вперед. Однако, оглядываясь назад на рассматриваемый метод класса, он уже имеет встроенный обработчик завершения. В примерах, данных мне полезными людьми, обработчик завершения использовал бы простую переменную, на которую можно ссылаться в обратном вызове. По-видимому, встроенный обработчик завершения Pod VimeoNetworking имеет сложную ссылку на класс ответа (который может быть частью responseDictionary?). Есть какие-нибудь идеи о том, как я могу ссылаться на этот обработчик завершения в обратном вызове? Или это не цель, и я должен попытаться создать собственный обработчик завершения поверх предоставленного?

Большое спасибо!

...