与SAP的Leonardo API等效的Swift 4.2代码

时间:2019-02-16 12:23:31

标签: 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()
    }

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

{URL:https://sandbox.api.sap.com/ml/scenetextrecognition/scene-text-recognition} {状态代码:400,标题{\ n Connection =(\ n \“ keep-alive \” \ n); \ n \“ Content-Length \” =(\\ n 131 \ n); \ n \“ Content-Type \” =(\ n \“ application / json \” \ n); \ n Date =(\ n \“ Sat,16 Feb 2019 11:56:37 GMT \“ \ n); \ n服务器=(\ n \” Werkzeug / 0.14.1 Python / 3.5.5 \“ \ n); \ n \” Strict-Transport-Security \“ =(\ n \” max- age = 31536000; includeSubDomains; preload; \“ \ n); \ n \” X-Vcap-Request-Id \“ =(\ n \” fea7037c-4e48-49d2-4be1-53b0dad0ee46 \“ \ n); \ n }

您将看到状态码是HTTP400。需要一些帮助来从服务器获取正确的响应和数据。

1 个答案:

答案 0 :(得分:0)

很可能是身体数据混乱了。这是工作代码:

        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上传图像。这样更干净,不需要过多地玩弄“身体”:

        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)")

            }
        }