Как мне разобрать и вернуть все данные json из ответа в Swift? - PullRequest
0 голосов
/ 02 июня 2018
struct LiveScores {
    let result: Bool
    let data: String
    let fixtures: [Fixture]

    struct Fixture : Codable {
        var kickOffTime: String
        var homeTeam: String
        var awayTeam: String
    }

    enum CodingKeys : String, CodingKey {
        case homeTeam = "home_name"
        case awayTeam = "away_name"
        case kickOffTime = "time"
    }
}

Я пытаюсь получить данные о приборах, в частности имя дома, имя и время выезда.Ниже приведен вызов, который я использую для извлечения данных:

    func fetchFixtures() {
    let session = URLSession.shared
    let url = URL(string: "\(baseUrl)fixtures/matches.json?key=\(apiKey)&secret=\(apiSecret)&date=2018-06-01")
    let task = session.dataTask(with: url!) { data, response, err in
        // check for a hard error
        if let error = err {
            NSLog("Live Scores Api Error: \(error)")
        }

        // check the response code
        if let httpResponse = response as? HTTPURLResponse {
            switch httpResponse.statusCode {
            case 200: // perfecto!
                if let fixture = self.fixtureFromJSONData(data!) {
                    NSLog("\(fixture)")
                }
            case 401: // unauthorised
                NSLog("Live Score Api returned an 'unauthorised' response.")
            default:
                NSLog("Live Scores Api returned response: %d %@", httpResponse.statusCode, HTTPURLResponse.localizedString(forStatusCode: httpResponse.statusCode))
            }
        }
    }
    task.resume()
}

Ответ JSON выглядит следующим образом:

{
"success": true,
"data": {
    "fixtures": [
        {
            "date": "2017-10-16",
            "time": "00:30:00",
            "round": "999",
            "home_name": "Santos Laguna",
            "away_name": "Atlas",
            "location": "",
            "league_id": "88"
        },
        {
            "date": "2017-10-16",
            "time": "00:30:00",
            "round": "999",
            "home_name": "O'Higgins",
            "away_name": "Audax Italiano",
            "location": "",
            "league_id": "63"
        },
        {
            "date": "2017-10-16",
            "time": "00:30:00",
            "round": "999",
            "home_name": "Colorado Rapids",
            "away_name": "Real Salt Lake",
            "location": "",
            "league_id": "94"
        }
    ],
    "next_page": "http:\/\/livescore-api.com\/api-client\/fixtures\/matches.json?key=demo_key&secret=demo_secret&page=2",
    "prev_page": false
}

Я успешно анализирую данные, но возвращается только один прибор -Я предполагаю, что это из-за индекса, который я указал как '[0]'.

 func fixtureFromJSONData(_ data: Data) -> LiveScores.Fixture? {
    typealias JSONDict = [String:AnyObject]
    let json : JSONDict

    do {
        json = try JSONSerialization.jsonObject(with: data, options: []) as! JSONDict
    } catch {
        NSLog("JSON parsing failed: \(error)")
        return nil
    }

    var jsonData = json["data"] as! [String:Any]
    var fixtureList = jsonData["fixtures"] as! [JSONDict]
    var fixtureDict = fixtureList[0]

    let fixture = LiveScores.Fixture(
                    kickOffTime: fixtureDict["time"] as! String,
                    homeTeam: fixtureDict["home_name"] as! String,
                    awayTeam: fixtureDict["away_name"] as! String
                    )
    return fixture
}

Как получить ВСЕ домашние имена, имена выездов и время для каждого возвращенного прибора?Каков был бы лучший способ сделать это?- Я пытался изменить функцию синтаксического анализа, но не повезло.

Спасибо :)

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Просто получите ваш результат от Codable, используя данные

Так ваша модель должна быть такой:

Модель:

import Foundation


struct LiveScores: Codable {
    let success: Bool
    let fixturesData: FixturesData?
    enum CodingKeys: String, CodingKey {
        case fixturesData = "data"
        case success 
    }
}

struct FixturesData: Codable {
    let fixtures: [Fixture]
    let nextPage, prevPage: Bool

    enum CodingKeys: String, CodingKey {
        case fixtures
        case nextPage = "next_page"
        case prevPage = "prev_page"
    }
}

struct Fixture: Codable {
    let id, date, time, round: String
    let homeName, awayName, location, leagueID: String
    let homeID, awayID: Int?

    enum CodingKeys: String, CodingKey {
        case id, date, time, round
        case homeName = "home_name"
        case awayName = "away_name"
        case location
        case leagueID = "league_id"
        case homeID = "home_id"
        case awayID = "away_id"
    }
}


// MARK: Convenience initializers

extension LiveScores {
    init(data: Data) throws {
        self = try JSONDecoder().decode(LiveScores.self, from: data)
    }

}

ваш API:

func fetchFixtures() {
        let session = URLSession.shared
        let url = URL(string: "\(baseUrl)fixtures/matches.json?key=\(apiKey)&secret=\(apiSecret)&date=2018-06-01")
        let task = session.dataTask(with: url!) { data, response, err in
            // check for a hard error
            if let error = err {
                NSLog("Live Scores Api Error: \(error)")
            }

            // check the response code
            if let httpResponse = response as? HTTPURLResponse {
                switch httpResponse.statusCode {
                case 200: // perfecto!

                   if let liveScores  = try? LiveScores.init(data: data!),
                    let fixture = liveScores.fixturesData{
                    NSLog("\(fixture)")

                   }
                case 401: // unauthorised
                    NSLog("Live Score Api returned an 'unauthorised' response.")
                default:
                    NSLog("Live Scores Api returned response: %d %@", httpResponse.statusCode, HTTPURLResponse.localizedString(forStatusCode: httpResponse.statusCode))
                }
            }
        }
        task.resume()
    }
0 голосов
/ 02 июня 2018

Если вы используете Codable, не сериализуйте данные самостоятельно, вы можете попробовать

 struct LiveScores : Codable 
 {
    let success : Bool
    let data: InnerObjc

 }

 struct InnerObjc: Codable 
 {
     let fixtures: [Fixture]
     let nextPage:String
     let prevPage:Bool

      enum CodingKeys : String, CodingKey {
        case fixtures = "fixtures"
        case nextPage = "next_page"
        case prevPage = "prev_page"
    }
 }

 struct Fixture : Codable {
    var kickOffTime: String
    var homeTeam: String
    var awayTeam: String

     enum CodingKeys : String, CodingKey {
        case homeTeam = "home_name"
        case awayTeam = "away_name"
        case kickOffTime = "time"
    }
 }

//

case 200: // perfecto!

    do {

       let myResult = try JSONDecoder().decode(LiveScores.self, from: data!)    
        print(myResult.data.fixtures)

      }
      catch {
      }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...