Вызов API REST с помощью Swift 5.2 - PullRequest
0 голосов
/ 21 апреля 2020

Я запрограммировал простой скрипт python для получения дивидендных данных по акциям от Finnhub.io, этот код работает и опубликован ниже.

#!/usr/bin/env python
import requests

resp = requests.get('https://finnhub.io/api/v1/stock/dividend?symbol=AAPL&from=2010-01-01&to=2020-12-31&token=xxx')
if resp.status_code != 200:
    # This means something went wrong.
    raise ApiError('GET /api/v1/stock/dividend?symbol=AAPL&from=2010-01-01&to=2020-12-31&token=xxx {}'.format(resp.status_code))
else:
    for dividend_item in resp.json():
        print('{} {} {}'.format(dividend_item['date'], dividend_item['symbol'], dividend_item['amount']))

Результат выполнения скрипта python выглядит как это:

2020-02-07 AAPL 0.77
2019-11-07 AAPL 0.77
2019-08-09 AAPL 0.77
2019-05-10 AAPL 0.77
2019-02-08 AAPL 0.73
2018-11-08 AAPL 0.73
2018-08-10 AAPL 0.73
2018-05-11 AAPL 0.73
2018-02-09 AAPL 0.63
2017-11-10 AAPL 0.63
2017-08-10 AAPL 0.63
2017-05-11 AAPL 0.63
2017-02-09 AAPL 0.57
2016-11-03 AAPL 0.57
2016-08-04 AAPL 0.57
2016-05-05 AAPL 0.57
2016-02-04 AAPL 0.52
2015-11-05 AAPL 0.52
2015-08-06 AAPL 0.52
2015-05-07 AAPL 0.52
2015-02-05 AAPL 0.47
2014-11-06 AAPL 0.47
2014-08-07 AAPL 0.47
2014-05-08 AAPL 0.47
2014-02-06 AAPL 0.43571
2013-11-06 AAPL 0.43571
2013-08-08 AAPL 0.43571
2013-05-09 AAPL 0.43571
2013-02-07 AAPL 0.37857
2012-11-07 AAPL 0.37857
2012-08-09 AAPL 0.37857

Что вызывает у меня головную боль, так это преобразование этого в Swift 5.2 на iOS 13. Я нашел здесь хороший пост по stackoverflow ( Выполните вызов REST API в Swift ) и скорректировал код в соответствии с приведенным ниже кодом Swift.

    func getDividendData() {
        let params = ["username":"john", "password":"123456"] as Dictionary<String, String>

        var request = URLRequest(url: URL(string: "https://finnhub.io/api/v1/stock/dividend?symbol=AAPL&from=2010-01-01&to=2020-12-31&token=xxx")!)
        request.httpMethod = "GET"
        request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")

        let session = URLSession.shared
        let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
            print(response!)
            do {
                let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, AnyObject>
                print(json)
            } catch {
                print("error")
            }
        })

        task.resume()
    }

Когда я затем вызываю метод getDividendData(), я получаю ошибки ниже. Поскольку я еще не очень опытен в программировании на Swift, я надеюсь, что кто-то может дать мне подсказку.

2020-04-21 22:39:27.963666+0200 RESTtest[15836:1085147] GET method must not have a body
2020-04-21 22:39:27.967193+0200 RESTtest[15836:1085147] Task <C919CF75-FB01-4FF5-8CC8-646B1CA1FB5D>.<1> finished with error [-1103] Error Domain=NSURLErrorDomain Code=-1103 "resource exceeds maximum size" UserInfo={NSUnderlyingError=0x600002953240 {Error Domain=kCFErrorDomainCFNetwork Code=-1103 "(null)"}, NSErrorFailingURLStringKey=https://finnhub.io/api/v1/stock/dividend?symbol=AAPL&from=2010-01-01&to=2020-12-31&token=xxx0, NSErrorFailingURLKey=https://finnhub.io/api/v1/stock/dividend?symbol=AAPL&from=2010-01-01&to=2020-12-31&token=xxx, NSLocalizedDescription=resource exceeds maximum size}
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/joe/Desktop/RESTtest/RESTtest/ViewController.swift, line 27
2020-04-21 22:39:27.967483+0200 RESTtest[15836:1085147] Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/joe/Desktop/RESTtest/RESTtest/ViewController.swift, line 27
(lldb) 

PS: Из соображений конфиденциальности я заменил токен на xxx.

1 Ответ

1 голос
/ 21 апреля 2020

Как гласит ошибка:

Метод GET не должен иметь тела

Таким образом, причиной ошибки является строка:

request.httpBody

Вместо этого вы должны добавить параметры URL (элементы запроса).

let url = URL(string: "https:// Your url path")!
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)
let queryItems: [URLQueryItem] = params.map { parameter in
    URLQueryItem(name: parameter.key, value: parameter.value)
}

components.queryItems = queryItems

var request = URLRequest(url: components.url!)
// ...

...