Swift5在响应头中解析JSON二进制

问题描述

我应该解析header(wtf)内部的数据,而不是正文。 响应标头格式如下:

{
    "InferResponse":
    {
        "modelName": "aixyolov2","modelVersion": "1","batchSize": 1,"output":
        [
            {
                "name": "OUTPUT2","raw":
                {
                    "dims": ["1"],"batchByteSize": "4"
                }
            },{
                "name": "OUTPUT0","raw":
                {
                    "dims": ["1","4"],"batchByteSize": "16"
                }
            },{
                "name": "OUTPUT1","batchByteSize": "4"
                }
            }
        ]
    },"Status":
    {
        "code": "SUCCESS","serverId": "inference:0","requestId": "12"
    },"Content-Length": 320,"Content-Type": "application/octet-stream"
}

我制作了三个包含数据的结构

struct Raw: Decodable {
    
    let dims: [String]?
    let batchByteSize: String?
}

struct Output: Decodable {
    
    let name: String?
    let raw: Raw?
}

struct InferResponse: Decodable {
    
    let modelName: String?
    let modelVersion: String?
    let batchSize: String?
    let output: [Output]?
}

因此,我实现了APIManager类来发送帖子并解析http响应标头。 代码如下。

class APIManager {
    
    static private let apiKey = "fill in key" // paste in Key(Token)
    static private let apiUrl = "fill in url" // paste in URL

    func postData(image: UIImage) {
        
        let urlString = APIManager.apiUrl

        let url = URL(string: urlString)

        guard url != nil else {

            print("URL nil")
            return
        }

        // header
        let token = "Bearer \(APIManager.apiKey)"

        var urlRequest = URLRequest(url: url!,cachePolicy: .useProtocolCachePolicy,timeoutInterval: 1)
        urlRequest.httpMethod = "POST"
        urlRequest.setValue(token,forHTTPHeaderField: "Authorization")
        urlRequest.setValue("batch_size: 1 input { name: \"input\" } output { name: \"Darknet\" cls { count: 1 } }",forHTTPHeaderField: "InferRequest") // fix this when we get actual value
        
        // body
        let imageData = image.pngData()
        
        urlRequest.httpBody = imageData?.base64EncodedData()
        
        // handle the request
        let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data,response,error) in
            
            if (error == nil && response != nil) {
                
                let httpResponse = response as? HTTPURLResponse
                
                if let inferResponse = httpResponse?.allHeaderFields["InferResponse"] as? String {
                    
                    let newData = inferResponse.data(using: .utf8)! // this is the part I'm having trouble with 
                    
                    do {
                    
                        let parsedResponse = try JSONDecoder().decode(InferResponse.self,from: newData)
                    }
                    catch {
                        
                        
                    }
                }
                else {
                    
                    print("failed to obtain 'InferResponse' field from response header")
                }
            }
        }
    }
}

但是,我对HTTP标头数据感到困惑。我的经理向我发送了一个二进制标头响应,她说这会有所帮助。那么,这是否意味着HTTP响应标头数据是二进制的?然后,我应该使用utf编码将其转换为字符串,然后将其解析为JSON吗?请给我一些有关如何改进此代码的建议。谢谢。

if let inferResponse = httpResponse?.allHeaderFields["InferResponse"] as? String {

    let newData = inferResponse.data(using: .utf8)! // this is the part I'm having trouble with 

    do {

        let parsedResponse = try JSONDecoder().decode(InferResponse.self,from: newData)                    
    }

    catch {


    }
}

解决方法

您快到了。解码操作由于数据类型而引发错误:

typeMismatch(Swift.String,Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "batchSize",intValue: nil)],debugDescription: "Expected to decode String but found a number instead.",underlyingError: nil))

这表明您的InferResponse.batchSizeInt,而不是String

struct InferResponse: Decodable {
    let modelName: String?
    let modelVersion: String?
    let batchSize: Int?
    let output: [Output]?
}

以后,请确保处理您的错误(执行/捕获)(或至少将其打印出来)。这应该有助于调试。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...