nastya_zholudeva
@nastya_zholudeva

Как сделать так, чтобы функция возвращала значения типа Array?

Хочу сделать универсальную функцию, которая бы делала запрос к API. Собственно вот она.
func request(uri: String, params: Dictionary<String, Any>) -> Array<Dictionary<String, String>> {
        Alamofire.request(self.url + uri, method: .get, parameters: params as! Parameters).responseJSON { response in
            if let json: [AnyObject] = response.result.value as? [AnyObject] {
                var items = [Dictionary<String, String>]()
                let data = JSON(json)
                for item in data {
                    items.append(["id": item.1["id"].stringValue, "title": item.1["title"].stringValue])
                }
                return items
            }
        }
    }

Но такой код выдает ошибку Unexpected non-void return value in void function. Как это можно сделать?
  • Вопрос задан
  • 336 просмотров
Решения вопроса 2
doublench21
@doublench21 Куратор тега Swift
Ну вы наверное просто забыли или не понимаете, что функция responseJson выполняется асинхронно. Это просто коллбэк, который выполнится тогд, когда сервер на ваш запрос вернёт Json. Но тк функция работает асинхронно в другом потоке, на текущем потоке после запроса к серверу ничего нет. И функция завершает свою работу. Но она ничего не возвращает, а вы указали что она должна что-то возвращать. Отсюда и ошибка про non Void.

То что вы возращаете item это хорошо. Ток он возвращается уже не в этой функции.

Если вы хотите что бы эта функция возвращала ответ сервера, то вам нужно каким то образом ждать ответа от асинхронной функции. Может воспользоваться DispatchGroup и wait.

А вообще так делать не нужно. Весь смысл асинхронности пропадёт. Эта функция не должна ничего возвращать. А сам факт того что пришли данные должен обрабатываться в responseJson или в наблюдателе переменной куда вы присвоите то что получите.
Ответ написан
briahas
@briahas
ObjC, Swift, Python
Либо сделать так как советует doublench21 :
private _data: [[String: String]]? {
  didSet {
   /* Тут я получил данные и что-то с ними уже делаю. Этот код выполнится так скоро,
 как запрос запишет ответ в данную переменную */
 }
}


Либо, переписать функцию чтоб был completion блок:
func request(uri: String, params: Dictionary<String, Any>, completion: ( Array<Dictionary<String, String>>)->())  {
        Alamofire.request(self.url + uri, method: .get, parameters: params as! Parameters).responseJSON { response in
            if let json: [AnyObject] = response.result.value as? [AnyObject] {
                var items = [Dictionary<String, String>]()
                let data = JSON(json)
                for item in data {
                    items.append(["id": item.1["id"].stringValue, "title": item.1["title"].stringValue])
                }
                completion(items)
            }
        }
    }

, в последнем случае, применение функции будет следующим:
classElement.request(uri: myPath, params: requestParams) { items in
    print(items)
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы