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)
}
}