'Swift Upload Multi Images to PHP Server
I want to upload multiple images to my server using Alamofire Lib, but it's uploading 1 image only.
I'm using an image picker that returns an array of UIImage which is Named
imagesdata
This is my code:
@IBAction func uploadimages(_ sender: Any) {
Alamofire.upload(
multipartFormData: { multipartFormData in
for img in self.imagesdata{
let imgdata = UIImageJPEGRepresentation(img, 1.0)
multipartFormData.append(imgdata!,withName: "image", fileName: "image.jpg", mimeType: "image/jpeg")
print("$$$$$$$$$$ : \(imgdata!)")
}
},
to: "http://localhost/maarathtest/MAPI/img_upload.php",
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
and my PHP:
<?php
$response = array();
if (empty($_FILES["image"])) {
$response['File'] = "NOFILE";;
} else {
$filename = uniqid() . ".jpg";
// If the server can move the temporary uploaded file to the server
if (move_uploaded_file($_FILES['image']['tmp_name'], "images/" . $filename)) {
$response['status'] = "Success";
$response['filepath'] = "https://serverName/MAPI/images/" . $filename;
} else {
$response['status'] = "Failure";
}
}
echo json_encode($response);
?>
And my console log:
$$$$$$$$$$ : 5849743 bytes
$$$$$$$$$$ : 3253337 bytes
[Request]: POST http://localhost/maarathtest/MAPI/img_upload.php
[Response]: <NSHTTPURLResponse: 0x600000620940> { URL: http://localhost/maarathtest/MAPI/img_upload.php } { status code: 200, headers {
Connection = "Keep-Alive";
"Content-Length" = 101;
"Content-Type" = "text/html";
Date = "Thu, 25 May 2017 10:08:08 GMT";
"Keep-Alive" = "timeout=5, max=100";
Server = "Apache/2.4.18 (Unix) OpenSSL/1.0.2h PHP/5.5.35 mod_perl/2.0.8-dev Perl/v5.16.3";
"X-Powered-By" = "PHP/5.5.35";
} }
[Data]: 101 bytes
[Result]: SUCCESS: {
filepath = "https://serverName/MAPI/images/5926ad083b770.jpg";
status = Success;
}
I have changed my code as below,
Alamofire.upload(
multipartFormData: { multipartFormData in
var count = 1
for img in self.imagesdata{
let imgdata = UIImageJPEGRepresentation(img, 1.0)
multipartFormData.append(imgdata!,withName: "image\(count)", fileName: "image\(count).jpg", mimeType: "image/jpeg")
count += 1
}
},...
<?php
$response = array();
if (empty($_FILES["image1"])) {
$response['File1'] = "NOFILE";
} else {
$filename = uniqid() . ".jpg";
// If the server can move the temporary uploaded file to the server
if (move_uploaded_file($_FILES['image1']['tmp_name'], "images/" . $filename)) {
$response['status1'] = "Success";
$response['filepath1'] = "https://serverName/MAPI/images/" . $filename;
} else {
$response['status1'] = "Failure";
}
}
if (empty($_FILES["image2"])) {
$response['File2'] = "NOFILE";
} else {
$filename = uniqid() . ".jpg";
// If the server can move the temporary uploaded file to the server
if (move_uploaded_file($_FILES['image2']['tmp_name'], "images/" . $filename)) {
$response['status2'] = "Success";
$response['filepath2'] = "https://serverName/MAPI/images/" . $filename;
} else {
$response['status2'] = "Failure";
}
}
echo json_encode($response);
?>
Now it's uploading the images, but I don't think this is the proper way to do it, since I don't know how many images users want to upload!
How can I do this properly?
Solution 1:[1]
I have solved the issue, the code below hope to help some 1
Swift :
@IBAction func uploadimages(_ sender: Any) {
Alamofire.upload(
multipartFormData: { multipartFormData in
var count = 1
for img in self.imagesdata{
let imgdata = UIImageJPEGRepresentation(img, 0.5)
// the name should be as array other wise want work
multipartFormData.append(imgdata!,withName: "image[]", fileName: "image\(count).jpg", mimeType: "image/jpeg")
count += 1
}
},
to: "http://localhost/maarathtest/MAPI/img_upload.php",
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
}
case .failure(let encodingError):
print(encodingError)
}
}
)
}
PHP code sample :
<?php
$response = array();
if (empty($_FILES["image"])) {
$response['File1'] = "NOFILE";
}else {
//$filename = uniqid() . ".jpg";
// loop through files array from IOS app
foreach ($_FILES["image"]["tmp_name"] as $index => $tmp_name) {
$filePath = "images/" . basename($_FILES["image"]["name"][$index]);
if (move_uploaded_file($tmp_name, $filePath)) {
// Images are stored in file path , do what ever is needed
$response['filepath'][$index] = $filePath;
}
$response['status'] = "Success";
}
}
echo json_encode($response);
?>
Solution 2:[2]
Use this below code to upload multiple images to your server. I've put this in a method that takes in NSMutableArray of UIImage objects and their corresponding names in another array. You could change NSMutableArray to Swift Array if you want. After successful upload, the completion handler will get called and would return a mapped object based on your response:
Code:
public func executeMultipleImageUpload<T: Mappable>(type: T.Type, url: String, parameters: Dictionary<String, String>, images: NSMutableArray?, names: [String], view: UIView, completion: @escaping(_ result: DataResponse<T>?)-> Void) {
//Calling Alamofire Upload method here...
Alamofire.upload(multipartFormData: { multipartFormData in // This is first param, the part data itself
if images == nil || images?.count == 0 {
print("There are no images to upload..!!")
} else {
//Append image data from array of images to multipart form data
var count = 1
for image in images! {
if let imageData = UIImageJPEGRepresentation(image as! UIImage, 0.76) {
multipartFormData.append(imageData, withName: names[count - 1], fileName: names[count - 1], mimeType: "image/jpeg")
}
count += 1
}
}
//We are encoding the parameters to be sent here in the multipart as well..
for (key, value) in parameters {
multipartFormData.append((value.data(using: .utf8))!, withName: key)
}}, to: url, method: .post, headers: ["": ""], //This is second param (to:)
encodingCompletion: { encodingResult in // This is third param (encodingCompletion:)
switch encodingResult {
case .success(let upload, _, _):
upload.response { [weak self] response in
guard self != nil else {
return
}
debugPrint(response)
}.validate().responseObject{
(response: DataResponse<T>) in
completion(response)
}
case .failure(let encodingError):
print("error:\(encodingError)")
}
})
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Mohammed Riyadh |
| Solution 2 | badhanganesh |
