0

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://********/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.

1
  • 2
    Please stop using SwiftyJSON. It's not topical anymore. Decode the JSON directly into the model with JSONDecoder. And please have a close look at the JSON. The key data is inside BookDetails which is not the root object. By the way .padding(.all,4) and .padding(4) does the same. Commented Sep 16, 2022 at 10:52

1 Answer 1

2

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
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much sir. and please give me proper guidance of using API in Swiftui

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.