【问题标题】:Swiftui The data couldn’t be read because it isn’t in the correct formatSwiftui 无法读取数据,因为它的格式不正确
【发布时间】:2021-12-04 00:09:50
【问题描述】:

当我使用 api 运行代码时出现上述错误。我仔细检查了复制 json 文件并在本地运行它正常工作,我似乎无法得到错误来自哪里,

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

当我在模拟器上测试它运行时,但是当我搜索它时出现这个错误“无法读取数据,因为它的格式不正确。”

我的 json 数据示例

[
    {
        "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. "
    }
]

【问题讨论】:

  • print(error.localizedDescription) 替换为print(error) 以获得真正的错误。
  • 另外,不要丢弃服务器响应。你需要能够知道那里发生了什么。而且,作为一种习惯,您应该对 URL 设置一个保护措施,而不是强制打开它。
  • 用 print(error) 替换 print(error.localizedDescription) 后 2021-10-16 05:29:46.093362+0800 Country Search[65184:1005713] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed 数据无法'无法阅读,因为它的格式不正确。无法读取数据,因为它的格式不正确。
  • 我的意思是catch 范围内的行。没有发生第一个错误。
  • 知道了 2021-10-16 05:38:06.838399+0800 国家搜索[65243:1010598] [] nw_protocol_get_quic_image_block_invoke dlopen libquic 失败 typeMismatch(Swift.Dictionary, Swift. DecodingError.Context(codingPath: [], debugDescription: "期望解码 Dictionary 但找到了一个数组。",底层错误: nil))

标签: api search swiftui urlsession jsondecoder


【解决方案1】:

你的设计错了。

替换

let countrys = try JSONDecoder().decode(APIResult.self, from: APIData)
            
DispatchQueue.main.async {
                
    if self.fetchCountries == nil {
        self.fetchCountries = countrys.data.results
    }
}

let countries = try JSONDecoder().decode([Countries].self, from: APIData)
            
DispatchQueue.main.async {
    self.fetchCountries = countries
}

其他两个结构没有意义。

并将fetchCountries 声明为非可选的空数组,并将结构命名为单数形式Country

【讨论】:

  • 终于取得了进展,使用您的答案,但现在所有国家/地区都在我搜索时显示,其他 2 个结构( APICountryData 和 APIResult )用于帮助过滤掉我的搜索结果。不过感谢您的宝贵时间。
  • @EMPIRE 这个答案直接解决了您提出的问题并解决了它。您的代码中存在其他关于过滤问题中未提及的搜索结果的架构问题,这一事实可能不会妨碍您将此答案标记为正确。
猜你喜欢
  • 2016-10-15
  • 1970-01-01
  • 2019-07-28
  • 2018-04-06
  • 2020-07-26
  • 2021-10-05
  • 2021-11-11
  • 1970-01-01
相关资源
最近更新 更多