SwiftyJSON 数据仅使用我 json 的第一个元素

SwiftyJSON data is only using the first element of my json

我正在使用 Alamofire 和 SwiftyJSON 并且正在获取数据,但我的视图只是重复 JSON 的第一个元素的数据。数据应为星期一、星期二、星期三等

[![在此处输入图片描述][1]][1]

这是我正在使用的class

class observer : ObservableObject {

    @Published var datas = [datatype]()

    init() {

        AF.request("https://api.npoint.io/e667b934a476b8b88745").responseData { (data) in

            let json = try! JSON(data: data.data!)
            let trainingDay = json["weekExercise"].arrayValue.map
            {[=11=]["exercise"].stringValue}
            print(trainingDay)

            for i in json["weekExercise"]{

                self.datas.append(datatype(id: i.1["weeknumber"].intValue,
                                           day: i.1["day"].stringValue,
                                           exercise: i.1["exercise"].stringValue,
                                           dayMiles: i.1["dayMiles"].intValue))

            }
        }
    }
}

我的数据是这样的:

{
    "weeknumber": 1,
    "weekExercise": [
      {
            "day": "Monday",
            "dayMiles": 6,
            "exercise": "6 miles"
        },
        {
            "day": "Tuesday",
            "dayMiles": 9,
            "exercise": "12 x 400m WU/CD"
        },
        {
            "day": "Wednesday",
            "dayMiles": 0,
            "exercise": "Rest"
        },
        {
            "day": "Thursday",
            "dayMiles": 6,
            "exercise": "6 miles"
        },
        {
            "day": "Friday",
            "dayMiles": 6,
            "exercise": "6 miles"
        },
        {
            "day": "Saturday",
            "dayMiles": 6,
            "exercise": "6 miles"
        },
        {
            "day": "Saturday",
            "dayMiles": 8,
            "exercise": "8 miles"
        }
    ],
    "totalWeekMiles": 41,
    "planName": "Hanson Method Advance"
}



  [1]: https://i.stack.imgur.com/9ZlRy.png?s=256

我的建议是利用 Alamofire 对 CodableCombine 的支持。 SwiftyJSON 已过时,不再需要。

import Combine
import Alamofire

struct ExerciseData : Codable, Identifiable {
    let id : Int
    let weeknumber : Int
    let weekExercise : [Exercise]
}

struct Exercise : Codable, Identifiable {
    let id = UUID()
    let day: String
    let dayMiles: Int
    let exercise: String
    
    private enum CodingKeys : String, CodingKey { case day, dayMiles, exercise}
}

class Observer : ObservableObject {
    
    private var subscription : AnyCancellable?

    @Published var exercises = [Exercise]()

    init() {
        subscription = AF.request("https://api.npoint.io/e667b934a476b8b88745")
            .publishDecodable(type: [ExerciseData].self, queue: .global())
            .result()
            .receive(on: DispatchQueue.main)
            .map{ result -> [Exercise] in
                switch result {
                    case .success(let data) : return data.first?.weekExercise ?? []
                    case .failure: return []
                }
            }
            .sink(receiveCompletion: { _ in
                self.subscription = nil // this breaks the retain cycle
            }, receiveValue: { exercises in
                self.exercises = exercises
            })
        
    }
}

您甚至可以删除 Alamofire 以支持内置数据任务发布者

import Combine

class Observer : ObservableObject {
    
    private var subscription : AnyCancellable?

    @Published var exercises = [Exercise]()

    init() {
        let url = URL(string: "https://api.npoint.io/e667b934a476b8b88745")!
        subscription = URLSession.shared.dataTaskPublisher(for: url)
            .receive(on: DispatchQueue.main)
            .map(\.data)
            .decode(type: [ExerciseData].self, decoder: JSONDecoder())
            .map{[=11=].first?.weekExercise ?? []}
            .replaceError(with: [])
            .sink(receiveCompletion: { _ in
                self.subscription = nil
            }, receiveValue: { exercises in
                self.exercises = exercises
            })
    }
}

错误处理是基本的。它 returns 一个空数组以防出错。