SAP Leonardo API 的 Swift 4.2 代码等效项

标签 swift

使用场景文本识别 API 连接 SAP Leonardo 沙箱服务器时出现 HTTP 400 错误

SAP 在旧版本的 swift 中提供了样板代码。我已经使用了curl命令和API并且可以工作。但当我尝试将代码转换为 swift 4.2 版本时它不起作用。我附上下面的代码。

 func connectWithSAP(photoURL : URL, photoData : String, sentImageData : Data){
          if let myNewURL = URL(string: "https://sandbox.api.sap.com/ml/scenetextrecognition/scene-text-recognition") {

            var myRequest = URLRequest(url: myNewURL)
            myRequest.addValue("multipart/form-data; --\(boundary)", forHTTPHeaderField: "Content-Type")
            myRequest.addValue("application/json", forHTTPHeaderField: "Accept")
            myRequest.addValue("xxxxxxxxxxx", forHTTPHeaderField: "APIKey")
            myRequest.httpMethod = "POST"
            myRequest.cachePolicy = .reloadIgnoringLocalCacheData
            myRequest.timeoutInterval = 60.0

//构造请求正文。

            var data = Data()
            var dataString = ""

            dataString.append("--\(boundary)\r\n")
            dataString.append(contentsOf: "Content-Disposition:form-data; name=\"files\"; filename=\"Image1.jpeg\" \r\n")
            dataString.append(contentsOf: ";Content-Type:image/jpeg \r\n\r\n")
            dataString.append(photoData)
            dataString.append("--\(boundary) ----- \r\n")
            data = dataString.data(using: .utf8)!
            myRequest.httpBody = data


            let task = URLSession.shared.dataTask(with: myRequest) { (data, response, error) in
            if let error = error {
                print(error)
            }
            guard let httpResponse = response as? HTTPURLResponse,
                (200...299).contains(httpResponse.statusCode) else {
                    print(error as Any)

//获取此阶段的输出,如下所示

                    return }
            if let mimeType = httpResponse.mimeType,
                mimeType == "application/json",
                let data = data {
                do {
                    let json =  try JSONSerialization.jsonObject(with: data, options: []) as? [String:Any]

                    print(json as Any)

                }catch {
                    print(error)
                }
            }

        }
        task.resume()
    }

我在响应对象中收到以下详细信息

{网址:https://sandbox.api.sap.com/ml/scenetextrecognition/scene-text-recognition } { 状态代码:400, header {\n 连接 = (\n\"keep-alive\"\n );\n\"Content-Length\"= (\n 131\n );\n\"内容-Type\"= (\n\"application/json\"\n );\n 日期 = (\n\"2019 年 2 月 16 日星期六 11:56:37 GMT\"\n );\n 服务器 = (\n\"Werkzeug/0.14.1 Python/3.5.5\"\n );\n\"严格传输安全\"= (\n\"max-age=31536000; includeSubDomains; 预加载;\"\n );\n\"X-Vcap-Request-Id\"= (\n\"fea7037c-4e48-49d2-4be1-53b0dad0ee46\"\n );\n}

正如您所看到的,状态代码是 HTTP 400。需要一些帮助才能从服务器获取正确的响应和数据。

最佳答案

很可能, body 数据被搞乱了。这是工作代码:

        let boundaryConstant = "----WebKitFormBoundary7MA4YWxkTrZu0gW"
        let headers = [
            "APIKey": "YourAPIKEY"
        ]
        let contentType = "multipart/form-data; boundary=" + boundaryConstant
        //API endpoint for API sandbox
        var request = URLRequest(url: URL(string: "https://sandbox.api.sap.com/ml/scenetextrecognition/scene-text-recognition")!)
        //setting request method
        request.httpMethod = "POST"
        request.allHTTPHeaderFields = headers
        let session = URLSession.shared


        let path1 = Bundle.main.path(forResource: "your_image", ofType: "png")!
        let url = URL(fileURLWithPath: path1)
        let fileName = url.lastPathComponent
        let data = try? Data(contentsOf: url)
        let imageData = UIImage.init(data: data!)!
        let pngData = UIImagePNGRepresentation(imageData)!
        let mimeType = "image/png"


        let boundaryStart = "--\(boundaryConstant)\r\n"
        let boundaryEnd = "--\(boundaryConstant)--\r\n"
        let fieldName = "files"
        let contentDispositionString = "Content-Disposition: form-data; name=\"\(fieldName)\"; filename=\"\(fileName)\"\r\n"
        let contentTypeString = "Content-Type: \(mimeType)\r\n\r\n"

        var body = Data()

        body.append(boundaryStart.data(using: .utf8)!)
        body.append(contentDispositionString.data(using: .utf8)!)
        body.append(contentTypeString.data(using: .utf8)!)
        body.append(pngData)
        body.append("\r\n".data(using: .utf8)!)
        body.append(boundaryEnd.data(using: .utf8)!)
        request.httpBody = body
        request.setValue(contentType, forHTTPHeaderField: "Content-Type")
        request.setValue(String(body.count), forHTTPHeaderField: "Content-Length")
        let dataTask = session.dataTask(with: request) { (data, response, error) in
            if (error != nil) {
                print(error)
            } else {
                let httpResponse = response as? HTTPURLResponse
                print(httpResponse)
            }
        }
        dataTask.resume()

您还可以使用 Alamofire 上传图像。它更干净,不需要太多地玩弄“body”:

        let headers: HTTPHeaders = [
            "APIKey": "<<Your API KEY>>",
            "Content-type": "multipart/form-data"
        ]
        let parameters:[String: String] = [:] //any other parameters you need to  send

        let path1 = Bundle.main.path(forResource: "<<your_image>>", ofType: "<<png or jpeg>>")!
        let url = URL(fileURLWithPath: path1)
        let fileName = url.lastPathComponent
        let data = try? Data(contentsOf: url)
        let imageData = UIImage.init(data: data!)!

        //converting it into png data
        let pngData = UIImagePNGRepresentation(imageData)
        let mimeType = "image/png"
        let fieldName = "files" 

        Alamofire.upload(multipartFormData: { (multipartFormData) in
            for (key, value) in parameters {
                multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
            }

            if let data = pngData{
                multipartFormData.append(data, withName: fieldName, fileName: fileName, mimeType: mimeType)
            }

        }, usingThreshold: UInt64.init(), to: "https://sandbox.api.sap.com/ml/scenetextrecognition/scene-text-recognition" , method: .post, headers: headers) { (result) in
            switch result{
            case .success(let upload, _, _):
                upload.responseJSON { response in
                    print("Succesfully uploaded")


                }
            case .failure(let error):
                print("Error in upload: \(error.localizedDescription)")

            }
        }

关于SAP Leonardo API 的 Swift 4.2 代码等效项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54723038/

相关文章:

ios - 自定义导航栏不是矩形

swift - 'value' 的使用不明确

ios - avplayer seek 在音频文件中播放错误的位置

swift - 如何在 Swift 5.5 中将 async/await 与 SwiftUI 一起使用?

ios - 如何将堆栈中的 1 个以上的 View Controller 委托(delegate)给 View Controller ?

ios - 调试为什么 SKScene init(fileNamed :) returns nil

swift - 通过大数组 Swift 进行过滤

ios - 如何使用自定义 UITableViewCell 制作 Hozirontal UITableView

ios - ipad模拟器上的UIImagePicker不是全宽

Swift/Spritekit UILongPressGestureRecognizer 似乎在按下时忽略所有其他手势