-1

My JSON

When I try to present the results I received this message "Response could not be decoded because of error: The data couldn’t be read because it isn’t in the correct format."

This is my format and its right I think.

  import Foundation

// MARK: - Response
struct Response: Codable {
    let code: Int
    let meta: Meta
    let data: [Datum]
}

// MARK: - Datum
struct Datum: Codable {
    let id, userID: Int
    let title, body: String

    enum CodingKeys: String, CodingKey {
        case id
        case userID = "user_id"
        case title, body
    }
}

// MARK: - Meta
struct Meta: Codable {
    let pagination: Pagination
}

// MARK: - Pagination
struct Pagination: Codable {
    let total, pages, page, limit: Int
}

also I try with this code to view the result.

private func fetchData() {
        self.task = AF.request(self.baseUrl, method: .get, parameters: nil)
        .publishDecodable(type: [Response].self)
            .sink(receiveCompletion: {(completion) in
                switch completion {
                case .finished:
                    ()
                case .failure(let error):
                    print(String(describing: error))
                    //print(error.localizedDescription)
                }
            }, receiveValue: {[weak self ](response) in
                switch response.result {
                case .success(let model):                self?.presenters = model.map {PostPresenter(with: $0)}
                case.failure(let error):
                     print(String(describing: error))
                    //  print(error.localizedDescription)
                }
            })
    }

And my post presenter code is this

struct PostPresenter: Identifiable {
    
    let id = UUID()
    let title: String
    
    init(with model:Response) {
        self.title = model.data
        
    }
    
}
georgekak
  • 73
  • 11
  • 1
    What is the full error message? – Mojtaba Hosseini Jul 18 '22 at 13:53
  • Xcode error- I Cannot assign value of type '[Datum]' to type 'String' ok, we have arrays understand. The output is Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in may also be helpful. 2022-07-18 16:12:53.951091+0300 iOS Assignment[17805:373050] [boringssl] boringssl_metrics_log_metric_block_invoke(153) Failed to log metrics Response could not be decoded because of error: The data couldn’t be read because it isn’t in the correct format. – georgekak Jul 18 '22 at 13:56
  • 1
    @kakouliadis for readability, instead of writing in the comments, please [edit] your question with additional information. – koen Jul 18 '22 at 15:27

2 Answers2

2

Two mistakes

  1. The root object is a dictionary so it's (type: Response.self)

  2. and model.data is [Datum] so declare

    struct PostPresenter: Identifiable {
    
        let id = UUID()
        let data: [Datum]
    
        init(with response: Response) {
            self.data = response.data
        }
    }
    

And in a Codable context print the error always print(error), not print(String(describing: error)) and never print(error.localizedDescription)

vadian
  • 274,689
  • 30
  • 353
  • 361
  • Thank you for your answer. Now I Have 4 errors. 1. Cannot convert value of type '[PostPresenter]' to expected argument type 'Binding' 2.Generic parameter 'Data' could not be inferred 3.Initializer 'init(_:)' requires that 'Binding' conform to 'StringProtocol' these 3 in content view var body: some View { List(self.viewModel.presenters) { Text($0.title) } NavigationView ... 4. And this in APIViewModel - Value of type 'Response' has no member 'map' – georgekak Jul 18 '22 at 14:12
  • 2
    That's another question which is related to your SwitUI view. And regarding 4. I don't know what `self.presenters` is – vadian Jul 18 '22 at 14:18
0

My right Post presenter

struct PostPresenter: Identifiable {

    let id = UUID()
    let data: [Datum]

    init(with response: Response<[Datum]>) {
        self.data = response.data

    }
    
    init() {
        data = []
    }
}

And my finally format as I right.

struct Response<T: Decodable>: Decodable {
    let code: Int
    let meta: Meta
    let data: T
}

// MARK: - Datum
struct Datum: Decodable {
    let id, userID: Int
    let title, body: String

    enum CodingKeys: String, CodingKey {
        case id
        case userID = "user_id"
        case title, body
    }
}

// MARK: - Meta
struct Meta: Decodable {
    let pagination: Pagination
}

// MARK: - Pagination
struct Pagination: Decodable {
    let total, pages, page, limit: Int
}

And finally my homeview and how I present

struct HomeView: View {
    
    @ObservedObject var viewModel = HomeAPIViewModel()
    
    var body: some View {
        
        ZStack {
            Color(.white)
            // Present the API Here
              List(self.viewModel.presenter.data, id: \.id) {
                  Text($0.title)
                }
                .padding()
        }
    }
}
georgekak
  • 73
  • 11