Swift 无法将json转换为结构对象

Swift 无法将json转换为结构对象,swift,Swift,我想将JSON数据解析成一个struct对象,但我做不到。 实际上,代码在不同的文件中,但在这里我把它作为一个整体发布 这是我的密码: import Foundation struct dataResponse: Decodable { var results: [userData] init(from decoder: Decoder) throws { var results = [userData] () var container =

我想将JSON数据解析成一个struct对象,但我做不到。 实际上,代码在不同的文件中,但在这里我把它作为一个整体发布

这是我的密码:

import Foundation

struct dataResponse: Decodable {
    var results: [userData]

    init(from decoder: Decoder) throws {
        var results = [userData] ()
        var container = try decoder.unkeyedContainer()
        while !container.isAtEnd {
            if let route = try? container.decode(userData.self) {
                results.append(route)
            }
            else {
               _ = try? container.decode(dummyData.self)
            }
        }
        self.results = results
    }
}

private struct dummyData: Decodable { }

enum dataError: Error {
    case dataUnavailable
    case cannotProcessData
}

struct userData: Codable {
    var avatar: String
    var city: String
    var contribution: Int
    var country: String
    var friendOfCount: Int
    var handle: String
    var lastOnlineTimeSeconds: Int
    var maxRank: String
    var maxRating: Int
    var organization: String
    var rank: String
    var rating: Int
    var registrationTimeSeconds: Int
    var titlePhoto: String
}

struct dataRequest {
    let requestUrl: URL

    init(){
        self.requestUrl = URL(string: "https://codeforces.com/api/user.info?handles=abhijeet_ar")!
    }
    func getData(completionHandler: @escaping(Result<[userData], dataError>) -> Void) {

        URLSession.shared.dataTask(with: self.requestUrl) { (data,response, error) in
            guard let data = data else {
                completionHandler(.failure(.dataUnavailable))
                print("-------bye-bye--------")
                return
            }
            do {
                print("-------entered--------")
//                let dataresponse = try JSONDecoder().decode([userData].self, from: data)
//                print(type(of: dataresponse))
//               completionHandler(.success(dataresponse))
                let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
                print(jsonResult)
                completionHandler(.success(jsonResult as! [userData]))
            }
            catch {
                completionHandler(.failure(.cannotProcessData))
            }

        }.resume()
    }
}
<代码>导入基础 结构数据响应:可解码{ var结果:[用户数据] init(来自解码器:解码器)抛出{ 变量结果=[userData]() var container=try decoder.unkeydcontainer() while!container.isattend{ 如果let route=try?container.decode(userData.self){ 结果。追加(路由) } 否则{ _=try?container.decode(dummyData.self) } } self.results=结果 } } 私有结构dummyData:可解码{} 枚举数据错误:错误{ 案例数据不可用 案例不能处理数据 } 结构userData:Codable{ 虚拟角色:字符串 var城市:字符串 风险值贡献:整数 国家:字符串 var-friendOfCount:Int 变量句柄:字符串 var lastOnlineTimeSeconds:Int var-maxRank:String var最大额定值:Int 变量组织:字符串 变量秩:字符串 风险值评级:整数 var注册时间秒:Int 变量titlePhoto:String } 结构数据请求{ 让requestUrl:URL init(){ self.requestUrl=URL(字符串:https://codeforces.com/api/user.info?handles=abhijeet_ar")! } func getData(completionHandler:@escaping(Result)->Void){ URLSession.shared.dataTask(带:self.requestUrl){(数据、响应、错误)在 guard let data=其他数据{ completionHandler(.failure(.dataUnavailable)) 打印(“----再见----”) 返回 } 做{ 打印(“----输入----”) //让dataresponse=try JSONDecoder().decode([userData].self,from:data) //打印(类型(类型:dataresponse)) //completionHandler(.success(dataresponse)) 让jsonResult=try JSONSerialization.jsonObject(with:data,options:JSONSerialization.ReadingOptions.mutableContainers)作为AnyObject 打印(jsonResult) completionHandler(.success(jsonResult as![userData])) } 抓住{ completionHandler(.failure(.cannotProcessData)) } }1.简历() } } 这里userData是我的结构 错误显示:无法将类型为“\uu NSDictionaryM”(0x7fff8fe2dab0)的值强制转换为“NSArray”(0x7fff8fe2dd30)


如果有人帮忙,我将不胜感激,谢谢。

您的问题是使用了错误的结构。创建并使用
响应
结构进行解码。您需要保留您的类型,以便将第一个字母大写,以避免混淆。您可以使用
JSONDecoder()
也许您使用的格式不正确。请尝试下面的代码

struct Response: Codable {
    var result: [UserData]
}

enum DataError: Error {
    case dataUnavailable, cannotProcessData
}

struct DataRequest {

    let requestUrl: URL

    init(){
        self.requestUrl = URL(string: "https://codeforces.com/api/user.info?handles=abhijeet_ar")!
    }

    func getData(completionHandler: @escaping(Result<Response, DataError>) -> Void) {

        URLSession.shared.dataTask(with: self.requestUrl) { (data,response, error) in
            guard let data = data else {
                completionHandler(.failure(.dataUnavailable))
                return
            }
            do {
                let dataresponse = try JSONDecoder().decode(Response.self, from: data)
               completionHandler(.success(dataresponse))
            } catch {
                completionHandler(.failure(.cannotProcessData))
            }

        }.resume()
    }
}
struct响应:可编码{
var结果:[UserData]
}
枚举数据错误:错误{
案例数据不可用,无法处理数据
}
结构数据请求{
让requestUrl:URL
init(){
self.requestUrl=URL(字符串:https://codeforces.com/api/user.info?handles=abhijeet_ar")!
}
func getData(completionHandler:@escaping(Result)->Void){
URLSession.shared.dataTask(带:self.requestUrl){(数据、响应、错误)在
guard let data=其他数据{
completionHandler(.failure(.dataUnavailable))
返回
}
做{
让dataresponse=try JSONDecoder().decode(Response.self,from:data)
completionHandler(.success(dataresponse))
}抓住{
completionHandler(.failure(.cannotProcessData))
}
}1.简历()
}
}

注意:
UserData
中的参数始终需要右键。尝试使用并清空struct以检查其他所有操作是否正常,然后继续逐个添加变量。

您的问题是使用了错误的struct。创建并使用
响应
结构进行解码。您需要保留您的类型,以便将第一个字母大写,以避免混淆。您可以使用
JSONDecoder()
也许您使用的格式不正确。请尝试下面的代码

struct Response: Codable {
    var result: [UserData]
}

enum DataError: Error {
    case dataUnavailable, cannotProcessData
}

struct DataRequest {

    let requestUrl: URL

    init(){
        self.requestUrl = URL(string: "https://codeforces.com/api/user.info?handles=abhijeet_ar")!
    }

    func getData(completionHandler: @escaping(Result<Response, DataError>) -> Void) {

        URLSession.shared.dataTask(with: self.requestUrl) { (data,response, error) in
            guard let data = data else {
                completionHandler(.failure(.dataUnavailable))
                return
            }
            do {
                let dataresponse = try JSONDecoder().decode(Response.self, from: data)
               completionHandler(.success(dataresponse))
            } catch {
                completionHandler(.failure(.cannotProcessData))
            }

        }.resume()
    }
}
struct响应:可编码{
var结果:[UserData]
}
枚举数据错误:错误{
案例数据不可用,无法处理数据
}
结构数据请求{
让requestUrl:URL
init(){
self.requestUrl=URL(字符串:https://codeforces.com/api/user.info?handles=abhijeet_ar")!
}
func getData(completionHandler:@escaping(Result)->Void){
URLSession.shared.dataTask(带:self.requestUrl){(数据、响应、错误)在
guard let data=其他数据{
completionHandler(.failure(.dataUnavailable))
返回
}
做{
让dataresponse=try JSONDecoder().decode(Response.self,from:data)
completionHandler(.success(dataresponse))
}抓住{
completionHandler(.failure(.cannotProcessData))
}
}1.简历()
}
}

注意:
UserData
中的参数始终需要右键。尝试使用并清空struct检查其他所有操作是否正常,然后继续逐个添加变量。

您犯了一个非常常见的错误

您正在忽略根对象,它是一个字典并导致错误

struct Root: Decodable {
    let status : String
    let result: [UserData]
}

struct UserData: Decodable {
    let avatar: String
    let city: String
    let contribution: Int
    let country: String
    let friendOfCount: Int
    let handle: String
    let lastOnlineTimeSeconds: Int
    let maxRank: String
    let maxRating: Int
    let organization: String
    let rank: String
    let rating: Int
    let registrationTimeSeconds: Int
    let titlePhoto: String
}
忘记
JSONSerialization
,只使用
JSONDecoder

返回无意义的枚举错误不是一个好主意。使用
Error
并返回real错误

使用
dataresponse.result

struct DataRequest { // name structs always with starting capital letter
    let requestUrl: URL

    init(){
        self.requestUrl = URL(string: "https://codeforces.com/api/user.info?handles=abhijeet_ar")!
    }
    func getData(completionHandler: @escaping(Result<Root, Error>) -> Void) {

        URLSession.shared.dataTask(with: self.requestUrl) { (data,response, error) in
            guard let data = data else {
                completionHandler(.failure(error!))
                print("-------bye-bye--------")
                return
            }
            do {
                print("-------entered--------")
                let dataresponse = try JSONDecoder().decode(Root.self, from: data)
                completionHandler(.success(dataresponse))   
            }
            catch {
                completionHandler(.failure(error))
            }

        }.resume()
    }
}
struct DataRequest{//name结构始终以大写字母开头
让requestUrl:URL
init(){
self.requestUrl=URL(字符串:https://codeforces.com/api/user.info