Возврат структуры после разбора json в Swift - PullRequest
0 голосов
/ 18 февраля 2020

Я пишу функцию, которая вызывает API фондовой биржи и возвращает базовые c данные о конкретных c акциях. После этого я анализирую данные в своей структуре, но затем я не могу вернуть эту структуру, когда добавляю инструкцию return.

Эта функция компилируется без каких-либо проблем и работает как положено.

func getData(symbol: String){


        let apiURL = "https://cloud.iexapis.com/stable/stock/\(symbol)/quote?token=\(secretToken)"
        let url = URL(string: apiURL)!

        URLSession.shared.dataTask(with: url) { (data, response, err) in

        guard let data = data else { return  }

            do {
                let json = try JSONDecoder().decode(Stock.self, from: data)
                let stockResult = Stock(symbol: json.symbol,
                                        companyName: json.companyName,
                                        latestPrice: json.latestPrice
                )

                //I want to return this Stock structure



            } catch let jsonErr {
                print("Error serialising json: ", jsonErr)
            }
        }.resume()

    }

Но когда я добавляю следующий код, я получаю сообщение об ошибке: Неожиданное возвращаемое значение в функции void

func getData(symbol: String) -> Stock {


        let apiURL = "https://cloud.iexapis.com/stable/stock/\(symbol)/quote?token=\(secretToken)"
        let url = URL(string: apiURL)!

        URLSession.shared.dataTask(with: url) { (data, response, err) in

        guard let data = data else { return  }

            do {
                let json = try JSONDecoder().decode(Stock.self, from: data)
                let stockResult = Stock(symbol: json.symbol,
                                        companyName: json.companyName,
                                        latestPrice: json.latestPrice
                )

                //I want to return this Stock structure

                return stockResult

            } catch let jsonErr {
                print("Error serialising json: ", jsonErr)
            }
        }.resume()

    }

любым способом, каким я могу заставить его скомпилировать и вернуть мою структуру акций?

Ответы [ 3 ]

0 голосов
/ 18 февраля 2020

Поскольку у вас есть сетевой вызов в вашей функции, вы должны использовать обратный вызов для возврата данных.


func getData(symbol: String, completion: @escaping ((Stock?)-> Void)) {


        let apiURL = "https://cloud.iexapis.com/stable/stock/\(symbol)/quote?token=\(secretToken)"
        let url = URL(string: apiURL)!

        URLSession.shared.dataTask(with: url) { (data, response, err) in

        guard let data = data else { return  }

            do {
                let json = try JSONDecoder().decode(Stock.self, from: data)
                let stockResult = Stock(symbol: json.symbol,
                                        companyName: json.companyName,
                                        latestPrice: json.latestPrice
                )

                // Here return your completion like this
                completion(stockResult)

            } catch let jsonErr {
                print("Error serialising json: ", jsonErr)
            }
        }.resume()

    }

вы можете вызывать свою функцию следующим образом в вашем контроллере или ViewModel:


getData(symbol: "yoursymbol") { stock in
    // process your stock
}
0 голосов
/ 18 февраля 2020

Я нашел решение. Вы должны добавить замыкание, а затем использовать его при вызове функции.

func getData(symbol: String, completion: @escaping (Stock) -> Void) {


        let apiURL = "https://cloud.iexapis.com/stable/stock/\(symbol)/quote?token=\(secretToken)"
        let url = URL(string: apiURL)!

        URLSession.shared.dataTask(with: url) { (data, response, err) in

        guard let data = data else { return  }

            do {
                let json = try JSONDecoder().decode(Stock.self, from: data)
                let stockResult = Stock(symbol: json.symbol,
                                        companyName: json.companyName,
                                        latestPrice: json.latestPrice
                )

                //I want to return this Stock structure

                completionBlock(stockResult)

            } catch let jsonErr {
                print("Error serialising json: ", jsonErr)
            }
        }.resume()

    }

, затем в основном вы вызываете

getData(symbol: "aapl") {(output) in
            print(output)
}
0 голосов
/ 18 февраля 2020

Сделайте так, чтобы ваша функция имела параметр completion, например:

func getData(symbol: String, completion: @escaping (Stock?) -> (Void) ) {
    ...
}

, и вызовите его, когда вы проанализировали результат

let stockResult = Stock(...)
completion(stockResult)

и в случае ошибки call completion(nil)

Вообще говоря, не боритесь с асинхронной природой сетевых вызовов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...