I Tried pull some restaurant data from foursquare base on user's location , but I got bunch of query error.
here is location code:
protocol UserLocationDelegate {
func tracingLocation(currentLocation: CLLocation)
}
class UserLocation: NSObject {
static let shared = UserLocation()
var delegate: UserLocationDelegate?
var userCurrentLocation: CLLocationCoordinate2D?
var locationManager: CLLocationManager?
func locationManagerStart() {
if locationManager == nil {
locationManager = CLLocationManager()
locationManager?.requestWhenInUseAuthorization()
locationManager?.distanceFilter = 1000
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
locationManager?.delegate = self
}
locationManager?.startUpdatingLocation()
}
func locationManagerStop() {
if locationManager != nil {
locationManager?.stopUpdatingLocation()
}
}
private func upataLocation(currentLocation: CLLocation) {
delegate?.tracingLocation(currentLocation: currentLocation)
}
}
extension UserLocation: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
upataLocation(currentLocation: location)
userCurrentLocation = location.coordinate
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .authorizedWhenInUse:
manager.startUpdatingLocation()
case .authorizedAlways:
manager.startUpdatingLocation()
case .restricted:
print("got error here, Authorization has been restriced")
case .denied:
locationManager = nil
print("got error here, Authorization has been denied")
@unknown default:
break
}
}
func locationManager(_ manager: CLLocationManager, didFinishDeferredUpdatesWithError error: Error?) {
if let error = error {
print(error.localizedDescription)
}
}
}
here is API code , Because "venues/search" doesn't contain detailed data about the venues. so I have to separate them. First, get the ID of the venues, then use the ID to get the venues details
And , I set records limit "50", which means I should got 50 response for Foursquare server .
class FoursquareAPI: NSObject, CLLocationManagerDelegate {
let categoryId = "4d4b7105d754a06374d81259" //food category
let client = FoursquareAPIClient(clientId: clientId , clientSecret: clientSecret)
func getDataFromJSON(with location: CLLocation, completion: @escaping (Data?, Error?) -> Void) {
let parameter:[String:String] = ["ll": "\(location.coordinate.latitude),\(location.coordinate.longitude)",
"limit": "50", "categoryId": categoryId]
client.request(path: "venues/search", parameter: parameter) {result in
switch result {
case let .success(data):
completion(data, nil)
//print(data)
case let .failure(error):
completion(nil, error)
}
}
}
func getVenuesData(with VenueID: String, completion: @escaping (Data?, Error?) -> Void) {
let parameter: [String: String] = ["VENUE_ID": VenueID]
client.request(path: "venues/\(VenueID)", parameter: parameter) {result in
switch result {
case let .success(data):
completion(data, nil)
case let .failure(error):
completion(nil, error)
}
}
}
}
call the api via users geolocation parameter , here's some if conditions: 1, app first launch? 2, user's movement distance since the last data acquisition
func tracingLocation(currentLocation: CLLocation) {
self.userCurrentLocation = currentLocation
let userMoved = currentLocation.distance(from: CLLocation(latitude: UserDefaults.standard.double(forKey: "userLastLat"), longitude: UserDefaults.standard.double(forKey: "userLastLong")))
if UserDefaults.standard.bool(forKey: "isFirstLaunch") || userMoved > 1000 {
loadBaseJSONData(with: currentLocation)
UserDefaults.standard.set(currentLocation.coordinate.latitude, forKey: "userLastLat")
UserDefaults.standard.set(currentLocation.coordinate.longitude, forKey: "userLastLong")
UserDefaults.standard.set(false, forKey: "isFirstLaunch")
}else {
print(userMoved as Any)
print("called step 3")
return
}
}
api call chain and save data to CoreData:
//MARK: - JSON
func loadBaseJSONData(with location: CLLocation) {
FoursquareAPI().getDataFromJSON(with: location){ (data, error) in
if let error = error {
print(error.localizedDescription)
return
}
guard let data = data else {return}
self.venuesBaseData = self.parseBaseJSON(data: data)
}
}
func parseBaseJSON(data: Data) -> [VenueBaseData] {
let decoder = JSONDecoder()
do {
let loadDataStore = try decoder.decode(RootClass.self, from: data)
self.venuesBaseData = loadDataStore.rootClass.venuesBaseData
for value in self.venuesBaseData {
loadVenuesJSON(whit: value.venueid)
}
}catch {
print(error)
}
return venuesBaseData
}
func loadVenuesJSON(whit venueID: String) {
FoursquareAPI().getVenuesData(with: venueID, completion: {(data, error) in
if let error = error {
print(error)
return
}
guard let data = data else {return}
self.venue = self.parseVenueJSON(data: data)
//self.tableView.reloadData()
})
}
func parseVenueJSON(data: Data) -> Venue {
let decoder = JSONDecoder()
do {
let loadDataStore = try decoder.decode(Response<SearchResponse>.self, from: data)
self.venue = loadDataStore.response.venues
if venue.photo.photoCount != 0 && venue.location.address != nil && venue.tips?.tipsCount != 0 {
var restaurant: RestaurantMO!
if let appdelegate = (UIApplication.shared.delegate as? AppDelegate) {
restaurant = RestaurantMO(context: appdelegate.persistentContainer.viewContext)
restaurant.id = venue.venueId
restaurant.name = venue.name
restaurant.type = venue.categories?[0].name
restaurant.location = venue.location.address
restaurant.phone = venue.contact.phone
restaurant.imageURL = venue.photo.group?[0].item?[0].venuePhotoURL
restaurant.summary = venue.tips?.tipsGroups?[0].tipsItems?[0].summary
restaurant.lat = venue.location.latitude!
restaurant.long = venue.location.longitude!
restaurant.distance = (self.userCurrentLocation?.distance(from: CLLocation(latitude: restaurant.lat, longitude: restaurant.long)))!
if let url = restaurant.imageURL {
URLSession.shared.dataTask(with: URL(string: url)!) {(data, response, error) in
if let error = error {
print(error)
return
}
if let data = data, let image = UIImage(data: data) {
DispatchQueue.main.sync {
restaurant.image = image.pngData()
appdelegate.saveContext()
}
}
}.resume()
}
appdelegate.saveContext()
}
}
}catch{
print(error)
}
return venue
}
After all of this, I got 14 records show on the tableView .... everytime , no more no less and got bunch of error in the debug area:
2020-10-08 10:07:19.087371+0800 DicFood[1041:182564] [connection] nw_resolver_start_query_timer_block_invoke [C8] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.840829+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C9] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.841318+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C10] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.858710+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C11] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.858858+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C12] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.858996+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C13] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.890860+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C14] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.891158+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C15] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.891241+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C16] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.891375+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C17] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.891420+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C18] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.891456+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C19] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.891574+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C20] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.892405+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C21] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.893128+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C22] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.893205+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C23] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.893242+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C24] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.893339+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C25] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.893374+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C26] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.894107+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C27] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.894260+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C28] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.894299+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C29] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.895213+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C30] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.895585+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C31] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.896063+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C32] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.896121+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C33] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.896159+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C34] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.896194+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C35] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.896981+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C36] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.897772+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C37] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.897841+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C38] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.897877+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C39] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.898385+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C40] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.898436+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C41] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.898471+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C42] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.898504+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C43] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.898542+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C44] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.898575+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C45] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.899597+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C46] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.899652+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C47] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.900221+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C48] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.900296+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C49] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.900383+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C50] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.900420+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C51] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.900461+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C52] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.900495+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C53] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.901379+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C54] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.901423+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C55] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.901959+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C56] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.902494+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C57] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:19.903016+0800 DicFood[1041:182413] [connection] nw_resolver_start_query_timer_block_invoke [C58] Query fired: did not receive all answers in time for api.foursquare.com:443
2020-10-08 10:07:20.836059+0800 DicFood[1041:182434] [connection] nw_resolver_start_query_timer_block_invoke [C59] Query fired: did not receive all answers in time for fastly.4sqi.net:443
2020-10-08 10:07:30.538722+0800 DicFood[1041:182565] [connection] nw_resolver_start_query_timer_block_invoke [C60] Query fired: did not receive all answers in time for app-measurement.com:443
2020-10-08 10:07:30.894479+0800 DicFood[1041:182564] [connection] nw_resolver_start_query_timer_block_invoke [C61] Query fired: did not receive all answers in time for app-measurement.com:443
2020-10-08 10:07:35.997608+0800 DicFood[1041:182564] [connection] nw_resolver_start_query_timer_block_invoke [C59] Query fired: did not receive all answers in time for fastly.4sqi.net:443
2020-10-08 10:08:15.394302+0800 DicFood[1041:182575] [connection] nw_resolver_start_query_timer_block_invoke [C59] Query fired: did not receive all answers in time for fastly.4sqi.net:443
2020-10-08 10:08:30.715883+0800 DicFood[1041:182875] [connection] nw_resolver_start_query_timer_block_invoke [C7] Query fired: did not receive all answers in time for firebaseinstallations.googleapis.com:443
2020-10-08 10:08:38.935937+0800 DicFood[1041:182875] [connection] nw_resolver_start_query_timer_block_invoke [C59] Query fired: did not receive all answers in time for fastly.4sqi.net:443
2020-10-08 10:08:49.383196+0800 DicFood[1041:182875] [connection] nw_resolver_start_query_timer_block_invoke [C7] Query fired: did not receive all answers in time for firebaseinstallations.googleapis.com:443
2020-10-08 10:09:11.498304+0800 DicFood[1041:182921] [connection] nw_resolver_start_query_timer_block_invoke [C59] Query fired: did not receive all answers in time for fastly.4sqi.net:443
anyone knows how to fix this ?