【发布时间】:2021-07-23 12:16:18
【问题描述】:
我想使用 Alamofire 将数据和图像发送到我的数据库,方法是将数据附加到请求正文中。现在我已成功插入所有数据,但没有插入图像(图像未插入数据库)。图像来自.photoLibrary 或.camera,然后将其转换为位图字符串数据,然后再将图像发送到服务器。如何使用 alamofire 将转换后的位图图像插入数据库?
这是我的内容视图
import SwiftUI
import UIKit
import Alamofire
import MobileCoreServices
struct ContentView: View {
@State var chassisNumber = ""
@State var engineNumber = ""
@State var lisencePlate = ""
@State var carYear = ""
@State var carModel = ""
@State var vehiclePicture = ""
@State var imageSelected: UIImage
@State var sourceType: UIImagePickerController.SourceType = .camera
@State var showImagePicker = false
@AppStorage("userEmail") var currentUserEmail: String?
var body: some View {
VStack{
Button(action: {
sourceType = UIImagePickerController.SourceType.photoLibrary
self.showImagePicker = true
}, label: {
Text("Choose Image")
})
TextField("Car Model", text: $carModel)
TextField("Car Year", text: $carYear)
TextField("Chassis Number", text: $chassisNumber)
TextField("Engine Number", text: $engineNumber)
TextField("Lisence Plate", text: $lisencePlate)
Button(action: {
vehiclePicture = randomString(length: 25)
insertNewVehicle(EMAIL: currentUserEmail ?? "Empty", NAMA_MODEL: carModel, TAHUN_PRODUKSI: carYear, CHASSISNO: chassisNumber, ENGINENO: engineNumber, NOPOL: lisencePlate, VEHICLE_PICTURE: vehiclePicture, ENCODED_IMG: imageSelected)
}, label: {Text("Save"})
}
.sheet(isPresented: $showImagePicker){
ImagePicker(imageSelected: $imageSelected, sourceType: $sourceType)
}
}
}
func insertNewVehicle(EMAIL: String, NAMA_MODEL: String, TAHUN_PRODUKSI: String, CHASSISNO: String, ENGINENO: String, NOPOL: String, VEHICLE_PICTURE: String, ENCODED_IMG: UIImage?){
let parameters = ["EMAIL": EMAIL, "NAMA_MODEL": NAMA_MODEL, "TAHUN_PRODUKSI": TAHUN_PRODUKSI, "CHASSISNO": CHASSISNO, "ENGINENO": ENGINENO, "NOPOL": NOPOL, "VEHICLE_PICTURE": VEHICLE_PICTURE]
AF.upload(multipartFormData: { multipartFormData in
for (key,value) in parameters {
multipartFormData.append((value).data(using: .utf8)!, withName: key)
}
// Upload image to server << image is not inserted
guard let image = ENCODED_IMG else { return }
let jpegData = image.toJpegData(compressionQuality: 0.4)
multipartFormData.append(Data((jpegData)!), withName: "ENCODED_IMG")
}, to: "http://myapi")
.responseJSON { response in
// Check whether chassis number is exist or not
if let data = response.data, let string = String(data: data, encoding: .utf8){
// If chassis number is exist
print(string)
}else{
// If chassis number is not exist
print("Chassis not exists, inserting data...")
}
}
}
func randomString(length: Int) -> String {
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map{ _ in letters.randomElement()! })
}
我从这里得到了 convertToJpegData https://stackoverflow.com/a/55839062/15132219
extension UIImage {
func toJpegData (compressionQuality: CGFloat, hasAlpha: Bool = true, orientation: Int = 6) -> Data? {
guard cgImage != nil else { return nil }
let options: NSDictionary = [
kCGImagePropertyOrientation: orientation,
kCGImagePropertyHasAlpha: hasAlpha,
kCGImageDestinationLossyCompressionQuality: compressionQuality
]
return toData(options: options, type: .jpeg)
}
func toData (options: NSDictionary, type: ImageType) -> Data? {
guard cgImage != nil else { return nil }
return toData(options: options, type: type.value)
}
// about properties: https://developer.apple.com/documentation/imageio/1464962-cgimagedestinationaddimage
func toData (options: NSDictionary, type: CFString) -> Data? {
guard let cgImage = cgImage else { return nil }
return autoreleasepool { () -> Data? in
let data = NSMutableData()
guard let imageDestination = CGImageDestinationCreateWithData(data as CFMutableData, type, 1, nil) else { return nil }
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
return data as Data
}
}
// https://developer.apple.com/documentation/mobilecoreservices/uttype/uti_image_content_types
enum ImageType {
case image // abstract image data
case jpeg // JPEG image
case jpeg2000 // JPEG-2000 image
case tiff // TIFF image
case pict // Quickdraw PICT format
case gif // GIF image
case png // PNG image
case quickTimeImage // QuickTime image format (OSType 'qtif')
case appleICNS // Apple icon data
case bmp // Windows bitmap
case ico // Windows icon data
case rawImage // base type for raw image data (.raw)
case scalableVectorGraphics // SVG image
case livePhoto // Live Photo
var value: CFString {
switch self {
case .image: return kUTTypeImage
case .jpeg: return kUTTypeJPEG
case .jpeg2000: return kUTTypeJPEG2000
case .tiff: return kUTTypeTIFF
case .pict: return kUTTypePICT
case .gif: return kUTTypeGIF
case .png: return kUTTypePNG
case .quickTimeImage: return kUTTypeQuickTimeImage
case .appleICNS: return kUTTypeAppleICNS
case .bmp: return kUTTypeBMP
case .ico: return kUTTypeICO
case .rawImage: return kUTTypeRawImage
case .scalableVectorGraphics: return kUTTypeScalableVectorGraphics
case .livePhoto: return kUTTypeLivePhoto
}
}
}
}
【问题讨论】:
-
toJpegData(compressionQuality:) 从何而来?
-
对不起,我忘了补充。我已经编辑了我的问题
-
错误是说响应没有返回任何
httpBody。是不是应该寄回去?应该是什么反应?您能否验证您的图片未正确上传? -
如果我成功插入数据。响应将不返回任何内容,如果错误(数据库中存在机箱号)将返回字符串“机箱号已存在”。我不知道我是否正确上传图片代码,因为我从未尝试使用 alamofire 上传图片。在我的代码中,除了上传图片部分,所有数据都可以插入。
-
"如果我成功插入数据。响应将不返回任何内容" 您看到的错误是因为响应没有任何httpBody。所以我猜它成功了?你不能在服务器上检查图像是否可见?
标签: ios swift xcode alamofire swift5