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
Zooming Mkmapview to Fit Annotation Pins
Xcode 6: Keyboard Does Not Show Up in Simulator
#Warning: C-Style For Statement Is Deprecated and Will Be Removed in a Future Version of Swift
How to Test Apple Push Notification Service Without an Iphone
In Ios13 the Status Bar Background Colour Is Different from the Navigation Bar in Large Text Mode
How Does View Controller Containment Work in iOS 5
How to Perform Wireless Debugging in Xcode 9 With iOS 11, Apple Tv 4K, etc
Unwind Segue Not Working in iOS 8
Swift Convert Unix Time to Date and Time
Difference Between Uiviewcontentmodescaleaspectfit and Uiviewcontentmodescaletofill
Anyobject Not Working in Xcode8 Beta6
How to Support Universal Links in iOS App and Setup Server For It
Table Header Views in Storyboards
Getting List of Files in Documents Folder
Uitableview Cell Selected Color
Undocumented Nsurlerrordomain Error Codes (-1001, -1003 and -1004) Using Storekit