How to Upload Images to a Server in iOS With Swift

iOS Swift 5 - Upload a file with a server by calling a PHP function

I've found a solution, here's my edited Swift 5 function, which now can also accept mp4 video files, not just jpg or png images:

func uploadFile(fileData:Data, fileName:String , completion: @escaping (_ fileURL:String?, _ error:String?) -> Void) {
print("FILENAME: \(fileName)")

let boundary: String = "------VohpleBoundary4QuqLuM1cE5lMwCy"
let contentType: String = "multipart/form-data; boundary=\(boundary)"
let request = NSMutableURLRequest()
request.url = URL(string: DATABASE_PATH + "upload-file.php")
request.httpShouldHandleCookies = false
request.timeoutInterval = 60
request.httpMethod = "POST"
request.setValue(contentType, forHTTPHeaderField: "Content-Type")
let body = NSMutableData()
body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"fileName\"\r\n\r\n".data(using: String.Encoding.utf8)!)
body.append("\(fileName)\r\n".data(using: String.Encoding.utf8)!)

body.append("--\(boundary)\r\n".data(using: String.Encoding.utf8)!)
body.append("Content-Disposition: form-data; name=\"file\"; filename=\"file\"\r\n".data(using: String.Encoding.utf8)!)

// File is an image
if fileName.hasSuffix(".jpg") {
body.append("Content-Type:image/png\r\n\r\n".data(using: String.Encoding.utf8)!)
// File is a video
} else if fileName.hasSuffix(".mp4") {
body.append("Content-Type:video/mp4\r\n\r\n".data(using: String.Encoding.utf8)!)
}

body.append(fileData)
body.append("\r\n".data(using: String.Encoding.utf8)!)


body.append("--\(boundary)--\r\n".data(using: String.Encoding.utf8)!)
request.httpBody = body as Data
let session = URLSession.shared
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
guard let _:Data = data as Data?, let _:URLResponse = response, error == nil else {
DispatchQueue.main.async { completion(nil, error!.localizedDescription) }
return
}
if let response = String(data: data!, encoding: String.Encoding(rawValue: String.Encoding.utf8.rawValue)) {
print("XSUploadFile -> RESPONSE: " + DATABASE_PATH + response)
DispatchQueue.main.async { completion(DATABASE_PATH + response, nil) }

// NO response
} else { DispatchQueue.main.async { completion(nil, E_401) } }// ./ If response
}; task.resume()
}

Here's how I use that function:

let imageData = UIImage(named: "my_img")!.jpegData(compressionQuality: 1)
uploadFile(fileData: imageData!, fileName: "image.jpg") { (fileURL, e) in
if e == nil {
print("FILE URL: " + fileURL!)
}}

This works 100%.

uploading image to server using swift 4 use Multi part & Alamofire

I think you also need to use multipart data with Almaofire upload

see this

let parameters = [
// List Parameter here if any
]

Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData, 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:"yourURL")
{ (result) in
switch result {
case .success(let upload, _, _):

upload.uploadProgress(closure: { (progress) in
//Print progress
})

upload.responseJSON { response in
//print response.result
}

case .failure(let encodingError):
//print encodingError.description
}
}

Upload image to server - Swift 3

I use the following structure for sending images:

func createRequestBodyWith(parameters:[String:NSObject], filePathKey:String, boundary:String) -> NSData {

let body = NSMutableData()

for (key, value) in parameters {
body.appendString(string: "--\(boundary)\r\n")
body.appendString(string: "Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n")
body.appendString(string: "\(value)\r\n")
}

body.appendString(string: "--\(boundary)\r\n")

let mimetype = "image/jpg"

let defFileName = "yourImageName.jpg"

let imageData = UIImageJPEGRepresentation(yourImage, 1)

body.appendString(string: "Content-Disposition: form-data; name=\"\(filePathKey!)\"; filename=\"\(defFileName)\"\r\n")
body.appendString(string: "Content-Type: \(mimetype)\r\n\r\n")
body.append(imageData!)
body.appendString(string: "\r\n")

body.appendString(string: "--\(boundary)--\r\n")

return body
}



func generateBoundaryString() -> String {
return "Boundary-\(NSUUID().uuidString)"
}



extension NSMutableData {
func appendString(string: String) {
let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
append(data!)
}
}

then you have to create body in your function like following:

request.httpBody = self.createRequestBodyWith(parameters:yourParamsDictionary, filePathKey:yourKey, boundary:self.generateBoundaryString)

uploading multi images to the server with swift using Alamofire or anyway to achieve that from the first step to know how we use it with image picker

finally I got an easy answer using a pod called OpalImagePicker and the way is so easy using Alamofire:

code from the first to understand

import Alamofire
import ImagePicker
import Photos
import OpalImagePicker

class PostVC: UIViewController,UITextViewDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate, ImagePickerDelegate,OpalImagePickerControllerDelegate {

var arryOfImages = [UIImage]()

// you have to put them don't worry about those funcs
func wrapperDidPress(_ imagePicker: ImagePickerController, images: [UIImage]) {
print("picked")
}

func doneButtonDidPress(_ imagePicker: ImagePickerController, images: [UIImage]) {
print("done")

func cancelButtonDidPress(_ imagePicker: ImagePickerController) {
print("cancel")
}

// set in your button action to get images the image/video .. etc and num of them



@IBAction func addPicture_clicked(_ sender: Any) {
let imagePicker = OpalImagePickerController()
imagePicker.imagePickerDelegate = self
imagePicker.maximumSelectionsAllowed = 3
imagePicker.allowedMediaTypes = Set([PHAssetMediaType.image]) //you can select only images set this
present(imagePicker, animated: true, completion: nil)


}

func imagePicker(_ picker: OpalImagePickerController, didFinishPickingImages images: [UIImage]){
print(images)
self.arryOfImages = images
picker.dismiss(animated: true, completion: nill

}


The Request You Want

//finally the request and thank you ^^



func addPostClicked(){

guard let text = postTextView.text else {
return
}
let token = "UYJ9ohx_M6JvDbJu0"

let profileId = 104
let params : [String: Any] = [
"postText" :text,
"profileId":profileId
]


Alamofire.upload(
multipartFormData: { multipartFormData in
var count = 1
for img in self.arryOfImages {
//here we send our images
let imageData = img.jpegData(compressionQuality: 0.5)
multipartFormData.append(imageData!, withName: "images[]", fileName: "image\(count).jpeg", mimeType: "image/jpeg")
count += 1
}

for (key, value) in params
{
multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key)

}
}, to:"https://api.yoogad.com/rest/api/v1/post/create", method:.post, headers: ["x-auth-token" : token],encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
debugPrint(response)
self.dismiss(animated: true)
}
case .failure(let encodingError):
print(encodingError)
}
})
}


Related Topics



Leave a reply



Submit