I am getting the above error when i run my code, using an api. I double checked copying the json file and running it locally it worked correctly, i cant seem to get where the error is coming from,
Countries.swift
struct APIResult: Codable {
var data: APICountryData
}
struct APICountryData: Codable {
var count: Int
var results: [Countries]
}
struct Countries: Identifiable, Codable {
var id: String
var name: String
var abrname: String
var flag_url: URL
var info: String
}
CountriesViewModel.swift
class CountriesViewModel: ObservableObject {
@Published var searchQuery = ""
var searchCancellable: AnyCancellable? = nil
//Fetched Data....
@Published var fetchCountries: [Countries]? = nil
@Published var offset: Int = 0
init() {
searchCancellable = $searchQuery
.removeDuplicates()
.debounce(for: 0.6, scheduler: RunLoop.main)
.sink(receiveValue: { str in
if str == ""{
// reset Data...
self.fetchCountries = nil
} else {
//search Data...
self.searchCountry()
}
})
}
func searchCountry() {
let url = "my api url"
let session = URLSession(configuration: .default)
session.dataTask(with: URL(string: url)!) { (data, _, err) in
if let error = err{
print(error.localizedDescription)
return
}
guard let APIData = data else {
print("No Data found")
return
}
do {
// Decoding API Data....
let countrys = try JSONDecoder().decode(APIResult.self, from: APIData)
DispatchQueue.main.async {
if self.fetchCountries == nil {
self.fetchCountries = countrys.data.results
}
}
}
catch{
print(error.localizedDescription)
}
}
.resume()
}
}
When i test it on the simulator it runs, but when i search it brings up this error "The data couldn’t be read because it isn’t in the correct format."
Sample of my json data
[
{
"id" : "0",
"name" : "Afghanistan",
"abrname" : "AFG",
"flag_url" : "Image URL",
"info" : "Afghanistan (/æfˈɡænɪstæn, æfˈɡɑËnɪstÉ‘Ën/ (About this soundlisten);[23] Pashto/Dari: اÙغانستان AfÄ¡ÄnestÄn, Pashto pronunciation: [afɣɑnɪstÉ‘n], Dari pronunciation: [afɣɒËnɪstÉ’Ën]), officially the Islamic Emirate of Afghanistan, is a landlocked country at the crossroads of Central and South Asia. It is bordered by Pakistan to the east and south, Iran to the west, Turkmenistan and Uzbekistan to the north, and Tajikistan and China to the northeast. Occupying 652,864 square kilometres (252,072 sq mi), the country is predominately mountainous with plains in the north and the southwest that are separated by the Hindu Kush mountains. Its population as of 2020 is 31.4 million, composed mostly of ethnic Pashtuns, Tajiks, Hazaras, and Uzbeks. Kabul serves as its capital and largest city."
},
{
"id" : "1",
"name" : "Andorra",
"abrname" : "AND",
"flag_url" : "Image URL",
"info" : "Andorra[g], officially the Principality of Andorra,[1][h] is a sovereign landlocked microstate on the Iberian Peninsula, in the eastern Pyrenees, bordered by France to the north and Spain to the south. Believed to have been created by Charlemagne, Andorra was ruled by the count of Urgell until 988, when it was transferred to the Roman Catholic Diocese of Urgell. The present principality was formed by a charter in 1278. It is headed by two co-princes: the Bishop of Urgell in Catalonia, Spain and the President of France. Its capital and also its largest city is Andorra la Vella. "
}
]
CodePudding user response:
Your design is wrong.
Replace
let countrys = try JSONDecoder().decode(APIResult.self, from: APIData)
DispatchQueue.main.async {
if self.fetchCountries == nil {
self.fetchCountries = countrys.data.results
}
}
With
let countries = try JSONDecoder().decode([Countries].self, from: APIData)
DispatchQueue.main.async {
self.fetchCountries = countries
}
the other two structs make no sense.
And declare fetchCountries
as non-optional empty array and name the struct in singular form Country
.