Ios Swift:如何在post请求中为主体创建实际的JSON

Ios Swift:如何在post请求中为主体创建实际的JSON,ios,swift,Ios,Swift,我很难弄清楚如何在swift中构造这个JSON结构。我试着玩弄字典和数组,在StackOverflow上寻找类似的问题,但它们并没有解决我的问题 { "requests": [ { "image": { "content": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z" }, "features": [

我很难弄清楚如何在swift中构造这个JSON结构。我试着玩弄字典和数组,在StackOverflow上寻找类似的问题,但它们并没有解决我的问题

    {
  "requests": [
    {
      "image": {
        "content": "/9j/7QBEUGhvdG9zaG9...base64-encoded-image-content...fXNWzvDEeYxxxzj/Coa6Bax//Z"
      },
      "features": [
        {
          "type": "TEXT_DETECTION"
        }
      ]
    }
  ]
}
试过这样的方法:

let request = [["image":["content":"base64endocedString"]],
                   ["type":"TEXT_DETECTION"]]

    let dictionary : [String : Any] = [
        "requests":request
    ] 
通过此函数的输出:

[
  "requests": [
    [
      "image": [
        "content": "base64endocedString"
      ]
    ],
    [
      "type": "TEXT_DETECTION"
    ]
  ]
]

我认为您正在使用google vision API从图像创建请求OCR数据。您应该按以下方式使用它:

    let parameters: [String: AnyObject] = [
            "requests": [
                "image": ["content": base64EncodeImage(image)],
                "features": [ "type": "TEXT_DETECTION" ],
            ]
        ] as [String: AnyObject]
对我来说,我还需要面部表情检测,就像:

    let header: [String: String] = ["Content-Type": "application/json",
                                    "X-Ios-Bundle-Identifier": Bundle.main.bundleIdentifier ?? ""]

    let param: [String: AnyObject] = [ "requests": [
            "image": [
                "content": base64EncodeImage(image)
            ],
            "features": [
                [
                    "type": "DOCUMENT_TEXT_DETECTION",
                    "maxResults": 10
                ],
                [
                    "type": "FACE_DETECTION",
                    "maxResults": 10
                ]
            ]
        ] ] as [String: AnyObject]
其中
func base64EncodeImage
是:

func base64EncodeImage(_ image: UIImage) -> String {
    let imagedata = image.resizeImageToUploadOnServer(maxSizeInKB: 2048)
    return imagedata.base64EncodedString(options: .endLineWithCarriageReturn)
}
extension UIImage {
    func resizeImageToUploadOnServer(maxSizeInKB: Int) -> Data {
        print("\(self.size)")

        let (imageSize, imageData) = self.logImageSizeInKB(scale: 1.0)
        if imageSize > maxSizeInKB {
            let resizedImage = self.reSizeImage()
            var scale: CGFloat = 1.0
            var (size, imageData) = resizedImage.logImageSizeInKB(scale: scale)
            while size > maxSizeInKB {
                scale -= 0.1
                if scale > 0 {
                    (size, imageData) = resizedImage.logImageSizeInKB(scale: scale)
                } else {
                    break
                }
                return imageData
            }
        }
        return imageData
    }

    func logImageSizeInKB(scale: CGFloat) -> (Int, Data) {
        let data = UIImageJPEGRepresentation(self, scale)!
        let formatter = ByteCountFormatter()
        formatter.allowedUnits = ByteCountFormatter.Units.useKB
        formatter.countStyle = ByteCountFormatter.CountStyle.file
        let imageSize = formatter.string(fromByteCount: Int64(data.count))
        print("ImageSize(KB): \(imageSize)")

        return (Int(Int64(data.count) / 1024), data)
    }

    func reSizeImage() -> UIImage {
        var actualHeight = Float(self.size.height)
        var actualWidth = Float(self.size.width)
        let maxHeight: Float = 2000.0
        let maxWidth: Float = 2000.0
        var imgRatio: Float = actualWidth / actualHeight
        let maxRatio: Float = maxWidth / maxHeight
        let compressionQuality: CGFloat = 1.0
        if actualHeight > maxHeight || actualWidth > maxWidth {
            if imgRatio < maxRatio {
                //adjust width according to maxHeight
                imgRatio = maxHeight / actualHeight
                actualWidth = imgRatio * actualWidth
                actualHeight = maxHeight
            } else if imgRatio > maxRatio {
                //adjust height according to maxWidth
                imgRatio = maxWidth / actualWidth
                actualHeight = imgRatio * actualHeight
                actualWidth = maxWidth
            } else {
                actualHeight = maxHeight
                actualWidth = maxWidth
            }
        }
        let rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight))
        UIGraphicsBeginImageContext(rect.size)
        self.draw(in: rect)

        let img = UIGraphicsGetImageFromCurrentImageContext()!
        let imageData: Data = UIImageJPEGRepresentation(img, compressionQuality)!
        UIGraphicsEndImageContext()

        return UIImage(data: imageData)!
    }
}
使用此扩展名调整图像大小:

func base64EncodeImage(_ image: UIImage) -> String {
    let imagedata = image.resizeImageToUploadOnServer(maxSizeInKB: 2048)
    return imagedata.base64EncodedString(options: .endLineWithCarriageReturn)
}
extension UIImage {
    func resizeImageToUploadOnServer(maxSizeInKB: Int) -> Data {
        print("\(self.size)")

        let (imageSize, imageData) = self.logImageSizeInKB(scale: 1.0)
        if imageSize > maxSizeInKB {
            let resizedImage = self.reSizeImage()
            var scale: CGFloat = 1.0
            var (size, imageData) = resizedImage.logImageSizeInKB(scale: scale)
            while size > maxSizeInKB {
                scale -= 0.1
                if scale > 0 {
                    (size, imageData) = resizedImage.logImageSizeInKB(scale: scale)
                } else {
                    break
                }
                return imageData
            }
        }
        return imageData
    }

    func logImageSizeInKB(scale: CGFloat) -> (Int, Data) {
        let data = UIImageJPEGRepresentation(self, scale)!
        let formatter = ByteCountFormatter()
        formatter.allowedUnits = ByteCountFormatter.Units.useKB
        formatter.countStyle = ByteCountFormatter.CountStyle.file
        let imageSize = formatter.string(fromByteCount: Int64(data.count))
        print("ImageSize(KB): \(imageSize)")

        return (Int(Int64(data.count) / 1024), data)
    }

    func reSizeImage() -> UIImage {
        var actualHeight = Float(self.size.height)
        var actualWidth = Float(self.size.width)
        let maxHeight: Float = 2000.0
        let maxWidth: Float = 2000.0
        var imgRatio: Float = actualWidth / actualHeight
        let maxRatio: Float = maxWidth / maxHeight
        let compressionQuality: CGFloat = 1.0
        if actualHeight > maxHeight || actualWidth > maxWidth {
            if imgRatio < maxRatio {
                //adjust width according to maxHeight
                imgRatio = maxHeight / actualHeight
                actualWidth = imgRatio * actualWidth
                actualHeight = maxHeight
            } else if imgRatio > maxRatio {
                //adjust height according to maxWidth
                imgRatio = maxWidth / actualWidth
                actualHeight = imgRatio * actualHeight
                actualWidth = maxWidth
            } else {
                actualHeight = maxHeight
                actualWidth = maxWidth
            }
        }
        let rect = CGRect(x: 0.0, y: 0.0, width: CGFloat(actualWidth), height: CGFloat(actualHeight))
        UIGraphicsBeginImageContext(rect.size)
        self.draw(in: rect)

        let img = UIGraphicsGetImageFromCurrentImageContext()!
        let imageData: Data = UIImageJPEGRepresentation(img, compressionQuality)!
        UIGraphicsEndImageContext()

        return UIImage(data: imageData)!
    }
}
扩展UIImage{ func resizeImageToUploadOnServer(maxSizeInKB:Int)->数据{ 打印(“\(self.size)”) let(imageSize,imageData)=self.logImageSizeInKB(比例:1.0) 如果imageSize>maxSizeInKB{ 设resizedImage=self.reSizeImage() 变量刻度:CGFloat=1.0 变量(大小,图像数据)=resizedImage.logImageSizeInKB(比例:比例) 而尺寸>最大尺寸{ 比例-=0.1 如果比例>0{ (大小,图像数据)=resizedImage.logImageSizeInKB(比例:比例) }否则{ 打破 } 返回图像数据 } } 返回图像数据 } func logImageSizeInKB(比例:CGFloat)->(整数,数据){ 让数据=UIImageJPEG表示(自身,比例)! let formatter=字节计数格式化程序() formatter.allowedUnits=字节计数formatter.Units.useKB formatter.countStyle=字节countformatter.countStyle.file 让imageSize=formatter.string(fromByteCount:Int64(data.count)) 打印(“图像大小(KB):\(图像大小)”) 返回(Int(Int64(data.count)/1024),数据) } func reSizeImage()->UIImage{ 变量实际高度=浮动(自身大小高度) var actualWidth=浮点(self.size.width) 设maxHeight:Float=2000.0 设maxWidth:Float=2000.0 变量imgRatio:Float=实际宽度/实际高度 设maxRatio:Float=maxWidth/maxHeight let压缩质量:CGFloat=1.0 如果实际高度>最大高度| |实际宽度>最大宽度{ 如果imgRatiomaxRatio{ //根据maxWidth调整高度 imgRatio=最大宽度/实际宽度 实际高度=绝对高度*实际高度 实际宽度=最大宽度 }否则{ 实际高度=最大高度 实际宽度=最大宽度 } } 设rect=CGRect(x:0.0,y:0.0,宽度:CGFloat(实际宽度),高度:CGFloat(实际高度)) UIGraphicsBeginImageContext(矩形大小) 自绘制(in:rect) 让img=UIGraphicsGetImageFromCurrentImageContext()! 让imageData:Data=UIImageJPEG表示(img,压缩质量)! UIGraphicsSendImageContext() 返回UIImage(数据:imageData)! } }
需要注意的两点。1.没有代码/数据2的图像。请详细说明您面临的问题。请提供您的一些尝试代码。我必须向google vision API发出请求,在请求正文中发送base64编码的图像。我的问题是构造实际的json结构,使其看起来像上图。我在提出实际请求时没有遇到任何问题,我只是在swiftWelcome@kMose中使用字典等创建这种结构。请问您如何确保base64EncodeImage不会太长?我使用扩展来调整图像大小更新了调整大小的答案:)