Closed sabina1997 closed 4 years ago
That JSON looks fairly simple to represent with a Decodable
struct.
struct APIRes: Decodable {
let error: Bool
let message: String
let data: [Person]
struct Person: Decodable {
let id: Int
let name: String
let image: String
let has_children: String
}
}
Then you can use this initializer to create a RequestView
that decodes to that type: public init<ResponseType: Decodable>(_ type: ResponseType.Type, _ request: Request, @ViewBuilder content: @escaping (ResponseType?) -> TupleView<(Content, Placeholder)>) {
Let me know if that works for you or if you need any more help.
Sorry I am new to swift and i am starting with SwiftUi . Can you show me an example in view like var body: some View { NavigationView { RequestView(Decodable, Request { Url(RestManager.baseUrl()) Header.Accept(.json) Header.ContentType(.json) Header.Authorization(.bearer(RestManager.headers())) }) { data in List(data != nil ? try! JSONDecoder().decode([APIRes].self, from: data!) : []) { category in
// need to get all categories here, in your example Person struct
}
Text("Loading...")
}
.navigationBarTitle(Text("Categories"))
}
}
Try this. I commented it with some explanations, hopefully those help:
struct APIRes: Decodable {
let error: Bool
let message: String
let data: [Category]
struct Category: Decodable {
let id: Int
let name: String
let image: String
let has_children: String
}
}
struct MyView: View {
var body: some View {
NavigationView {
// Here we give it the type that we expect back.
// To get the actual type (not an instance) in Swift we add `.self` to the end
// This tells the RequestView to try and map the JSON we get to the `APIRes` struct
RequestView(APIRes.self, Request {
Url(RestManager.baseUrl())
Header.Accept(.json)
Header.ContentType(.json)
Header.Authorization(.bearer(RestManager.headers()))
}) { (data: APIRes?) in // here we get the data back. It's optional, but already in the `APIRes` format.
// We check if it's null, then force unwrap it if it's not, and grab the category array from the `data` property.
List(data != nil ? data!.data : []) { (category: APIRes.Category) in
Text(category.name)
}
Text("Loading...")
}
.navigationBarTitle(Text("Categories"))
}
}
}
When you use that initializer, swift-request
handles decoding the data for you.
I tried this but i got this error
You can pass an ID to the list like so:
List(data != nil ? data!.data : [], id: \.id) { (category: APIRes.Category) in
...
}
now its working, thank you very much for your help :)
SwiftUI requires all list items to conform to the Identifiable
protocol so that when you try to do things like animations, it remembers which array item belongs to which UI element, among other things. The other way to give an ID is to pass the ID as a KeyPath
.
Here's some resources on this stuff if you want to learn more:
I have a json like this and I want to make a RequestView loading all categories { "error": false, "message": "Success", "data": [ { "id": 5, "name": "Man", "image": "phpSLlQP3.png", "has_children": "yes" }, { "id": 6, "name": "Woman", "image": "php1g8L0Q.png", "has_children": "no" } }