Pass array of string in parameter request - swift 5 - arrays

Pass array of string in parameter request - swift 5. I want to send an array in a parameter from an alamofire request.
This is the request on Postman:
This is my solution:
var Token : String?
var tasksMO = [NSManagedObject]()
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "ConfirmActivationEntity")
do {
let results = try pe.context.fetch(request)
tasksMO = results as! [NSManagedObject]
for taskmo in tasksMO {
Token = (taskmo.value(forKey: "access_token") as! String )
}
print("assbil")
} catch {
print("fild")
}
print(" Token :\(Token!)")
let levels : [String] = ["+972569431827","+972598110437","+972592923343","3555656","00970567163651","258258"]
let paramsJSON = JSON(levels)
debugPrint(paramsJSON)
let parameters : [String : Any] = ["contacts":paramsJSON,"platform":2]
let headers : HTTPHeaders = ["Authorization":"Bearer \(Token!)","Accept-Language" : Locale.current.languageCode ?? "ar", "Content-Type" : "application/x-www-form-urlencoded","Accept" : "application/json"]
guard let url = URL(string: "\(UrlApi.url)\(UrlApi.contactsPost)") else { return }
sdLoader.startAnimating(atView: self.view)
Alamofire.request(url, method: .post, parameters: parameters, headers: headers).responseJSON { response in
if let error = response.error {
print(error)
return
}
if let status = response.response?.statusCode {
print(status)
print(response.result.value!)
switch(status){
case 200:
self.sdLoader.stopAnimation()
do{
let decoder = JSONDecoder()
let userResultDec = try decoder.decode(ContactsJSON.self, from: response.data!)
decoder.keyDecodingStrategy = .convertFromSnakeCase
if userResultDec.status == true {
print(userResultDec.items)
} else if userResultDec.status == false {
self.showAlert(title: "رسالة", message: "هناك خطا بالمعلومات المدخلة", style: .alert)
}
} catch let parsingError {
print("Error", parsingError)
MessageBox.Show(Message: " \(parsingError) , خطأ في السيرفير ", MyVC: self)
}
case 401 :
self.sdLoader.stopAnimation()
print("error with response status: \(status)")
print("خطأ في السيرفير")
MessageBox.Show(Message: "error with response status: \(status) , خطأ في السيرفير ", MyVC: self)
case 404 :
self.sdLoader.stopAnimation()
print("error with response status: \(status)")
print("خطأ في السيرفير")
MessageBox.Show(Message: "error with response status: \(status) , خطأ في السيرفير ", MyVC: self)
case 500:
MessageBox.Show(Message: "error with response status: \(status) , خطأ في السيرفير ", MyVC: self)
default:
print("Error")
}
}
}
The problem is:
The items in the array do not appear in the reference response from the server
I am using the Alamofire pod and the SwiftyJson pod with iOS 13, Swift 5, and Xcode 11.

Something is wrong with application/x-www-form-urlencoded conversations in Alamofire/Swift. It does work in Postman way. Postman automatically converts your array but swift does not.
struct ArrayEncoding: ParameterEncoding {
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
var request = try URLEncoding().encode(urlRequest, with: parameters)
request.url = URL(string: request.url!.absoluteString.replacingOccurrences(of: "%5B%5D=", with: "="))
return request
}
}

Please try this example :
var apiRequest = URLRequest(url: url)
apiRequest.httpMethod = "POST"
apiRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
let levels = ["+972569431827","+972598110437","+972592923343","3555656","00970567163651","258258"]
apiRequest.httpBody = try! JSONSerialization.data(withJSONObject: values)
Alamofire.request(apiRequest)
.responseJSON { response in
switch response.result {
case .failure(let error):
print(error)
if let data = response.data, let responseStr = String(data: data, encoding: .utf8) {
print(responseStr)
}
case .success(let responseValue):
print(responseValue)
}
}

