This is Model for My API and we will use this model in future. can Anyone tell me this is correct or Not. Im a native user of SwiftUI.
public struct Temperatures {
public let bookDetails: BookDetails
public init(bookDetails: BookDetails) {
self.bookDetails = bookDetails
}
}
public struct BookDetails {
public let data: [Datum]
public init(data: [Datum]) {
self.data = data
}
}
public struct Datum : Hashable, Identifiable {
public let id = UUID()
public let title: String
public let published: String
public let url: String
public init( title: String, published: String, url: String) {
self.title = title
self.published = published
self.url = url
}
}
And this is ViewModel And i cant fetch the data of data[]
View Model For Prime Book And Showing Details
class PrimeBookVM: ObservableObject{
@Published var datas = [Datum]()
init(){
let source = "https://alibrary.in/api/book-search?is_prime"
let url = URL(string: source)!
let session = URLSession(configuration: .default)
session.dataTask(with: url){
(data, _, err) in
if err != nil{
print(err?.localizedDescription ?? "Hello Error")
return
}
let json = try!JSON(data: data!)
for i in json["data"]{
let published = i.1["published"].stringValue
let title = i.1["title"].stringValue
let url = i.1["url"].stringValue
DispatchQueue.main.async {
self.datas.append(Datum(title: title, published: published, url: url))
}
}
}
.resume()
}
}
This is my View and try to fetch the detail of data array in api.
struct PrimeBooksView: View{
@StateObject var list = PrimeBookVM()
var body: some View{
ScrollView(.horizontal){
HStack{
ForEach(list.datas, id: \.self){ item in
VStack(alignment: .leading){
WebImage(url: URL(string: item.url)!, options: .highPriority, context: nil)
.resizable()
.frame(width: 180, height: 230)
Text(item.title)
.multilineTextAlignment(.leading)
.font(.system(size: 16))
.foregroundColor(Color("default"))
Text(item.published)
.font(.system(size: 12))
.fontWeight(.light)
.foregroundColor(Color("default"))
}
.padding(.all,4)
.background(Color.white).cornerRadius(8)
.shadow(color: .gray, radius: 1)
}
.padding(.all,1)
}
}
}
}
Thank You So much in Advance for Help.
CodePudding user response:
Try this example code, with a working set of data model structs, and an updated getData()
function
to fetch the data from the server. You still need to check the server documentation,
to determine which properties are optional.
import Foundation
import SwiftUI
struct ContentView: View {
var body: some View {
PrimeBooksView()
}
}
class PrimeBookVM: ObservableObject {
@Published var datas = [Datum]()
init() {
getData()
}
func getData() {
guard let url = URL(string: "https://alibrary.in/api/book-search?is_prime") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
if let data = data {
do {
let results = try JSONDecoder().decode(ApiResponse.self, from: data)
DispatchQueue.main.async {
self.datas = results.bookDetails.data
}
}
catch {
print(error)
}
}
}.resume()
}
}
struct PrimeBooksView: View{
@StateObject var list = PrimeBookVM()
var body: some View{
ScrollView(.horizontal){
HStack {
ForEach(list.datas, id: \.self){ item in
VStack(alignment: .leading){
AsyncImage(url: URL(string: item.url)) { image in
image
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 180, height: 230)
} placeholder: {
ProgressView()
}
Text(item.title)
.multilineTextAlignment(.leading)
.font(.system(size: 16))
Text(item.published)
.font(.system(size: 12))
.fontWeight(.light)
}
.padding(4)
.background(Color.white).cornerRadius(8)
.shadow(color: .gray, radius: 1)
}
}
}
}
}
public struct ApiResponse: Codable {
let bookDetails: BookDetails
let bookSearch: String?
let uploadTypeID: Int
let stackID: String
let data: Int
enum CodingKeys: String, CodingKey {
case bookDetails, bookSearch
case uploadTypeID = "upload_type_id"
case stackID = "stack_id"
case data
}
}
public struct BookDetails: Codable {
let currentPage: Int
let data: [Datum]
let firstPageURL: String
let from, lastPage: Int
let lastPageURL, nextPageURL, path: String
let perPage: Int
let prevPageURL: String?
let to, total: Int
enum CodingKeys: String, CodingKey {
case data, from, path, to, total
case currentPage = "current_page"
case firstPageURL = "first_page_url"
case lastPage = "last_page"
case lastPageURL = "last_page_url"
case nextPageURL = "next_page_url"
case perPage = "per_page"
case prevPageURL = "prev_page_url"
}
}
public struct Datum : Hashable, Identifiable, Codable {
public let id = UUID() // <-- could be Int
public let title: String
public let published: String
public let url: String
public init( title: String, published: String, url: String) {
self.title = title
self.published = published
self.url = url
}
enum CodingKeys: String, CodingKey {
case title, published, url
}
}