【问题标题】:How do I decode my HTTP Get request with a JSON body in Swift 5?如何在 Swift 5 中使用 JSON 正文解码我的 HTTP Get 请求?
【发布时间】:2022-01-06 20:44:01
【问题描述】:

我正在尝试从响应中获取数据。在 RapidAPI 页面上,我尝试了 GET 请求,并且在应用程序中我也得到了响应。但它不会将 JSON 解码为我的 Decodable 协议。我以前针对天气和地点做过,但这次似乎不适合。

class ClubManager {
    func getClubInformation(clubID: String) async throws -> Club? {

        
        guard let url = URL(string: "https://transfermarket.p.rapidapi.com/clubs/get-squad?id=\(clubID)") else {fatalError("Missing URL")}

        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = "GET"
        urlRequest.setValue("transfermarket.p.rapidapi.com", forHTTPHeaderField: "x-rapidapi-host")
        urlRequest.setValue("006f5b3a01mshaa222632dd44131p17cc4djsn9e2c7e927b93", forHTTPHeaderField: "x-rapidapi-key")

        
        let (data, response) = try await URLSession.shared.data(for: urlRequest)
        
        guard (response as? HTTPURLResponse)?.statusCode == 200 else {fatalError("error fetching data")}
        
        print(response)

        let decodedData = try JSONDecoder().decode(ResponseBody.self, from: data)
        
        
        return decodedData
        
    }
}

struct Club: Decodable {
    
    var mainFacts: MainFacts
    var stadium: Stadium
    
    struct MainFacts: Decodable {
        var id: String
        var fullName: String
        var city: String
        var coutryImage: String
        var squadSize: String
        var avgAge: String
    }
    
    struct Stadium: Decodable {
        var id: String
        var name: String
        var totalCapacity: String
        var image: String
    }
    
}

API 说我收到了这个响应正文:

{
    "internationalTeamFlag":"",
    "mainFacts":{
        "id":"44",
        "fullName":"Hertha Berliner Sport-Club",
        "street":"Hanns-Braun-Straße, Friesenhaus 2",
        "postalCode":"14053",
        "city":"Berlin",
        "phone":"+49 30 300928",
        "fax":"+49 30 300928",
        "homepage":"www.herthabsc.de",
        "founding":"25.07.1892",
        "members":"37800",
        "membersDate":"01.07.2020",
        "countryName":"Deutschland",
        "countryID":"40",
        "countryImage":"https://tmssl.akamaized.net/images/flagge/verysmall/40.png?lm=1520612525",
        "avgAge":"26.20",
        "squadSize":"30",
        "legionaries":"16",
        "internationalRank":"",
        "nationalPlayer":6
    },
    "stadium":{
        "id":"343",
        "name":"Olympiastadion Berlin",
        "street":"Olympischer Platz",
        "postalCode":"14053",
        "city":"Berlin",
        "phoneTicketCenter":"+49 30 3009280",
        "faxTicketCenter":"+49 30 30092899",
        "homepage":"www.olympiastadion-berlin.de",
        "ticketCenter":"www.eventim.de/tickets.html?fun=erdetail&affiliate=OLY&doc=erdetaila&erid=470534",
        "constructionYear":"1934",
        "totalCapacity":"74649",
        "standingRoom":"0",
        "seats":"74649",
        "image":"https://tmssl.akamaized.net/images/foto/stadionnormal/olympiastadion-berlin-1587729679-37029.jpg?lm=1587729699"
    },
    "historicImages":[
        0:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597300.png?lm=1400597299",
        1:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597307.png?lm=1400597306",
        2:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597316.png?lm=1400597315",
        3:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597323.png?lm=1400597322",
        4:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597332.png?lm=1400597331",
        5:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597346.png?lm=1400597345",
        6:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597356.png?lm=1400597355",
        7:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597368.png?lm=1400597367",
        8:"https://tmssl.akamaized.net/images/wappen/medium/44_1400597374.png?lm=1400597374",
        9:"https://tmssl.akamaized.net/images/wappen/medium/44_1502534268.png?lm=1502534269"
    ]
    "successes":[
        0:{
            "number":"2",
            "name":"Deutscher Meister",
            "id":"10",
            "additionalData":{
                "competitionId":"L1",
                "competitionTypeId":"1",
                "cycle":NULL,
                "seasonIds":[
                    0:"1930",
                    1:"1929",
                ]
            }
        }
    ]
    "additionalTeams":[
        0:{
            "image":"https://tmssl.akamaized.net/images/wappen/medium/44.png?lm=1534505742",
            "name":"Hertha BSC",
            "id":"44"
        },
        1:{
            "image":"https://tmssl.akamaized.net/images/wappen/medium/45.png?lm=1562952802",
            "name":"Hertha BSC II",
            "id":"45"
        }
    ]
    "share":{
        "title":"Vereinsprofil Hertha BSC",
        "url":"https://www.transfermarkt.de/hertha-bsc/startseite/verein/44",
        "description":"Dies ist die Vereins-Startseite. Hier gibt es neben dem aktuellen Kader vereinsrelevante News, aktuelle Gerüchte und alle wichtigen Infos rund um den Spielbetrieb des Klubs."
    }
}

这是错误:

Error getting Club: keyNotFound(CodingKeys(stringValue: "mainFacts", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"mainFacts\", intValue: nil) (\"mainFacts\").", underlyingError: nil))

【问题讨论】:

  • 报错说没有Club,也没有。
  • 什么是ResponseBody"x-rapidapi-key" 是否重视您自己的私钥?如果是,您可能想隐藏它。
  • 您显示的json数据不是有效的json。先解决这个问题,然后你就有机会解码它。主要与缺少逗号和数组有关。
  • 另外,您在MainFacts 中使用coutryImage 而不是countryImage。向我们展示真实的 json 数据,而不是您认为的数据。
  • 要显示您从服务器获得的内容,请执行以下操作(然后显示给我们):在let (data, response) = try await URLSession.shared.data(for: urlRequest) 之后添加print("---> data: \(String(data: data, encoding: .utf8))")

标签: json swift httprequest httpresponse decodable


【解决方案1】:

我不太确定 ResponseBody 是什么,但我会尝试 改变

    let decodedData = try JSONDecoder().decode(ResponseBody.self, from: data)

 let decodedData = try JSONDecoder().decode(Club.self, from: data)

【讨论】:

  • 谢谢,忘记重构了
猜你喜欢
  • 1970-01-01
  • 2015-11-03
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2017-01-05
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
相关资源
最近更新 更多