This is how I make the request post by sending an array: (Alamofire v5)
let apiInputs = [
"input1": "example1",
"input2": "example2",
"input3": "example3",
"inputN": "exampleN",
]
AF.upload(multipartFormData: { multipartFormData in
for (key, value) in apiInputs {
multipartFormData.append(value.data(using: String.Encoding.utf8)!, withName: key) } // End for multipart form data.
}, to: "https://example.com/api")
.responseJSON { response in
debugPrint(response)
}
I leave you the official documentation:
Alamofire/MultipartFormData

Related

Get an [String] link from a json file

Here is my structure for the json file
struct DataRespons: Codable {
let data: [String]
let status: String
}
JSON file url
{
"status": "success",
"data": [
"f7c75c1f-10ab-4298-9dc9-e80b7bd07dfd",
"6f5f6eeb-191d-4ad9-b5ef-6f61fd5fcefc",
"8008800880088008",
"64a3f5d0-37c7-4c30-8d0f-3b67fb5c8fde"
]
}
This is my class for JSON requests and decoding
I use these functions to get an array of links
I hope I wrote correctly what I want to receive, and if there are any questions, please contact me
#MainActor
class NetworkModel: ObservableObject {
#Published var listId: [String] = []
var statusList = ""
var statusUser = ""
#Published var userData = UserRespons(status: "??", data: UserData(id: "???", firstName: "???", lastName: "??", age: 4, gender: "???", country: "???"))
func getList() {
guard let url = URL(string: "some URL") else { fatalError("Missing URL") }
var request = URLRequest(url: url)
request.addValue("bearer \(token)", forHTTPHeaderField: "Authorization")
let dataTask = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Requst error",error)
return
}
guard let response = response as? HTTPURLResponse else { return }
if response.statusCode == 200 {
guard let data = data else { return }
DispatchQueue.main.async {
do {
let decoded = try JSONDecoder().decode(DataRespons.self, from: data)
self.listId = decoded.data
self.statusList = decoded.status
} catch let error{
print("Error decode",error)
}
}
}
}
dataTask.resume()
}
I can't through index [String] to get each element
use this code to access the data elements of an array:
// ....
self.listId = decoded.data
for i in listId.indices {
print("--> listId[\(i)] = \(listId[i]) ")
}
print("--> listId[0] = \(listId[0]) ")
print("--> listId[1] = \(listId[1]) ")
// ....
Read the very basics of Swift, specially regarding arrays here:
https://docs.swift.org/swift-book/LanguageGuide/CollectionTypes.html

how convert JSON response to Array in swift?

