Home > Enterprise >  fetch array data from API in SwiftUI?
fetch array data from API in SwiftUI?

Time:09-17

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
    }
}
  • Related