How to pass Data object in Post Api in swift - arrays

I am new in swift and trying to send Data to Api which is in the form of Data object and i am trying to pass that data in JSON
let val:Data = myFile.DataRepresentation()
let json: [String: Any] = ["file": val,
"dict": ["1":"First", "2":"Second"]]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
it giving me error "Invalid type in JSON.write"
or help me how can i pass Data in NSMUtableURLRequest

Try to implement this code example, it should work:
let json: [String: Any] = ["name": "morpheus",
"job": "leader"]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "https://reqres.in/api/users")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responseJSON = responseJSON as? [String: Any] {
print(responseJSON)
}
}
task.resume()

Related

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

"print array in main thread swift3 Xcode 8"

I learn swift not long ago and i have some problem in this code print array:
class InitController: UIViewController {
public var initdata = [(id: String, name: String)]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
print("initdata", initdata)
init_auth()
}
func init_auth(){
let json: [String: Any] = ["token": UserDefaults.standard.value(forKey: "token"), "id":UserDefaults.standard.value(forKey: "id")]
//let jsonData = try? JSONSerialization.data(withJSONObject: json)
let jsonData = try? JSONSerialization.data(withJSONObject: json)
let url = "http://some_ip/api"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
//print(jsonData)
let task = URLSession.shared.dataTask(with: request) { data, responce, error in guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responceJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responceJSON = responceJSON as? [String: Any]{
let s = responceJSON["specialities"] as? NSDictionary
let d = s?["items"] as! NSArray
for i in d {
let f = i as? NSDictionary
self.initdata.append((id: f?["id"] as! String, name: f?["name"] as! String))
}
}
}
print("list", self.initdata)
task.resume()
}
}
initdata is empty array, but I get some json file and append this array. I try print initdata, but this array is nil. I think maybe problem in thread, but I don't know how realize this.
Try this -
func init_auth(){
let json: [String: Any] = ["token": UserDefaults.standard.value(forKey: "token"), "id":UserDefaults.standard.value(forKey: "id")]
//let jsonData = try? JSONSerialization.data(withJSONObject: json)
let jsonData = try? JSONSerialization.data(withJSONObject: json)
let url = "http://some_ip/api"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.httpBody = jsonData
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
//print(jsonData)
let task = URLSession.shared.dataTask(with: request) { data, responce, error in guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let responceJSON = try? JSONSerialization.jsonObject(with: data, options: [])
if let responceJSON = responceJSON as? [String: Any]{
let s = responceJSON["specialities"] as? NSDictionary
let d = s?["items"] as! NSArray
for i in d {
let f = i as? NSDictionary
self.initdata.append((id: f?["id"] as! String, name: f?["name"] as! String))
}
print("list", self.initdata)
}
}
task.resume()
}

How to wait the function execution until json loaded in Swift?

I am getting json file from url, then, all json output will be added in a array. When I print the array, it says that array is empty, but actually array is not empty I know. If I use like: DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { }, then, I can print the array.
My code to get json and adding its values to the array:
var allTags:Array<String> = []
func getJSON(getUrl:URL){
let url:URL = getUrl
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest) {
(data, response, error) in
let dataString = String(data: data, encoding: String.Encoding.utf8)!
do {
let data = Data(dataString.utf8)
let dictionaries = (try? JSONSerialization.jsonObject(with: data)) as? [[String:Any]] ?? []
for dict in dictionaries {
let tags = dict["Tags"] as? [String] ?? []
for tag in tags {
allTags.append(tag)
}
}
}
}task.resume()
}
getJSON(getUrl: self.jsonUrl())
print(self.allTags.count) //it prints 0, but there are some data I know
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
print(self.allTags.count) //it prints 168
}
Use a callback:
var allTags:Array<String> = []
func getJSON(getUrl:URL, callback: #escaping () -> Void) {
let url:URL = getUrl
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
let dataString = String(data: data, encoding: String.Encoding.utf8)!
do {
let data = Data(dataString.utf8)
let dictionaries = (try? JSONSerialization.jsonObject(with: data)) as? [[String:Any]] ?? []
for dict in dictionaries {
let tags = dict["Tags"] as? [String] ?? []
for tag in tags {
allTags.append(tag)
}
}
callback()
}
}
task.resume()
}
getJSON(getUrl: self.jsonUrl()) {
print(self.allTags.count) // Should work now
}
var allTags:Array<String> = []
func getJSON(getUrl:URL, completion: #escaping () -> ()) {
let url:URL = getUrl
let session = URLSession.shared
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData
let task = session.dataTask(with: request as URLRequest) {
(data, response, error) in
let dataString = String(data: data, encoding: String.Encoding.utf8)!
do {
let data = Data(dataString.utf8)
let dictionaries = (try? JSONSerialization.jsonObject(with: data)) as? [[String:Any]] ?? []
for dict in dictionaries {
let tags = dict["Tags"] as? [String] ?? []
for tag in tags {
allTags.append(tag)
}
}
completion()
}
}task.resume()
}
getJSON(getUrl: self.jsonUrl()) { [weak self] in
guard let strongSelf = self else { return }
print(strongSelf.allTags.count)
}

Send array to server starting with iOS 7

I need to send many variables to server. Previously I was using construction like this:
let myURL = NSURL(string: "http://example.com");
let request = NSMutableURLRequest(URL:myURL!);
request.HTTPMethod = "POST";
let postString = "param1=\(var1)&param2=\(var2)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding);
Now I need to send not only variables like param1 and param2 but few arrays. I know that there is library called Alamofire but it is not supporting iOS 7.
You can do something like this,
let mapDict = [ "a":"First", "b":"Second"]
let json = [ "title":"kk" , "dict": mapDict ]
let jsonData = NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted, error: nil)
// create post request
let url = NSURL(string: "http://example.com/post")!
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
// insert json data to the request
request.HTTPBody = jsonData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request){ data,response,error in
if error != nil{
println(error.localizedDescription)
return
}
if let responseJSON = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as? [String:AnyObject]{
println(responseJSON)
}
}
task.resume()
You can use array instead of dictionary as per your requirement. hope this will help. :)

Resources