func llamadaApiDos(postData: (Data),empresa: String,boundary: String) -> [String] {
var request = URLRequest(url: URL(string: "https://www.something.com")!,timeoutInterval: Double.infinity)
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
var success = false
var serviceResponse = [""]
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if let error = error {
print("Error while trying to re-authenticate the user: \(error)")
} else if let response = response as? HTTPURLResponse,
300..<600 ~= response.statusCode {
print("Error while trying to re-authenticate the user, statusCode: \(response.statusCode)")
} else if let data = data {
let loginDataModel = try! JSONDecoder().decode(responseLogin.self,from: data)
serviceResponse = JSONDecoder.decode(loginDataModel)
success = true
}else{
success = true
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
if success
{
return serviceResponse
}else
{
return ["Error"]
}
}
Cannot assign value of type '(T.Type, Data) throws -> T' to type '[String]'
I need to convert the JSON response into an array that can be validated in another function, but I don't know what type of data I should return, I'm sorry if it's not well understood, my English isn't very good either.
To convert the JSON response to an array in Swift, you can use the JSONSerialization class to convert the response data to a dictionary, then access the array stored in the dictionary using the key for the array.
Here's an example:
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let array = json["keyForArray"] as? [String] {
// Use the array here
}
In your code, you can use this approach to convert the JSON response to an array, then return the array from the llamadaApiDos function.
Here's how your function would look like with this change:
func llamadaApiDos(postData: (Data),empresa: String,boundary: String) -> [String] {
var request = URLRequest(url: URL(string: "https://www.something.com")!,timeoutInterval: Double.infinity)
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
var success = false
var serviceResponse = [""]
let semaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
if let error = error {
print("Error while trying to re-authenticate the user: \(error)")
} else if let response = response as? HTTPURLResponse,
300..<600 ~= response.statusCode {
print("Error while trying to re-authenticate the user, statusCode: \(response.statusCode)")
} else if let data = data {
// Convert the JSON response to an array
let json = try JSONSerialization.jsonObject(with: data, options: [])
if let array = json["keyForArray"] as? [String] {
// Use the array here
serviceResponse = array
success = true
}
}else{
success = true
}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
if success
{
return serviceResponse
}else
{
return ["Error"]
}
}

Completion Handler in API never runs

I have an APICall as below
static func getLinkToken() {
// Prepare URL
let url = URL(string: "https://sandbox.plaid.com/link/token/create")
guard let requestUrl = url else { fatalError() }
// Prepare URL Request Object
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
let prePostString : [String : Any] = [
"client_id" : clientID,
"secret" : secret,
"user" : ["client_user_id": uniqueID],
"client_name": "Plaid App",
"products": ["transactions"],
"country_codes": ["US"],
"language": "en",
"account_filters": [
"depository": [
"account_subtypes": ["checking"]
]
]
]
let postString = try? JSONSerialization.data(withJSONObject: prePostString)
// Set HTTP Request Body
request.httpBody = postString;
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// Perform HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Check for Error
if let error = error {
print("Error took place \(error)")
return
}
do {
//Parse response into a dict
let parsedData = try JSONSerialization.jsonObject(with: data!) as! [String:Any]
//Add link token to user class
User.linkToken = (parsedData["link_token"] as! String)
} catch let error as NSError {
print(error)
}
// Convert HTTP Response Data to a String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
}
For some reason this code never works if I call it unless it is in #main.init.
It appears that when I call the function in any class/method other than the initializer for main, the completion handler never runs. An example of how I call it is shown below.
class Practice {
func getAPI() {
getLinkToken()
}
}
TLDR; completion handler in API call never runs.
Thanks

Escaping closure captures mutating 'self' parameter while decode JSON Swift

I try to parse JSON with mvc pattern.I'm trying for the first time. But I'm getting "Escaping closure captures mutating 'self' parameter error " I mutated functions and put self where necessary.I can access and use required protocols in ViewController. Everything seems normal What's the problem here ?
import Foundation
protocol ItunesManagerDelegate {
func didUpdateSearchin(_ ItunesManager:ItunesManager, product: [ItunesModel])
func didFailWithError(error:Error)
}
struct ItunesManager {
let baseURL = "https://itunes.apple.com/search?term="
var delegate : ItunesManagerDelegate?
var itunesDataArray = [ItunesModel]()
mutating func getSearchResult(for terms:String){
let urlString = "\(baseURL)\(terms)"
if let url = URL(string: urlString) {
let session = URLSession(configuration: .default)
let task = session.dataTask(with: url) { (data, response, error) in
if error != nil {
self.delegate?.didFailWithError(error: error!)
return
}
if let searchResult = self.parseJSON(data!){
self.delegate?.didUpdateSearchin(ItunesManager(), product: searchResult)
}
}
task.resume()
}
}
mutating func parseJSON(_ itunesData:Data) -> [ItunesModel]? {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode([ItunesData].self, from: itunesData)
decodedData.forEach { (ItunesData) in
ItunesData.results.forEach { (SearchResults) in
let type = SearchResults.wrapperType
let name = SearchResults.collectionName
let url = SearchResults.artworkUrl100
let price = SearchResults.collectionPrice
let date = SearchResults.releaseDate
let itunesProductInfo = ItunesModel(collectionName: name, collectionPrice: price, artWorkUrl100: url, wrapperType: type, releaseDate: date)
itunesDataArray.append(itunesProductInfo)
}
}
return itunesDataArray
}catch{
delegate?.didFailWithError(error: error)
return nil
}
}
}

