Alamofire sending parameter array with key and multiple value - swift

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
]

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")
}
}
}

Can I request a two-dimensional associative array in swift Moya?

The following two forms of data were successfully requested.
{
"ride_fare": 1000,
"km": 7
]
}
{
"ride_fare": 1000,
"km": 7,
"options": [ 0, 1, 2]
}
However, I don't know how to request a two-dimensional associative array like the one below.
How can I request it?
{
"ride_fare": 1000,
"km": 7,
"option_fares": [
{
"price": 200,
"name": "立ち寄り",
"id": 1
}
]
}
The code that I wrote:
var options = [Any]()
for option in optionFares {
let params = [
"id" : option.id ?? 0,
"name" : option.name ?? "",
"price" : option.price ?? 0
] as [String : Any]
options.append(params)
}
let faresData = [
"id" : driverOrder.id ?? 0,
"km" : driverOrder.distance ?? 0,
"option_fares" : options,
"ride_fare" : driverOrder.ride_fare ?? 0
] as [String : Any]
First, create a struct that matches the json format you want to request.
struct Params: Codable {
let rideFare, km: Int
let optionFares: [OptionFare]
enum CodingKeys: String, CodingKey {
case rideFare = "ride_fare"
case km
case optionFares = "option_fares"
}
}
struct OptionFare: Codable {
let price: Int
let name: String
let id: Int
}
And you must create a request parameter in Moya's task.
import Moya
extension APITarget: TargetType {
var task: Task {
case .yourCaseName(let price, let name, let id, let rideFare, let km):
let encoder: JSONEncoder = JSONEncoder()
let optionFareData: [OptionFare] = []
optionFareData.append(OptionFare(price, name, id))
let paramsData = Params(rideFare, km, optionFareData)
let jsonData: Data = try! encoder.encode(paramsData)
return .requestData(jsonData)
}
}
}

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)
}
}
}

Send JSON array as a parameter Alamofire

I'm having difficulty with a parameter which contains a Json array using Alamofire
Here is a string of my Json:
"[{\"id\":546836102,\"count\":1},{\"id\":216479424,\"count\":1}]"
Here is my code where I make the request:
let data = (params["cart"] as! String).data(using: .utf8)!
do {
if let jsonArray = try JSONSerialization.jsonObject(with: data, options : .fragmentsAllowed) as? [Dictionary<String, Int>] {
let parameters: Parameters = [
"address_id": params["address_id"] as! Int,
"delivery_day": params["delivery_day"] as! String,
"delivery_hour": params["delivery_hour"] as! Int,
"cart": jsonArray,
"via": params["via"] as! String
]
Alamofire.request(Global.baseURL + "orders/finish", method: .post, parameters: parameters, encoding: URLEncoding.default, headers: header)
.responseSwiftyJSON {
Printing out my parameters
["cart": [["id": 546836102, "count": 1], ["count": 1, "id": 216479424]], "address_id": 641589205, "delivery_day": "1399-01-20", "delivery_hour": 21, "via": "ios"]
Backend must receive the cart as below:
[
{
"id": 123456,
"count": 2
},
{
"id": 654321,
"count": 3
}
]
But instead it gets the data like this:
{
"delivery_hour" : "21",
"delivery_day" : "1399-01-20",
"cart" : [
{
"count" : "1"
},
{
"id" : "546836102"
},
{
"count" : "1"
},
{
"id" : "216479424"
}
],
"via" : "ios",
"address_id" : "641589205"
}
I have tried JSONEncoding and URLEncoding options by Alamofire but nothing seems to work and this is the closest I've gotten to the API template so far.
What am I doing so wrong here?
// MARK: - Update
So I updated to the latest version of Alamofire and still no good results :(
Here is the code:
let payload = MyParameters(address_id: 641589205, delivery_day: "1399-01-21", delivery_hour: 21, cart: items, via: "ios")
AF.request(url, method: .post, parameters: payload, encoder: JSONParameterEncoder.default, headers: .init(header), interceptor: nil).response { dataResponse in
switch dataResponse.result {
case .success(let value):
if dataResponse.response?.statusCode == 200 {
let json = JSON(value!)
completionHandler(json, nil)
} else {
print(dataResponse.response?.statusCode ?? -1)
}
case .failure(let error):
print(error)
completionHandler(nil, error.localizedDescription)
}
}
My payload looks exactly what I want it to be
{
"cart" : [
{
"count" : 1,
"id" : 546836102
},
{
"count" : 1,
"id" : 216479424
}
],
"via" : "ios",
"address_id" : 641589205,
"delivery_day" : "1399-01-21",
"delivery_hour" : 21
}
But then again the endpoint receives this:
{
"{\"delivery_day\":\"1399-01-21\",\"address_id\":641589205,\"delivery_hour\":21,\"cart\":" : {
"{\"id\":546836102,\"count\":1},{\"id\":216479424,\"count\":1}" : null
}
}
Using Alamofire 4, you can't send arrays using the method you've shown, as the Parameters type is [String: Any]. You're also not using the correct ParameterEncoding. If you want to send a JSON body, you need to use the JSONEncoding. What you can do is manually serialize the array into a URLRequest and make that request using Alamofire.
Additionally, if you update to Alamofire 5, Encodable parameters are now supported, so you if you can define your parameters as an Encodable type, sending them would be as easy as passing an array.
AF.request(..., parameters: [some, encodable, values], encoder: JSONEncoder.default)...

how to store the JSON format to database through api using Alamofire in 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)
}
}