Swift - Alamofire - upload file from photolibrary - swift

I'm trying to implement an upload from my photo-library with Alamofire:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
return
}
let documentDirectory: NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as NSString
let imageName = "temp"
let imagePath = documentDirectory.appendingPathComponent(imageName)
if let data = UIImageJPEGRepresentation(image, 80) {
do {
try data.write(to: URL(fileURLWithPath: imagePath), options: .atomic)
} catch let error {
print(error)
}
}
Alamofire.upload(.POST, "\(self.app_url)/user/upload", multipartFormData: { formData in
let filePath = NSURL(fileURLWithPath: image)
formData.appendBodyPart(fileURL: filePath, name: "upload")
formData.appendBodyPart(data: "Alamofire".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!, name: "test")
}, encodingCompletion: { encodingResult in
switch encodingResult {
case .Success:
print("SUCCESS")
case .Failure(let error):
print(error)
}
})
self.dismiss(animated: true, completion: nil)
}
And it prints:
Ambiguous reference to member 'upload(_:to:method:headers:)'
Can anybody explain me how to resolve this issue?
Thanks and Greetings!

In Swift 3 and Alamofire 4
Here is the Full Implementation of how to upload using Alamofire
Add the Following to your ViewController Class:
UIImagePickerControllerDelegate and UINavigationControllerDelegate
Create A Button:
First Create a button and implement the Following method in it for picker view
#IBAction func btnSelectProfileImageClicked(_ sender: Any) {
let ImagePicker = UIImagePickerController()
ImagePicker.delegate = self
ImagePicker.sourceType = UIImagePickerControllerSourceType.photoLibrary
self.present(ImagePicker, animated: true, completion: nil)
}
Then Implement the following UIPicker Methods:
func imagePickerController( _ picker: UIImagePickerController,didFinishPickingMediaWithInfo info:[String : Any] )
{Imgprofile.image = info[UIImagePickerControllerOriginalImage] as? UIImage
self.dismiss(animated: true, completion: nil)}
Make Another Button Which Passes the data to URL using Alamofire and Give an #IBAction outlet to it to it :
Enter Following Data to it
#IBAction func btnUpdateProfileSelected(_ sender: Any) {
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(UIImageJPEGRepresentation(self.Imgprofile.image!, 1)!, withName: "Prescription", fileName: "Profile_Image.jpeg", mimeType: "image/jpeg")
}, to:" Your URL Here where You want to Upload")
{ (result) in
switch result {
case .success(let upload, _, _):
print(result)
upload.uploadProgress(closure: { (progress) in
print(progress)
})
upload.responseJSON { response in
//print response.result
print(response);
}
case .failure(let encodingError):
print(encodingError);
}
}
}
Thats all
Hope This helps
For Full sample code or any doubts please comment. I will provide you
the sample code for this. Which Includes the Fetching as well as
upload data using Alamofire.
Thanks

Related

Upload an Image to a server from UIImagePickerController using Alamofire 5.0 swift 5

I want to ask how to upload an Image to a server from UIIMagePicker Controller using Alamofire 5.0 with swift 5.
Here is my code which is not really working
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
let imageData = Data(pickedImage.pngData()!)
let photo = UIImage.init(named: "photo")
let parameters: [String: String] = ["Benutzername": "lina.str"] //var parameters: [String: Any] = [:]
AF.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imageData, withName: "picture", fileName: "image", mimeType: "image/jpg")
for (key,value) in parameters {
multipartFormData.append((value ).data(using: .utf8)!, withName: key)
}
guard let image = photo else { return }
let jpegData = image.jpegData(compressionQuality: 1.0)
multipartFormData.append(Data((jpegData)!), withName: "photo")
}, to: "https://mydomain/ajax/Upload.php")
.responseString { response in
debugPrint(response)
}
}
dismiss(animated: true, completion: nil)
}
The problem is that the file isn't uploading the Image.
check this...
{
let url = "https://mydomain/ajax/Upload.php"
let imgData = imageDev.jpegData(compressionQuality: 0.1)!
let parameters = ["Benutzername": "lina.str"]
//Optional for extra parameter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy-hh-mm-ss"
let dateString = dateFormatter.string(from: Date())
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "picture",fileName: "uploads"+dateString+".jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
} //Optional for extra parameters
},
to:url,method:.post)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
if let result = response.result.value as? [String : Any]
{
}
}
case .failure(let encodingError):
print(encodingError)
}
}
}

UIImagePickerController not initiating next function

I'm using Swift 5 and have integrated MessageKit into my app. Here's the expected functionality:
User selects the image via picker
uploadImage function is initiated
Image is uploaded and displayed
What's actually happening:
User selects the image via picker
Nothing happens from there.
I'm not getting a single error message. I've put in print statements to see if it's even entering the uploadImage() function but it's not kicking off. I've change the uipickerimagecontroller code to exact code in other places of my app that is working and even that's not kicking off the function. I know my code isn't pretty but I'm still learning (please don't judge lol). Can anyone help:
Variable setup
private var isSendingPhoto = true {
didSet {
DispatchQueue.main.async {
self.messageInputBar.leftStackViewItems.forEach { item in
item.inputBarAccessoryView?.isUserInteractionEnabled = !self.isSendingPhoto
}
}
}
}
ViewDidLoad
messagesCollectionView.messagesDataSource = self
messagesCollectionView.messagesLayoutDelegate = self
messageInputBar.delegate = self as? InputBarAccessoryViewDelegate
messagesCollectionView.messagesDisplayDelegate = self
title = "MaybeDrinks"
// 1
let cameraItem = InputBarButtonItem(type: .system)
cameraItem.tintColor = .primary
cameraItem.image = #imageLiteral(resourceName: "camera")
// 2
cameraItem.addTarget(
self,
action: #selector(cameraButtonPressed),
for: .primaryActionTriggered
)
cameraItem.setSize(CGSize(width: 60, height: 30), animated: false)
messageInputBar.leftStackView.alignment = .center
messageInputBar.setLeftStackViewWidthConstant(to: 50, animated: false)
messageInputBar.setStackViewItems([cameraItem], forStack: .left, animated: false) // 3
}
private func sendPhoto(_ image: UIImage) {
isSendingPhoto = true
uploadImage(image) { [weak self] url in
guard let `self` = self else {
return
}
self.isSendingPhoto = false
guard let url = url else {
return
}
var message = Message(messageuser: self.sender, image: image)
message.downloadURL = url
self.save(message)
self.messagesCollectionView.scrollToBottom()
}
}
func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion: nil)
// 1
if let asset = info[.phAsset] as? PHAsset {
let size = CGSize(width: 500, height: 500)
PHImageManager.default().requestImage(
for: asset,
targetSize: size,
contentMode: .aspectFit,
options: nil) { result, info in
print("I'm in image picker")
guard let image = result else {
return
}
self.sendPhoto(image)
}
// 2
} else if let image = info[.originalImage] as? UIImage {
sendPhoto(image)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
// MARK: - Actions
#objc private func cameraButtonPressed() {
let picker = UIImagePickerController()
picker.delegate = self as? UIImagePickerControllerDelegate & UINavigationControllerDelegate
picker.allowsEditing = true
if UIImagePickerController.isSourceTypeAvailable(.camera) {
picker.sourceType = .camera
} else {
picker.sourceType = .photoLibrary
}
present(picker, animated: true, completion: nil)
}
Upload Image function
private func uploadImage(_ image: UIImage, completion: #escaping (URL?) -> Void) {
print("im in upload")
// STEP 1. Declare URL, Request and Params
let url = URL(string: "https://localhost/messagepost.php")!
// declaring reqeust with further configs
var request = URLRequest(url: url)
// POST - safest method of passing data to the server
request.httpMethod = "POST"
// values to be sent to the server under keys (e.g. ID, TYPE)
let params = ["sender_id": user_id, "uuid": uuid, "sender": me, "recipient_id": rid, "recipient": recipient, "puuid": puuid]
// body
let boundary = "Boundary-\(UUID().uuidString)"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// Compressing image and converting image to 'Data' type
guard let scaledImage = image.scaledToSafeUploadSize,
let data = scaledImage.jpegData(compressionQuality: 0.4) else {
return
}
// assigning full body to the request to be sent to the server
request.httpBody = createBodyWithParams(params, filePathKey: "file", imageDataKey: data, boundary: boundary)
print(request.httpBody as Any, "\(puuid).jpg")
URLSession.shared.dataTask(with: request) { (data, response, error) in
DispatchQueue.main.async {
// error occured
if error != nil {
Helper().showAlert(title: "Server Error", message: error!.localizedDescription, in: self)
return
}
do {
// save mode of casting any data
guard let data = data else {
Helper().showAlert(title: "Data Error", message: error!.localizedDescription, in: self)
return
}
// fetching JSON generated by the server - php file
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? NSDictionary
// save method of accessing json constant
guard let parsedJSON = json else {
return
}
// uploaded successfully
if parsedJSON["status"] as! String == "200" {
let newurl = parsedJSON["path"]
print("did you upload", newurl as Any)
print("did you upload", parsedJSON["message"] as Any)
self.isSendingPhoto = true
guard let url = newurl else {
return
}
//uploadImage(image)
var message = Message(messageuser: self.sender, image: image)
message.downloadURL = url as? URL
self.save(message)
self.messagesCollectionView.scrollToBottom()
} else {
// show the error message in AlertView
if parsedJSON["message"] != nil {
let message = parsedJSON["message"] as! String
Helper().showAlert(title: "Error", message: message, in: self)
print("where am i", parsedJSON["message"] as Any)
}
}
} catch {
Helper().showAlert(title: "JSON Error", message: error.localizedDescription, in: self)
print("where am i 2")
}
}
}.resume()
let imageName = [UUID().uuidString, String(Date().timeIntervalSince1970)].joined()
}
private func save(_ message: Message) {
self.messagesCollectionView.scrollToBottom()
}
Make sure your view controller declares conformance to both UIImagePickerControllerDelegate and UINavigationControllerDelegate in either the class declaration:
class DirectMessageViewController: MessagesViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
[...]
}
or in one or more extensions:
extension DirectMessageViewController: UIImagePickerControllerDelegate {
[...]
}
extension DirectMessageViewController: UINavigationControllerDelegate {
[...]
}

Upload image to Firebase Storage and show as Profile Image

I need help with uploading image to Firebase Storage. I have a profile menu in my app. When user tap on this menu he/she can see profile with their info and Profile Image. So I made it so you can select a photo from the gallery. But I need to save photo to Firebase Storage and add ref to Firebase Database by uid.
In addition, the user may not have a photo, so it will be nill because nothing in Database. Look at photo and you will understand everything
extension ProfileViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
var selectedImage: UIImage?
if let editedImage = info[.editedImage] as? UIImage {
selectedImage = editedImage
self.profileImage.image = selectedImage!
self.savedImage = selectedImage
picker.dismiss(animated: true, completion: nil)
} else if let originalImage = info[.originalImage] as? UIImage {
selectedImage = originalImage
self.profileImage.image = selectedImage!
self.savedImage = selectedImage
picker.dismiss(animated: true, completion: nil)
}
}
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView) )
profileImage.addGestureRecognizer(tapGesture)
profileImage.isUserInteractionEnabled = true
#objc func handleSelectProfileImageView () {
print("Tapped")
let pickerController = UIImagePickerController()
pickerController.delegate = self
present(pickerController, animated: true, completion: nil)
}
So, how to upload and dowload image.
If the user does not have a photo (ref in Database). He will see image from assets.
If the user have photo he will see image from FB.
image
For Uploading to Firebase storage
let imgData: NSData = NSData(data: UIImageJPEGRepresentation((self.img_Photo?.image)!, 0.5)!)
let _:NSData = NSData(data:UIImagePNGRepresentation(((self.img_Photo?.image)!))!)
self.uploadProfileImageToFirebase(data: imgData)
Function for uploading
func uploadProfileImageToFirebase(data:NSData){
let randomPic = randomString(length: 10)
let storageRef = Storage.storage().reference().child("Pictures").child("\(value(forKey: "UserUID") ?? randomPic).jpg")
if data != nil {
storageRef.putData(data as Data, metadata: nil, completion: { (metadata, error) in
if(error != nil){
print(error)
return
}
guard let userID = Auth.auth().currentUser?.uid else {
return
}
// Fetch the download URL
storageRef.downloadURL { url, error in
if let error = error {
// Handle any errors
if(error != nil){
print(error)
return
}
} else {
// Get the download URL for 'images/stars.jpg'
let urlStr:String = (url?.absoluteString) ?? ""
let values = ["photo_url": urlStr]
self.registerUserIntoDatabaseWithUID(uid: userID, values: values as [String : AnyObject])
}
}
})
}
}
func registerUserIntoDatabaseWithUID(uid:String, values:[String:AnyObject]){
let ref = Database.database().reference(fromURL: "https://domain.firebaseio.com/")
let usersReference = ref.child("users").child((Auth.auth().currentUser?.uid)!)
usersReference.updateChildValues(values) { (error, ref) in
if(error != nil){
print(error)
return
}
self.parentVC?.dismiss(animated: true, completion: nil)
}
}

UIImagePickerView gives portion of image blank while selecting image in editing mode

I am using UIImagePickerView to allow user to select profile image. After selecting image from UIImagePickerView user select portion of image (Square selection box which comes in editing mode) when user choose that image I am uploading it to a server and also storing it to a local machine part of the image comes as a black when I open that image on server as well as on device.
This is how image looks after uploading.
Following code I am using.
func launchImagePicker(){
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.allowsEditing = true
imagePicker.navigationBar.isTranslucent = false
imagePicker.navigationBar.barTintColor = UIColor(named:"navigationColor")
imagePicker.navigationBar.tintColor = .white
present(imagePicker, animated: true, completion: {
self.closeSharedWindow()
})
}
following will get call when we cancel picker
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
Here we are getting image from picker and uploading it.
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
selectedImageFromPicker = editedImage
}
else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker{
profileImageView.image = selectedImage
self.uploadImageToServer(image: selectedImage , userId: (self.user?.userId)!) {
self.dismiss(animated: true, completion: nil)
}
}
}
following function will upload image to server
func uploadImageToServer(image: UIImage,userId: String,completion: #escaping () -> ()){
//,completion: #escaping ([String:Any])->Void
let imgData = UIImageJPEGRepresentation(image, 0.5)!
let parameters = ["userId": userId]
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "profileImage",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key)
}
},
to:APPURL.updateProfileImage)
{ (result) in
switch result {
case .success(let upload, _, _):
upload.uploadProgress(closure: { (progress) in
print("Upload Progress: \(progress.fractionCompleted)")
})
upload.responseJSON { response in
self.storeProfileImageDetail(image: image)
guard let profileImage = UIImageJPEGRepresentation(image,0.9) else {
print("Error in JPG Representation Image")
return
}
//save image on local
self.saveImageToDisk(image: profileImage)
completion()
}
case .failure(_):
self.view.makeToast("Failed to upload profile image.")
completion()
}
}
}
I am unable to understand what could be wrong any one have idea about this?

Uploading an image into a Web Service from an ImageView

I'm trying to upload an image taken by the device camera, or selected from the device Gallery, later present it at the screen with an ImageView, and at last upload it to a Rest API. I already have a default image stored in the Rest API and my App is already loading this image, but when I try to change the image I have issues.
This is my code after the Post API call, the data of my JSON:
let defaultServiceResponse = data["defaultServiceResponse"] as! NSDictionary
self.idResponse = defaultServiceResponse["idResponse"] as! Int
let loginModel = LoginModel()
if self.idResponse == 0 {
let userInfo = data["userInfo"] as! NSDictionary
loginModel.imageProfileUrl = userInfo["imageProfileUrl"] as! String
let url = URL(string: loginModel.imageProfileUrl)
let data = try? Data(contentsOf: url!)
self.userImage.image = UIImage(data: data!)!
Then I have a second class where I'm trying to upload the image:
class PhotoViewController: UIViewController, UIImagePickerControllerDelegate,
UINavigationControllerDelegate {
#IBOutlet weak var imagePicked: UIImageView!
#IBAction func openCameraButton(sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(.camera) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .camera;
imagePicker.allowsEditing = false
self.present(imagePicker, animated: true, completion: nil)
}
}
#IBAction func openPhotoLibraryButton(sender: AnyObject) {
if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.delegate = self
imagePicker.sourceType = .photoLibrary;
imagePicker.allowsEditing = true
self.present(imagePicker, animated: true, completion: nil)
}
}
private func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
let image = info[UIImagePickerControllerOriginalImage] as! UIImage
imagePicked.image = image
dismiss(animated:true, completion: nil)
}
#IBAction func saveButt(sender: AnyObject) {
let imageData = UIImageJPEGRepresentation(imagePicked.image!, 0.6)
let compressedJPGImage = UIImage(data: imageData!)
UIImageWriteToSavedPhotosAlbum(compressedJPGImage!, nil, nil, nil)
let alert = UIAlertView(title: "Wow",
message: "Your image has been saved to Photo Library!",
delegate: nil,
cancelButtonTitle: "Ok")
alert.show()
}
When I tap the openCamara button and openLibrary button it does the correct function each time, but when I choose the photo (either from the Camera or the Gallery) it doesn't appear anything at the ImageView, and the error I receive is: "Creating an image format with an unknown type is an error
"
And I'm not sending back the image into the Rest API because I haven't any idea of how can I do that.
Can somebody help me showing where is the error that is not letting me show the picture at the screen on the ImageView?
And if it's posible can somebody show me the best way to return that image into my Rest API?
#Zita Noriega Estrada
this code will remove your all errors.
func isValidData(_ result: Result<Any>, completion: #escaping (_ : NSDictionary?, _ : Bool?, _ : NSError?) -> Void) {
self.getValidDict(result, completion: {(dict, error) in
var success = false
var errorNew = error
if dict != nil {
success = ((dict?["dataKey"] as AnyObject).boolValue)!
if !success {
errorNew = NSError(domain: "", code: 400, userInfo: [NSLocalizedDescriptionKey: dict?.value(forKey: "messageKey")! as Any])
}
}
completion (dict, success, errorNew)
})
}
func getValidDict(_ result: Result<Any>, completion: #escaping (_ : NSDictionary?, _ : NSError?) -> Void) {
var dict: NSDictionary!
let errorNew = result.error as NSError?
if let json = result.value {
dict = (json as AnyObject).value(forKey: "responseKey") as! NSDictionary
}
completion (dict, errorNew)
}
Use Alamofire to upload image to server.
Try this code:
func uploadImage {
uploadImage(image: image, completion: { (success, error) in
if success! {
} else {
}
})
}
func uploadImage(_ image: UIImage!, completion: #escaping (_ : Bool?, _: NSError?) -> Void) {
let parameters: Parameters = ["image": image]
Alamofire.upload(multipartFormData: {
multipartFormData in
// For Image
for (key, value) in parameters {
if value != nil {
if let imageData = UIImageJPEGRepresentation(value!, 0.5) {
multipartFormData.append(imageData, withName: key, fileName: "file.png", mimeType: "image/png")
}
}
}
}, to: "apiName", method: .post, encodingCompletion: {
encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response {
[weak self] response in
guard self != nil
else {
return
}
upload.responseJSON(completionHandler: { response in
self?.isValidData(response.result, completion: {(dict, success, error) in
completion (success, error)
})
})
}
case .failure(let encodingError):
print("error:\(encodingError)")
completion (false, encodingError as NSError?)
}
})
}