How to send JSON Array to POST request for Swift 3 iOS?

I am using the below post method to send JSON array, Please help to me solved below issue?
I need post json data like below ;
key = punchdata
{
"maids" : "649",
"misReason" : "test",
"uId" : "20",
"aDate" : "2020-04-24",
"punchArray" : [
{
"in_time" : "14:10:00",
"in_date" : "2020-04-24",
"out_date" : "2020-04-24",
"out_time" : "19:00:00"
}
]
}
Below I attached the postman request and response, please check ;
func sendJSONArrayToPost() {
let params2 = ["punchdata" : ["uId": "20",
"aDate":"2020-04-24",
"maids":"649",
"misReason":"test",
"punchArray": [
[
"in_date": "2020-05-07",
"in_time": "10:00:00",
"out_date": "2020-05-07",
"out_time": "13:00:00"
]]]] as [String : Any]
let url = "https://iiplccr.hrgird.com/owner/hrmessapi/applymissingPunch"
Alamofire.request(url, method: .post, parameters: params2, encoding:JSONEncoding.default, headers: nil)
.responseJSON { response in
debugPrint(response)
if let data = response.result.value{
if (data as? [String : AnyObject]) != nil{
if let dictionaryArray = data as? Dictionary<String, AnyObject?> {
if dictionaryArray.count > 0 {
var resCode = Int()
var resMessage = ""
if let success = dictionaryArray["success"] as? Int{
resCode = success
}
if let Msg = dictionaryArray["Msg"] as? String{
resMessage = Msg
}
}
}
}
}
}
}
Other Way :
let jsonDataDict: NSMutableDictionary = NSMutableDictionary()
let arrObj: NSMutableDictionary = NSMutableDictionary()
let jsonArrayDict: NSMutableArray = NSMutableArray()
jsonDataDict.setValue("\(mLoginUserId)", forKey: "uId")
jsonDataDict.setValue(dateArray[0], forKey: "aDate")
jsonDataDict.setValue(maidStr, forKey: "maids")
jsonDataDict.setValue(resason, forKey: "misReason")
for item in self.MissingPunchListArray {
arrObj.setValue(item.inDate, forKey: "in_date")
arrObj.setValue(item.inTime, forKey: "in_time")
arrObj.setValue(item.outDate, forKey: "out_date")
arrObj.setValue(item.outTime, forKey: "out_time")
jsonArrayDict.add(arrObj)
}
jsonDataDict.setValue(jsonArrayDict, forKey: "punchArray")
below is another function I am trying to do ;
let url = "https://iiplccr.hrgird.com/owner/hrmessapi/applymissingPunch"
var request = URLRequest(url: NSURL(string: url)! as URL)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try! JSONSerialization.data(withJSONObject: ["punchdata": jsonDataDict])
Alamofire.request(request)
.responseJSON { response in
switch response.result {
case .failure(let error):
print("error: \(error)")
if let data = response.data, let responseString = String(data: data, encoding: .utf8) {
print("responseString: \(responseString)")
}
case .success(let responseObject):
print("responseObject: \(responseObject)")
}
}
I get below error:
[Data]: 37025 bytes
[Result]: FAILURE: responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(error: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
You can try this way
var JsonDic = [String:Any]()
JsonDic["maids"] = "649"
JsonDic["misReason"] = "test"
JsonDic["uId"] = "20"
JsonDic["aDate"] = "2020-04-24"
let arr = [[String: String]]()
var obj = [String: String]()
obj["in_time"] = "14:10:00"
obj["to_city_id"] = "2020-04-24"
obj["out_date"] = "2020-04-24"
obj["out_time"] = "19:00:00"
arr.append(obj)
JsonDic["punchArray"] = arr

Resources