I am still new to swift and i am trying to fetch json data and pass it to the next view as an object which i created. However, i am getting this error Cannot convert value of type 'Dictionary?' to expected argument type 'Data' when i try to user the decoder class. I am not sure what to do to fix it. I have tried changing Dictionary?' to Data in my completion handler but i am still getting errors.
This is my code :
Service call
class ServiceCall: NSObject, ServiceCallProtocol, URLSessionDelegate {
let urlServiceCall: String?
let country: String?
let phone: String?
var search: SearchResultObj?
init(urlServiceCall: String,country: String, phone: String){
self.urlServiceCall = urlServiceCall
self.country = country
self.phone = phone
}
func fetchJson(request: URLRequest, customerCountry: String, mobileNumber: String, completion: ((Bool, Dictionary<String, Any>?) -> Void)?){
let searchParamas = CustomerSearch.init(country: customerCountry, phoneNumber: mobileNumber)
var request = request
request.httpMethod = "POST"
request.httpBody = try? searchParamas.jsonData()
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
do {
let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, Any>
let status = json["status"] as? Bool
if status == true {
print(json)
}else{
print(" Terrible failure")
}
} catch {
print("Unable to make an api call")
}
})
task.resume()
}
}
SearchViewModel
func searchDataRequested(_ apiUrl: String,_ country: String,_ phone:String) {
let service = ServiceCall(urlServiceCall: apiUrl, country: country, phone: phone)
let url = URL(string: apiUrl)
let request = URLRequest(url: url!)
let country = country
let phone = phone
service.fetchJson(request: request, customerCountry: country, mobileNumber: phone)
{ (ok, json) in
print("CallBack response : \(String(describing: json))")
let decoder = JSONDecoder()
let result = decoder.decode(SearchResultObj.self, from: json)
print(result.name)
// self.jsonMappingToSearch(json as AnyObject)
}
}
New error:
You are going to deserialize the JSON twice which cannot work.
Instead of returning a Dictionary
return Data
, this mistake causes the error, but there are more issues.
func fetchJson(request: URLRequest, customerCountry: String, mobileNumber: String, completion: (Bool, Data?) -> Void) { ...
Then change the data task to
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
if let error = error {
print("Unable to make an api call", error)
completion(false, nil)
return
}
completion(true, data)
})
and the service call
service.fetchJson(request: request, customerCountry: country, mobileNumber: phone) { (ok, data) in
if ok {
print("CallBack response :", String(data: data!, encoding: .utf8))
do {
let result = try JSONDecoder().decode(SearchResultObj.self, from: data!)
print(result.name)
// self.jsonMappingToSearch(json as AnyObject)
} catch { print(error) }
}
}
And you have to adopt Decodable
in ServiceCall
class ServiceCall: NSObject, ServiceCallProtocol, URLSessionDelegate, Decodable { ...
Further I highly recommended to separate the class model from the code to retrieve the data.
The data returned from session's task can either be serialized with JSONSerialization
or decode it with JSONDecoder
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
either
let json = try JSONSerialization.jsonObject(with: data!) as! Dictionary<String, Any>
OR
let result = try decoder.decode([item].self,data!)
the second argument of the decode method expects a parameter of type Data
not Dictionary
you have to only edit the completion of fetchJson
to return Bool,Data instead of Bool,Dictionary,and remove JSONSerialization
code from it
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.