问题
Below mentioned is my method to upload a multipart image to the server but when I am trying to do so the app is crashing "unexpectedly found nill"
But value of image is there as I am selecting it from photo library.
func createCoupon(_ code: String, storeID: Int, description: String, terms: String, image: UIImage, startDate: String, endDate: String, couponDiscount: String, minimumDiscount: String, percentage: String, maximumDiscount: String){
let urlString = BaseURL + "create-coupon"
let params =
[
"code" : code,
"store_id" : storeID,
"type" : "merchant",
"description" : description,
"terms" : terms,
"start_date" : startDate,
"end_date" : endDate,
"coupon_discount" : couponDiscount,
"minimum_total" : minimumDiscount,
"percentage" : percentage,
"maximum_discount" : maximumDiscount
] as [String : Any]
let manager = Alamofire.SessionManager.default
manager.session.configuration.timeoutIntervalForRequest = 30000
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(UIImageJPEGRepresentation(image, 0.2)!, withName: "image", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
for (key, value) in params {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, to:urlString)
{
(result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
//Print progress
})
upload.responseJSON { response in
let resJson = response.result.value
print(resJson)
NotificationCenter.default.post(name: Notification.Name(rawValue: NotifRequestSuccess.createCoupon.rawValue), object: nil, userInfo: ["data": resJson!])
}
case .failure(let encodingError):
NotificationCenter.default.post(name: Notification.Name(rawValue: NotifRequestError.createCoupon.rawValue), object: encodingError, userInfo: nil)
}
}
回答1:
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(UIImageJPEGRepresentation(self.photoImageView.image!, 0.5)!, withName: "photo_path", fileName: "swift_file.jpeg", mimeType: "image/jpeg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
}, to:"http://server1/upload_img.php")
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (Progress) in
print("Upload Progress: \(Progress.fractionCompleted)")
})
upload.responseJSON { response in
//self.delegate?.showSuccessAlert()
print(response.request) // original URL request
print(response.response) // URL response
print(response.data) // server data
print(response.result) // result of response serialization
// self.showSuccesAlert()
//self.removeImage("frame", fileExtension: "txt")
if let JSON = response.result.value {
print("JSON: \(JSON)")
}
}
case .failure(let encodingError):
//self.delegate?.showFailAlert()
print(encodingError)
}
}
回答2:
Just simple Use this Function as
/// Data for image
var userImageString = Data()
/// Convert Image to Data
func convertImageToData(image: UIImage) -> Data {
let imageData = UIImageJPEGRepresentation(image, 0.1)!
return imageData
}
///Conversion Method - with target size if required
userImageString = convertImageToData(image: resizeImage(image: img, targetSize: CGSize.init(width: 600, height: 600)))
//MARK: Data to server
func imageDataToServer(parameters: [String : AnyObject])
{
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(self.userImageString, withName: "parameter_name", fileName: "image.jpeg", mimeType: "image/jpeg")
for (key, value) in parameters
{
multipartFormData.append(value.data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, to:"url", method: .post,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload,_,_):
upload.responseJSON { (response:DataResponse<Any>) in
print("RRRRR: \(response)")
if response.result.isSuccess
{
/// Success
}
else
{
/// Failure
}
}
upload.uploadProgress(closure: {
progress in
print(progress.fractionCompleted)
})
case .failure(let encodingError):
print(encodingError)
}
})
}
Function Usage
if you have parameters send Parameters else nil or [:]
self.imageDataToServer(parameters: parameters)
回答3:
I've created a func to satisfy thy needs in this case. Pass the UIImage in 'image' param in the below request.
multipartUploadRequestWith(imageData: UIImageJPEGRepresentation(image, 1.0), parameters: params, onCompletion: {
print("Upload Successful")
}) { (error) in
print(error.debugDescription)
}
Below is the code for the function.
func multipartUploadRequestWith(imageData: Data?, parameters: [String : Any], onCompletion: (() -> Void)? = nil, onError: ((Error?) -> Void)? = nil){
let url = /* your API url */
let headers: HTTPHeaders = [
/* "Authorization": "your_access_token", in case you need authorization header */
"Content-type": "multipart/form-data",
]
print(headers)
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 = imageData{
multipartFormData.append(data, withName: "photo", fileName: "photo.jpeg", mimeType: "image/jpeg")
}
}, usingThreshold: UInt64.init(), to: url, method: .post, headers: headers) { (result) in
switch result{
case .success(let upload, _, _):
upload.response { response in
if let err = response.error{
print("This error")
let alert = UIAlertController(title: "Upload Failed", message: "The image upload failed. Check your internet connection", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
UIApplication.shared.keyWindow?.rootViewController?.present(alert, animated: true, completion: nil)
onError?(err)
return
}
if response.response?.statusCode == 200 {
print("Succesfully uploaded")
onCompletion?()
} else {
print("Error " )
}
}
case .failure(let error):
print("Error in upload: \(error.localizedDescription)")
onError?(error)
}
}
}
回答4:
Try This
func callAPI( _ parameters:[String:Any] , url:String) {
print(parameters)
let uploadImageProfileURL = url
var urlRequest = URLRequest(url: URL(string:uploadImageProfileURL)!)
urlRequest.httpMethod = "POST"
urlRequest.allHTTPHeaderFields = [
"content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
"cache-control": "no-cache",
]
Alamofire.upload(multipartFormData: { multipartFormData in
for (key, value) in parameters {
if value is String {
multipartFormData.append((value as! String).data(using: String.Encoding.utf8)!, withName: key )
}
if value is UIImage {
let imgData = UIImageJPEGRepresentation(value as! UIImage, 1)!
multipartFormData.append(imgData, withName: key ,fileName: "file.jpg", mimeType: "image/jpg")
}
if value is Array<UIImage> {
let arrayValue = value as! [UIImage]
for image in arrayValue {
let fileName = "file\(arc4random()%1000).jpg"
let mimeType = "application/octet-stream" ?? "image/jpg"
let data = UIImageJPEGRepresentation(image, 1)
multipartFormData.append(data!, withName: "\(key)", fileName:fileName, mimeType: mimeType)
}
}
}},to:url,method: .post)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
if let JSON = response.result.value {
}
}
case .failure(let encodingError):
print(encodingError.localizedDescription)
}
}
}
回答5:
Use Below code for single Image Upload using Alamofire
: Swift 3.0
var strImagePicked = [UIImage]() // declared as global variable ... this will be image picked from ImagePickerController
Below is the function used for uploading single image from ImagePickerController
and call this method when you click button to upload Image
func imageuploadAPI(){
let params =
[
"code" : code,
"store_id" : storeID,
"type" : "merchant",
"description" : description,
"terms" : terms,
"start_date" : startDate,
"end_date" : endDate,
"coupon_discount" : couponDiscount,
"minimum_total" : minimumDiscount,
"percentage" : percentage,
"maximum_discount" : maximumDiscount
] as [String : Any]
Alamofire.upload(
multipartFormData: { MultipartFormData in
for (key, value) in params {
MultipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
for element in 0..<self.strImagePicked.count {
let singleImage : Data? = self.strImagePicked[element].lowestQualityJPEGNSData as Data?
MultipartFormData.append(singleImage!, withName: "image", fileName: "swift_file.jpg", mimeType: "image/jpeg")
//"image" is the parameter for image
}
}, to: "your_URL") { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
print(response.result.value as Any)
}
case .failure(let encodingError):
print(encodingError)
break
}
}
}
// extension is used for image so that if image will be of hight quality it will reduce it's size
extension UIImage {
var highestQualityJPEGNSData: NSData { return UIImageJPEGRepresentation(self, 1.0)! as NSData }
var highQualityJPEGNSData: NSData { return UIImageJPEGRepresentation(self, 0.75)! as NSData}
var mediumQualityJPEGNSData: NSData { return UIImageJPEGRepresentation(self, 0.5)! as NSData }
var lowQualityJPEGNSData: NSData { return UIImageJPEGRepresentation(self, 0.25)! as NSData}
var lowestQualityJPEGNSData: NSData { return UIImageJPEGRepresentation(self, 0.0)! as NSData }
}
回答6:
Alamofire4 and Swift 4.1
1st Step: Take a imageView and pick the image by using imagepickerview After that take a button in which below function will be call
**
func uploadAvatar() {
let id : String = UserDefaults.standard.value(forKey: "id") as! String
let token : String = UserDefaults.standard.value(forKey: "token") as! String
let url = "http://203.163.248.214:1357/api/user/update_image"
let headers = ["x-access-token": token]
showLoader(OnView: view)
let imageData = self.imgView.image!.jpegData(compressionQuality: 0.7)
let parameters: [String : AnyObject] = ["user_id": id as AnyObject]
Alamofire.upload(multipartFormData:{ multipartFormData in
multipartFormData.append(imageData!, withName: "file", fileName: "file.jpeg", mimeType: "image/jpeg")
for (key, value) in parameters
{
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, to: url, headers: headers)
{ (result) in
switch result {
case .success(let upload,_,_ ):
upload.uploadProgress(closure: { (progress) in
//Print progress
})
upload.responseJSON
{ response in
let json = response.result.value as! [String:AnyObject]
print(json)
if response.result.value != nil
{
if json["status"] as! NSInteger == 200 {
DispatchQueue.main.async(execute: {() -> Void in
self.dismissLoader()
self.userImage = json["data"] as! [String:AnyObject]
})
}else{
self.dismissLoader()
}
}
}
case .failure( _):
self.dismissLoader()
break
}
}
}*
*
userImage will be ur array or may be dictionary depends upon the response and declare it globally as var userImage = String: AnyObject
来源:https://stackoverflow.com/questions/50041287/how-to-upload-multipart-image-to-server-using-alamofire