// // ContentModel.swift // City Sights App // // Created by Milos Ilic on 10.1.23.. // import Foundation import CoreLocation class ContentModel: NSObject, CLLocationManagerDelegate, ObservableObject { var locationManager = CLLocationManager() @Published var authorizationState = CLAuthorizationStatus.notDetermined @Published var restaurants = [Business]() @Published var sights = [Business]() override init() { // Init method of NSObject super.init() // Set ContentModel as the delegate of the location manager locationManager.delegate = self } func requestGeoLocationPermission() { // Request Permission from the user locationManager.requestWhenInUseAuthorization() } // MARK: - Location Manager Delegate Methods func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { // Update the authorizationState property authorizationState = locationManager.authorizationStatus if locationManager.authorizationStatus == .authorizedAlways || locationManager.authorizationStatus == .authorizedWhenInUse { // We have permission // Start geolocating the user after we get permission locationManager.startUpdatingLocation() } else if locationManager.authorizationStatus == .denied { // We don't have permission } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // Gives us the location of the user let userLocation = locations.first if userLocation != nil { // If we have the coordinates of the user send into Yelp API // Stop requesting the location after we get it once locationManager.stopUpdatingLocation() // If we have the coordinates of the user, send into Yelp API getBusinesses(category: Constants.sightsKey, location: userLocation!) getBusinesses(category: Constants.restaurantsKey, location: userLocation!) } } // MARK: - Yelp API methods func getBusinesses(category:String, location:CLLocation) { // Create URL // let urlString = "https://api.yelp.com/v3/businesses/search?latitude\(location.coordinate.latitude)&longitude=\(location.coordinate.longitude)&categories=\(category)&limit=6" // let url = URL(string: urlString) var urlComponents = URLComponents(string: Constants.apiUrl) urlComponents?.queryItems = [ URLQueryItem(name: "latitude", value: String(location.coordinate.latitude)), URLQueryItem(name: "longitude", value: String(location.coordinate.longitude)), URLQueryItem(name: "categories", value: category), URLQueryItem(name: "limit", value: "6") ] let url = urlComponents?.url if let url = url { // Create URL Request var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10.0) request.httpMethod = "GET" request.addValue("Bearer \(Constants.apiKey)", forHTTPHeaderField: "Authorization") // Get URLSession let session = URLSession.shared // Create Data Task let dataTask = session.dataTask(with: request) { (data, response, error) in // Check that there isn't an error if error == nil { do { // Parse json let decoder = JSONDecoder() let result = try decoder.decode(BusinessSearch.self, from: data!) // Sort businesses // Sort logic: If it is true b1 will be ahead, if it is false b2 will be ahead var businesses = result.businesses businesses.sort { b1, b2 in return b1.distance ?? 0 < b2.distance ?? 0 } // Call the get image function of the businesses for b in businesses { b.getImageData() } DispatchQueue.main.async { // Assign results to the appropriate property if category == Constants.sightsKey { self.sights = businesses } else if category == Constants.restaurantsKey { self.restaurants = businesses } } } catch { print(error) } } } // Start the Data Task dataTask.resume() } } }