How to parse array data from Yelp API?

201 Views Asked by At

Allo, Hi, im new with SwiftUI and im facing some issue with the Yelp API and can't find answer anywhere... I'm creating a restaurant app and I want to add a on the business detail page a list of Yelp transactions that the business is registered for ("pickup", "delivery", and "restaurant_reservation").

I've try a lot of way to retrieved it but im about to give up... I don't know if it's me who's dumb or anything but my brain can't figured it out anymore. I've tried to get the data with "ForEach" and all any other way we usually get array data...

Second question (similar as the previous one) how can I retrieve the category alias/title from the API? I want to be able to filter the business based on their categories and also show on the business detail page the category associated to it.

Thank you :)

Yelp Response Body Example :

   {
  "total": 144,
  "businesses": [
    {
      "id": "gR9DTbKCvezQlqvD7_FzPw",
      "alias": "north-india-restaurant-san-francisco",
      "price": "$$",
      "url": "https://www.yelp.com/biz/north-india-restaurant-san-francisco",
      "rating": 4,
      "location": {
        "zip_code": "94105",
        "state": "CA",
        "country": "US",
        "city": "San Francisco",
        "address2": "",
        "address3": "",
        "address1": "123 Second St"
      },
      "categories": [
        {
          "alias": "indpak",
          "title": "Indian"
        }
      ],
      "phone": "+14153481234",
      "coordinates": {
        "longitude": -122.399305736113,
        "latitude": 37.787789124691
      },
      "image_url": "http://s3-media4.fl.yelpcdn.com/bphoto/howYvOKNPXU9A5KUahEXLA/o.jpg",
      "is_closed": false,
      "name": "North India Restaurant",
      "review_count": 615,
      "transactions": ["pickup", "restaurant_reservation"]
    },
    // ...
  ]
}

Here is my Business model :

class Business: Decodable, Identifiable, ObservableObject {
    
    @Published var imageData: Data?
    
    var id: String?
    var alias: String?
    var name: String?
    var imageUrl: String?
    var isClosed: Bool?
    var url: String?
    var reviewCount: Int?
    var categories: [Category]?
    var rating: Double?
    var coordinates: Coordinate?
    var transactions: [String]?
    var price: String?
    var location: Location?
    var phone: String?
    var displayPhone: String?
    var distance: Double?
    
    enum CodingKeys: String, CodingKey {
        
        case imageUrl = "image_url"
        case isClosed = "is_closed"
        case reviewCount = "review_count"
        case displayPhone = "display_phone"
        
        case id
        case alias
        case name
        case url
        case categories
        case rating
        case coordinates
        case transactions
        case price
        case location
        case phone
        case distance
    }
    
    func getImageData() {
        
        // Check that image url isn't nil
        guard imageUrl != nil else {
            return
        }
        
        // Download the data for the image
        if let url = URL(string: imageUrl!) {
            
            // Get a session
            let session = URLSession.shared
            let dataTask = session.dataTask(with: url) { (data, response, error) in
                
                if error == nil {
                    
                    DispatchQueue.main.async {
                        // Set the image data
                        self.imageData = data!
                    }
                }
            }
            dataTask.resume()
        }
    }
    
    static func getTestData() -> Business {
        let b = Business()
        return b
    }
}
struct Category: Decodable {
    var alias: String?
    var title: String?
}

Here an example of my code :

struct BusinessDetail: View {
    
    var business: Business

    
    @State private var showDirections = false
    
    var body: some View {
        
        VStack (alignment: .leading) {
            
            VStack (alignment:.leading, spacing:0) {
                
                GeometryReader() { geometry in
                    
                    // Business image
                    let uiImage = UIImage(data: business.imageData ?? Data())
                    Image(uiImage: uiImage ?? UIImage())
                        .resizable()
                        .scaledToFill()
                        .frame(width: geometry.size.width, height: geometry.size.height)
                        .clipped()
                        
                }
                .ignoresSafeArea(.all, edges: .top)
                
                
                // Open / closed indicator
                ZStack (alignment: .leading) {
                    Rectangle()
                        .frame(height: 35)
                        .foregroundColor(business.isClosed! ? Color("icon-primary") : Color("background"))
                    
                    Text(business.isClosed! ? "Closed" : "Open")
                        .foregroundColor(.white)
                        .font(.textHeader)
                        .padding(.leading)
                }
            }
            
            
            
            Group {
                
                HStack {
                    BusinessTitle(business: business)
                        .padding()
                    Spacer()
                }
  
                
                // Phone
                HStack {
                    Text("Phone:")
                        .bold()
                    Text(business.displayPhone ?? "")
                    Spacer()
                    Link("Call", destination: URL(string: "tel:\(business.phone ?? "")")!)
                }
                .padding()
                
                // Transactions
           if business.transactions != nil {

                ForEach(business.transactions!, id: \.self) { transaction in
            Text(transaction)
                        .font(.bodyParagraph)
                }
            }
0

There are 0 best solutions below