无法使用params作为字典与Swift 4& Alamofire

时间:2018-03-30 09:34:23

标签: swift post request alamofire

我正在尝试学习使用/不使用库来调用API。但这里的问题让我感到困惑。

我有这样的参数:

let parameters: [String:String] =
            ["key":"MY_KEY" ,
             "q":sourceText,
             "source": sourceLanguage),
             "target": target)]

let headers: HTTPHeaders = [ "Content-type": "application/json"]

我这样打了一个电话:

Alamofire.request(urlString, method: HTTPMethod.post, parameters: parameters, headers: headers)
                .responseJSON{ response in
                    guard response.result.error == nil else {
                        print("error calling POST on /todos/1")
                        print(response.result.error!)
                        return
                    }
                    // make sure we got some JSON since that's what we expect
                    guard let json = response.result.value as? [String: Any] else {
                        print("didn't get todo object as JSON from API")
                        print("Error: \(response.result.error)")
                        return
                    }

由此我得到一个错误403,说我没有有效的API密钥(我用邮递员测试了密钥,没关系)。

经过多方努力,我必须改变这样的代码

let stringparams = "key=MY_KEY&q=\(sourceText)&source=\(sourceLanguage)&target=\(target)"
request.httpBody = stringparams.data(using: String.Encoding.utf8)

并使用此:Alamofire.request(请求) 有用! 我正在使用Google Cloud Translation api。并且网络使用REST api,如下所述:https://cloud.google.com/translate/docs/reference/translate

那么为什么我不能将params用作字典,但使用字符串(如formdata)可以在这里工作?

我的猜测是Alamofire没有为参数的请求做出正确的BODY,因为其他参数都没问题。但我不知道为什么。 我认为Google应该接受他们提到的json params,而不是使用表单数据?我确实尝试过原始方法,但它不适用于JSON。

2 个答案:

答案 0 :(得分:0)

从实际上适合您的工作看起来您需要以与查询相同的样式对参数进行编码。试试这个:

struct ParameterQueryEncoding: ParameterEncoding {
    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var request = try urlRequest.asURLRequest()
        request.httpBody = parameters?
            .map { "\($0)=\($1)" }
            .joined(separator: "&")
            .data(using: .utf8)
        return request
    }
}

然后您应该能够执行之前的原始呼叫:

Alamofire.request(urlString,
                  method: HTTPMethod.post,
                  parameters: parameters,
                  encoding: ParameterQueryEncoding(),
                  headers: headers)
    .responseJSON { response in
        ...
}

答案 1 :(得分:0)

尝试使用JSON编码。确保你已从字典中删除了。

Alamofire.request(URL, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers)