how to store the JSON format to database through api using Alamofire in swift4 - swift4

{
"Employee_ID" : "160",
"Date" : "10-06-2019",
"Time" : [
{
"In" : "10:30",
"In_Location": "506/507, 1st Main RoadMurugeshpalya, Bengaluru",
"Out" : "18:30",
"Out_Location": "506/507, 1st Main RoadMurugeshpalya, Bengaluru",
"Description" : "Designing Login Page",
"Total" : "240"
}
]
}
my actual code is:
Alamofire.upload( multipartFormData: { multipartFormData in
multipartFormData.append("160".data(using: .utf8)!, withName: "Employee_ID")
multipartFormData.append(dateString.data(using: .utf8)!, withName: "Date")
multipartFormData.append(InTime.data(using: .utf8)!, withName: "In")
multipartFormData.append(self.locationName.data(using: .utf8)!, withName: "In_Location")
// for (key, value) in timeParams {
// multipartFormData.append(value.data(using: .utf8)!, withName: key)
// }
}, to: "http://touramical-test.infanion.com:5000/api/save-tempion/", method: .post, headers: nil) { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.response { answer in
print(answer.response?.statusCode as Any)
}
upload.uploadProgress { progress in
//call progress callback here if you need it
}
case .failure(let encodingError):
print("multipart upload encodingError: \(encodingError)")
}
}
it uploads only employee Id and date but not time parameters

First, try to transform your data in a struct like this:
struct Employer: Codable {
var employeeID, date: String
var time: [Time]
enum CodingKeys: String, CodingKey {
case employeeID = "Employee_ID"
case date = "Date"
case time = "Time"
}
}
struct Time: Codable {
var timeIn, inLocation, out, outLocation: String
var timeDescription, total: String
enum CodingKeys: String, CodingKey {
case timeIn = "In"
case inLocation = "In_Location"
case out = "Out"
case outLocation = "Out_Location"
case timeDescription = "Description"
case total = "Total"
}
}
And later try to do something like this:
let jsonEncoder = JSONEncoder()
var jsonData = try? jsonEncoder.encode(yourTimeStruct) as? [String: Any]
Alamofire.request(yourURL, method: .post, parameters: jsonData, encoding: JSONEncoding.default, headers: nil).responseJSON {
response in
switch response.result {
case .success:
print(response)
break
case .failure(let error):
print(error)
}
}

Related

How to send an array of json as value for multipart/form-data content type?

Guys I need to send parameters described in the image value where content type is multipart/form-data. Im having difficulty in sending only package_json parameter.
The problem is I don't know how do I send multiple package_json values as parameter? I can send one value like this:
let param = [
"outletId : "1",
"vehicleId" : "1",
"instructions" : tvInstructions.text,
"package_json" : "[{\"packageId\":\"1\"}]",
"addressId" : "1"
]
Above i'm able to send package_json = [{"packageId": 1}] as String as my function below sends parameters as [String : String] and images of Data type as [String : Any]. Im having problem sending multiple values in package_json. For eg. something like this: [{"packageId": 1}, {"packageId": 2}, {"packageId": 3}] and so on. Here's the function that i'm using to send parameters:
func postrequest(_ request: String, onPath imagesData:[Data]?,_ imageName : String, andParameter parameters: [String:String]?, withCompletion response: #escaping serviceCompletion) {
let headers: HTTPHeaders
headers = ["Content-type": "multipart/form-data"]
AF.upload(multipartFormData: { multiPart in
if let allParams = parameters {
for (key, value) in allParams {
multiPart.append(value.data(using: .utf8)!, withName: key)
}
}
for imageData in imagesData ?? [] {
multiPart.append(imageData, withName: "\(imageName)", fileName: "file.jpg", mimeType: "image/jpg")
}
}, to: request, usingThreshold: UInt64.init(),
method: .post,
headers: headers).response { (res) in
if((res.error == nil)){
do {
response(res.data,res.error)
}
}
else{
// hideHud()
response(res.data,res.error)
}
}
}
I tried to convert function to send [String: Any] data but found out we can only send as [String : String] along with images as [String : Any].
I just want to know if there is any way to modify "package_json" : "[{\"packageId\":\"1\"}]" so I can send [{"packageId": 1}, {"packageId": 2}, {"packageId": 3}]?
Just in case, this is how im calling above function and sending parameters:
func sendData() {
let param = [
"outletId" : "1",
"vehicleId" : "1",
"instructions" : tvInstructions.text,
"package_json" : "[{\"packageId\":\"1\"}]",
"addressId" : "1"
]
ApiNetworkManager.shared.postrequest(Api.completeUrl, onPath: [], "", andParameter: param) { (response, err) in
ApiNetworkManager.shared.hideHud()
debugPrint(param)
let json = JSON.init(response!)
debugPrint(json)
if err == nil {
if err == nil && response != nil {
if json.dictionaryValue["success"]?.stringValue == "1" {
//Add your code here
}
else{
let message = json.dictionaryValue["message"]?.stringValue
self.showAlert(Message: message ?? "Error")
}
} else {
// hideHud()
print(err?.localizedDescription as Any)
let message = json.dictionaryValue["message"]?.stringValue
self.showAlert(Message: message ?? "Error")
}
}
else{
ApiNetworkManager.shared.hideHud()
let message = err?.localizedDescription
self.showAlert(Message: message ?? "Error")
}
}
}

Uploading multiple images(with parameters) using multipart form data - Alamofire 5

I have been trying to upload multiple images(3) with parameters using alamofire but i cant seem to do it.(My lack of knowledge). Could someone kindly help me out with this?
This is what i have tried
{
let headers: HTTPHeaders = [
xyz
]
let param : [String: Any] = [
"emp_Id" : "",
"device_Identifier" : "",
"timestamp" : "",
"description" : "",
"handoverStatus" : ""
]
AF.upload(
multipartFormData: { multipartFormData in
multipartFormData.append(imgData0, withName: "media1" , fileName: "file0.jpeg", mimeType: "image/jpeg")
multipartFormData.append(imgData1, withName: "media2",fileName: "file1.jpg", mimeType: "image/jpg")
multipartFormData.append(imgData2, withName: "media3",fileName: "file1.jpg", mimeType: "image/jpg")
// I think im supposed to add the last part here but i dunno how to do that
},
to: "http://ip.here.--.--/new.php", method: .post , headers: headers)
.response { resp in
print(resp)
}
}
This is what the server expects
[{"key":"media1","description":"","type":"file","value":["/C:/Users/x/x/Saved Pictures/x.jpg"]},
[{"key":"media2","description":"","type":"file","value":["/C:/Users/x/x/Saved Pictures/x.jpg"]},
[{"key":"media3","description":"","type":"file","value":["/C:/Users/x/x/x.jpg"]},
{"key":"model","value":"{\"emp_Id\": \"6\",\"device_Identifier\":\"Device 01\",\"timestamp\":\"\123\,
”\description\”:\”description\",”handoverStatus”:”false”}","type":"text"}]
I dunno how to add the last part to the multipart form data, could some point me in the right direction ?
Thanks
Try this method to upload multiple images
class func uploadImageWithURL(endPath : String, dictImage : [String:[UIImage]], parameter : [String : Any], header : HTTPHeaders? = nil, success : #escaping ( Any? )->Void, failure : #escaping (Error) -> Void){
let baseUrl = "your base URL"
let fullUrl = baseUrl + endPath
var headers = ["Content-type" : "multipart/form-data"]
if let header = header{
headers = header
}
let url = (try? URLRequest(url: fullUrl, method: .post, headers: headers))!
upload(multipartFormData: { (multipartData) in
for imagesData in dictImage {
for arrimage in imagesData.value{
multipartData.append(arrimage.jpegData(compressionQuality: 0.50)!, withName: imagesData.key, fileName: "\(Date().timeIntervalSince1970).jpg", mimeType: "image/jpeg")
}
}
for (key, value) in parameter {
multipartData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
}, with: url) { (resultData) in
switch resultData{
case .success(let upload, let streamingFromDisk, let fileURL):
print("File URL : \(String(describing: fileURL))")
print("Streaming From Disk : \(streamingFromDisk)")
upload.uploadProgress(closure: { (progress) in
print("Progress : \(progress.fractionCompleted)")
})
upload.responseJSON(queue: nil, options: .allowFragments, completionHandler: { (response) in
if let value = response.result.value
{
success(value)
}
})
case .failure(let error):
failure(error)
print(error)
}
}
}

Alamofire sending parameter array with key and multiple value

I need to do this in my project:
multiple values in multiple array common key for parameter
Some links that have the same question but no exact answers, I always see posts that have answers like use a custom encoding and that's it.
https://github.com/Alamofire/Alamofire/issues/570
i have 4 array :
var imagesArray: [UIImage] = [], var DayOpreation: [String] = [],varDayOffStart: [String] = [], var DayOffEnd: [String] = []
and this my code :
let parameters : Parameters = [
"about": self.descriptionLabel.text!,
"address" : addressLabel.text!,
"country" : "1",
"state": "1",
"city" : "1",
"postcode" : self.postalCode.text!,
"policies": self.policiesLabel.text,
"longitude" : "",
"latitude" : "",
"available_24hours": "0",
"open_hour" : "09:00",
"closed_hour" : "18:00",
"operating_days[0]": "Senin",
"days_off[0][start]" : "2019-10-10",
"days_off[0][end]" : "2019-10-15",
]
let token = UserDefaults.standard.string(forKey: UserDefaultConstant.ACCESS_TOKEN)
let headers = ["key": "\(token!)"
]
let ImageData = UIImageView()
ImageData.image = UIImage(named: "rectangle-1")
let imgData = UIImagePNGRepresentation(ImageData.image!)!
Alamofire.upload(multipartFormData: { multipartFormData in
multipartFormData.append(imgData, withName: "photo_profile[0]",fileName: "file.jpg", mimeType: "image/jpg")
for (key, value) in parameters {
multipartFormData.append((value as AnyObject).data(using: String.Encoding.utf8.rawValue)!, withName: key)
}
},
to:"\(Endpoints.BASE)\(Endpoints.UPDATE_VENDOR)",
method: .post,
headers: headers,
encodingCompletion: { encodingResult in
switch encodingResult {
case .success(let upload, _, _):
upload.responseJSON { response in
if let data = response.data {
guard let json = try? JSON(data: data) else { return }
let messageRoom = json["message"].string
print("listOfficialRoom== ",json)
}
}
case .failure(let encodingError):
print(encodingError)
}
})
Use Paramaters in Alamofire, something like this
let daysOff = [String: Any]() // array of dictionaries for days off
for (i, day) in days.enumerated() {
let dayOff: Parameters = [
"start": day.start,
"end": day.end
]
daysOff["\(i)"] = dayOff
}
let parameters: Parameters = [
"open_hour": "...",
"closed_hour": "...",
"days_off": daysOff
]

how to store the response of a service in a model with alamofire

I am learning to programme in swift, I developed with android previously the consumption of services and stored them in a model with the help of retrofit and serializable. Now in swift, I use the Alamofire 4.0 and SwiftyJson to consume a service and the problem is how to save all the response JSON in a model and then use this data, I have reviewed several examples but I still do not understand how to do it.
Could you tell me how to do it or what I need to add to complete this action to get the information and then use it
so I consume the service
static func loginService(email : String, password : String, completionHandler : #escaping (LoginResponse) -> Void){
let parameters : Parameters = ["email": email, "password": password]
Alamofire.request(AlamofireConstants.LOGIN, method: .post, parameters: parameters, encoding: URLEncoding.default).validate(statusCode: 200..<300).responseData { response in
switch response.result {
case .failure(let error):
print("error ==> \(error)")
case .success(let data):
do{
let result = try JSONDecoder().decode(LoginResponse.self, from: data)
print(result)
} catch {
print(error)
}
}
}
}
this is my model
struct LoginResponse : Decodable {
let user : User?
let status: Int
let success: Bool
let message: String
}
struct User : Decodable {
let id: Int
let firstName, lastName, surName, email: String
let emailToken: String?
let validate: String
let token, nationality, documentType, documentNumber: String?
let legalName, legalNumber, birthdate: String?
let gender: String
let phoneMovil, phoneFix, icon: String?
let wishOffers, acceptTerms, isCustomer: Int
let active: Bool
let createdAt, updatedAt: String
}
and this is the json from response
{
"user": {
"id": 183,
"first_name": "teste",
"last_name": "testet",
"sur_name": "este",
"email": "adeveloper964#gmail.com",
"email_token": null,
"validate": "S",
"token": null,
"nationality": null,
"document_type": null,
"document_number": null,
"legal_name": null,
"legal_number": null,
"birthdate": null,
"gender": "O",
"phone_movil": null,
"phone_fix": null,
"icon": null,
"wish_offers": 0,
"accept_terms": 1,
"is_customer": 0,
"active": true,
"created_at": "2019-05-13 17:04:50",
"updated_at": "2019-05-14 10:19:31"
},
"status": 0,
"success": true,
"message": ""
}
I get this error
keyNotFound(CodingKeys(stringValue: "firstName", intValue: nil), Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "user", intValue: nil)], debugDescription: "No value associated with key CodingKeys(stringValue: \"firstName\", intValue: nil) (\"firstName\").", underlyingError: nil))
Why SwiftyJSON? You don't need that. To parse JSON into a model Decodable is much easier to use and it's built-in (no dependencies).
struct LoginResponse : Decodable {
let user: User
let status: Int
let success : Bool
let message : String
}
struct User : Decodable {
let id : Int
let firstName, lastName, surName, email : String
}
static func loginService(user : String, password : String){
Alamofire.request(AlamofireConstants.BASE_URL_TEST + "/api/loginuser", method: .post, parameters: ["email":user,"password":password], encoding: URLEncoding.default)
.validate(statusCode: 200..<300)
.responseData { response in // note the change to responseData
switch response.result {
case .failure(let error):
print(error)
case .success(let data):
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(LoginResponse.self, from: data)
print(result)
} catch { print(error) }
}
}
}
import SwiftyJSON in the class where you wrote loginService API and under success case write:
case .success(let value):
let json = JSON(value)
let loginModel = LoginResponse(json: json)
print("Login Model is: \(loginModel)")
and see if it works

Alamofire.upload SwiftLint violation

The code for uploading image with Alamofire triggers a SwiftLint violation. How can it be fixed?
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData, withName: "profileImage", fileName: "image.png", mimeType: "image/jpg")
}, usingThreshold: UInt64.init(), to: requestURL, method: .post, headers: headers) { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
if let error = response.error {
completionBlock(.failure(error as NSError))
return
}
completionBlock(.success(response))
}
case .failure(let error):
completionBlock(.failure(error as NSError))
}
}
Multiple Closures with Trailing Closure Violation: Trailing closure
syntax should not be used when passing more than one closure argument.
(multiple_closures_with_trailing_closure)
The error is telling you not to use trailing closure syntax when there is more than one closure parameter.
Alamofire.upload(multipartFormData: { (multipartFormData) in
multipartFormData.append(imageData, withName: "profileImage", fileName: "image.png", mimeType: "image/jpg")
}, usingThreshold: UInt64.init(), to: requestURL, method: .post, headers: headers, encodingCompletion: { (result) in
switch result {
case .success(let upload, _, _):
upload.responseJSON { response in
if let error = response.error {
completionBlock(.failure(error as NSError))
return
}
completionBlock(.success(response))
}
case .failure(let error):
completionBlock(.failure(error as NSError))
}
})