#json #swift #xcode #api #http
Вопрос:
Я пытаюсь создать функцию http-запроса для вызова API, который я хочу использовать. Я продолжаю получать ошибку, что NSDictionary должен соответствовать кодируемому, но при инициализации перед вызовом я уже сделал его кодируемым.
Что я делаю не так?
Сообщение об ошибке
Статический метод «apiRequest(метод:параметры:url:authToken:)» требует, чтобы «NSDictionary» соответствовал «Кодируемому»
Ниже приведена инициализация параметров запроса API.
private struct APIBodylt;CallParams: Encodablegt;: Encodable { var method: String var params: CallParams var jsonrpc = "2.0" var id = Int64(Date().timeIntervalSince1970) } private static let bodyEncoder: JSONEncoder = { let e = JSONEncoder() e.keyEncodingStrategy = .convertToSnakeCase return e }()
Ниже приведена инициализация для отправки запроса API.
private static func apiRequestlt;Params: Encodablegt;( method: String, params: Params, url: URL, authToken: String? ) throws -gt; URLRequest { let body = APIBody(method: method, params: params) var req = URLRequest(url: url) req.httpMethod = "POST" do { req.httpBody = try bodyEncoder.encode(body) } catch let e { assertionFailure("API encoding error: (e)") throw e } req.addValue("application/json", forHTTPHeaderField: "Content-Type") req.addValue("application/json", forHTTPHeaderField: "Accept") if let authToken = authToken, !authToken.isBlank { req.addValue(authToken, forHTTPHeaderField: "X-Lbry-Auth-Token") } return req }
Ниже приведен последний вызов API, в котором я получаю ошибку.
static func apiCall( method: String, params: [String: Any], connectionString: String, authToken: String? = nil, completion: @escaping ([String: Any]?, Error?) -gt; Void ) { let req: URLRequest do { req = try apiRequest( //lt;-- Error throws on this Line ********************* method: method, params: params as NSDictionary, url: URL(string: connectionString)!, authToken: authToken ) } catch let e { completion(nil, e) return } let task = URLSession.shared.dataTask(with: req, completionHandler: { data, response, error in guard let data = data, error == nil else { // handle error completion(nil, error) return } do { Log.verboseJSON.logIfEnabled(.debug, "Response to `(method)`: (String(data: data, encoding: .utf8)!)") let response = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] if response?["result"] != nil { completion(response, nil) } else { if response?["error"] == nil, response?["result"] == nil { completion(nil, nil) } else if response?["error"] as? String != nil { completion(nil, LbryApiResponseError(response?["error"] as! String)) } else if let errorJson = response?["error"] as? [String: Any] { completion(nil, LbryApiResponseError(errorJson["message"] as! String)) } else { completion(nil, LbryApiResponseError("unknown api error")) } } } catch { completion(nil, error) } }) task.resume() }
Комментарии:
1. Я уверен, что будет лучший способ использовать
Codable
структуру2. Не используйте
NSDictionary
в Swift. Используйте родной словарь.