ios - 使用 Google Vision API 发出请求 - 收到无效的 JSON 有效负载且 INVALID_ARGUMENT

标签 ios json google-api http-post google-vision

尝试按照 link 中的说明进行操作从我的 iOS 应用程序创建请求,但收到无效的 JSON 有效负载和 INVALID_ARGUMENT 错误消息。有什么建议吗?

这是我尝试使用的示例。

{
  "requests":[
    {
      "image":{
        "source":{
          "imageUri":
            "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
        }
      },
      "features":[
        {
          "type":"LOGO_DETECTION",
          "maxResults":1
        }
      ]
    }
  ]
}

在我的 iOS 应用程序中,我创建了 para

let feature1 = ["type": "LOGO_DETECTION", "maxResults": 1] as [String : Any]
let features = [feature1]
let source = ["imageUri": "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"]
let image = ["source": source]
let request = ["image": image, "features": features] as [String : Any]
let requests = ["requests": [request]]

if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
    let str = String(data: data, encoding: .utf8) {
    print(str)
}

let privateKey = "my............key"

let requestString = "https://vision.googleapis.com/v1/images:annotate?key=\(privateKey)"
Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in
    switch response.result {
    case .success(let data):
        print("data", data)
        print(response.result)
    case .failure(let error):
        print(error)
    }
}

我可以看到我的打印日志中有同样的东西。

{
  "requests" : [
    {
      "features" : [
        {
          "type" : "LOGO_DETECTION",
          "maxResults" : 1
        }
      ],
      "image" : {
        "source" : {
          "imageUri" : "https:\/\/www.google.com\/images\/branding\/googlelogo\/2x\/googlelogo_color_272x92dp.png"
        }
      }
    }
  ]
}

但是我收到以下错误消息

[BoringSSL] Function boringssl_context_get_peer_sct_list: line 1754 received sct extension length is less than sct data length
data {
  "error": {
    "code": 400,
    "message": "Invalid JSON payload received. Unknown name \"requests[][features][][maxResults]\": Cannot bind query parameter. Field 'requests[][features][][maxResults]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"requests[][image][source][imageUri]\": Cannot bind query parameter. Field 'requests[][image][source][imageUri]' could not be found in request message.\nInvalid JSON payload received. Unknown name \"requests[][features][][type]\": Cannot bind query parameter. Field 'requests[][features][][type]' could not be found in request message.",
    "status": "INVALID_ARGUMENT",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.BadRequest",
        "fieldViolations": [
          {
            "description": "Invalid JSON payload received. Unknown name \"requests[][features][][maxResults]\": Cannot bind query parameter. Field 'requests[][features][][maxResults]' could not be found in request message."
          },
          {
            "description": "Invalid JSON payload received. Unknown name \"requests[][image][source][imageUri]\": Cannot bind query parameter. Field 'requests[][image][source][imageUri]' could not be found in request message."
          },
          {
            "description": "Invalid JSON payload received. Unknown name \"requests[][features][][type]\": Cannot bind query parameter. Field 'requests[][features][][type]' could not be found in request message."
          }
        ]
      }
    ]
  }
}

正确答案

1.删除

if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
    let str = String(data: data, encoding: .utf8) {
    print(str)
}

2.改变

Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in

Alamofire.request(requestString, method: .post, parameters: requests, encoding: JSONEncoding.default, headers: [:]).responseJSON { (response) in

最佳答案

乍一看,错误非常明显:

  • 未知名称 requests[][features][][maxResults]:无法绑定(bind)查询参数。在请求消息中找不到字段。
  • 未知名称 requests[][image][source][imageUri]:无法绑定(bind)查询参数。在请求消息中找不到字段。
  • 未知名称 requests[][features][][type]:无法绑定(bind)查询参数。在请求消息中找不到字段。”

但是将您的控制台输出与文档中的示例进行比较,它是匹配的。我的猜测是问题是两种可能性之一:

  1. 请求中完全缺少您的负载,或者
  2. 您没有正确编码负载。

为了在下次发生这种情况时为您提供帮助,我建议您通过构建有效负载并通过 Curl 或 Postman 发送它来进行调试,以消除您的应用程序的罪魁祸首。

获得有效负载后,将您的 Swift 应用指向 http://requestb.in并将您的请求发送到那里。这将允许您检查您发送的内容并将其与工作示例进行比较。

现在开始修复它:

事实证明问题是#2 - 你没有正确编码。或者更确切地说,您是,但您没有发送编码字符串。

看到这一行:

let requests = ["requests": [request]]

if let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
    let str = String(data: data, encoding: .utf8) {
    print(str)
}

然后你就可以:

Alamofire.request(requestString, method: .post, parameters: requests).responseString { (response) in

请注意您如何在有效负载中使用 requests,而不是编码的 str?您已将编码字符串隐藏在 if 语句中,使其无法使用。我会在这里使用 guard - 它的代码更少,并且不会隐藏编码的字符串(它也更安全):

let requests = ["requests": [request]]

guard let data = try? JSONSerialization.data(withJSONObject: requests, options: .prettyPrinted),
      let encodedStr = String(data: data, encoding: .utf8) else { return }

Alamofire.request(requestString, method: .post, parameters: encodedStr).responseString { (response) in
                                                            // ^ use the right var here!

关于ios - 使用 Google Vision API 发出请求 - 收到无效的 JSON 有效负载且 INVALID_ARGUMENT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46897302/

相关文章:

json - gs协议(protocol)是什么意思?

javascript - 使用已解析的 JavaScript 数据加载 Javascript 变量

c# - 从重定向的 URI 接收 Oauth2 授权代码

python-3.x - Python gspread获取accessNotConfigured-未找到项目(编号),并且无法用于API调用

python - Google Drive API Python 实现的 ~/.credentials/drive-python-quickstart.json 保存在哪里?

ios - 将格式化测量值限制为 2 位数字

ios - 如何处理从另一个应用程序发送到我自己的 iOS 应用程序的 'Open in...' 文件?

ios - 在 NSDictionary* 类型的对象上找不到读取数组元素的预期方法

objective-c - 我的 NSDictionary 的键是什么

ios - items' 产生 '(Source) -> Disposable' ,而不是 UICollectionLayout 的预期上下文结果类型 '(_) -> _' 错误