I'm attempting to access the ratings part of Google's Places API but keep coming back empty with each call attempt. Any suggestions?
func nearBy()
{
...
//starting the task to the API
let task = URLSession.shared.dataTask(with: urlRequest) { [self]
(data, response, error) in
do {
//making sure it actually has something
if let error = error {
throw error
}
guard let data = data else {
print("data is nil")
return // or throw error
}
//for debugging, show response data as text
//print(String(data: data, encoding: .utf8) ?? "?")
guard let jsonDict = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
print("response data is not a JSON object")
return // or throw error
}
//setting jsonDict to read datta from url
guard let status = jsonDict["status"] as? String, status == "OK" else {
print("API error, status is not OK")
return // or throw error
}
let token = jsonDict["next_page_token"] as? String
guard let results = jsonDict["results"] as? [[String: Any]] else {
print("`results` is not an Array of JSON object")
return // or throw error
}
for result in results{
guard let name = result["name"] as? String else {
print("value for `name` not found or not object")
return // or throw some error or ignore and continue
}
guard let geometry = result["geometry"] as? [String: Any] else {
print("value for `geometry` not found or not object")
return // or throw some error or ignore and continue
}
guard let location = geometry["location"] as? [String: Double] else {
print("value for `location` not found or not object")
return // or throw some error or ignore and continue
}
guard let lat = location["lat"],
let lng = location["lng"] else {
print("value for `lat` or `lng` not found or not number")
return // or throw some error or ignore and continue
}
guard let place = result["place_id"] as? String else {
print("value for place not found or not number")
return // or throw some error or ignore and continue
}
guard let rating= result["rating"] as? String else {
print("value for rating not found")
return // or throw some error
}
DispatchQueue.global(qos: .userInitiated).async
{
//adding to the arr the names, lat and long,
semaphore.wait()
// self.pagetoken = token ?? "EMPTY"
self.nameArray.append(name)
let coord = CLLocationCoordinate2D(latitude: lat, longitude: lng)
self.locationArray.append(coord)
self.placeArray.append(place)
//self.ratingArray.append(rating)
self.status = "Ready"
semaphore.signal()
}
}
} catch {
print(error)
let title = NSLocalizedString("There was an Error", comment: "")
let message = NSLocalizedString("We encountered an error while trying to find you a place to eat. Try again later.", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Okay!", style: .default))
self.present(alert, animated: true, completion: nil)
}
}
task.resume()
}
Post
Replies
Boosts
Views
Activity
I'm attempting to store the values that I've obtained from a google API and then use them once the task.resume() has finished. But currently, the arrays are always empty once I've left the task. Is there anyway to go about this?
Thank you.
func nearBy() -> ([String], [String], [CLLocationCoordinate2D], Int)
{
var counter = 0
var arraylength = 0
var googleURLAPI = URLComponents(string: "https://maps.googleapis.com/maps/api/place/nearbysearch/json")!
googleURLAPI.queryItems = [
URLQueryItem(name: "location", value: "\(origin.latitude),\(origin.longitude)"),
URLQueryItem(name: "radius", value: range),
URLQueryItem(name: "type", value: "restaurant"),
//URLQueryItem(name: "price_level", value: price),
URLQueryItem(name: "keyword", value: keyword),
URLQueryItem(name: "key", value: KEY),
//URLQueryItem(name: "pagetoken", value: pagetoken)
]
print(googleURLAPI.url!)
var urlRequest = URLRequest(url: googleURLAPI.url!)
urlRequest.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: urlRequest) { [self]
(data, response, error) in
do {
if let error = error {
throw error
}
guard let data = data else {
print("data is nil")
return // or throw some error
}
guard let jsonDict = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
print("response data is not a JSON object")
return // or throw some error
}
guard let status = jsonDict["status"] as? String, status == "OK" else {
print("API error, status is not OK")
return // or throw some error
}
guard let results = jsonDict["results"] as? [[String: Any]] else {
print("`results` is not an Array of JSON object")
return // or throw some error
}
for result in results {
guard (result["name"] as? String) != nil else {
print("value for `name` not found or not object")
return // or throw some error or ignore and continue
}
arraylength = arraylength + 1
}
for result in results{
guard let name = result["name"] as? String else {
print("value for `name` not found or not object")
return // or throw some error or ignore and continue
}
guard let geometry = result["geometry"] as? [String: Any] else {
print("value for `geometry` not found or not object")
return // or throw some error or ignore and continue
}
guard let location = geometry["location"] as? [String: Double] else {
print("value for `location` not found or not object")
return // or throw some error or ignore and continue
}
guard let lat = location["lat"],
let lng = location["lng"] else {
print("value for `lat` or `lng` not found or not number")
return // or throw some error or ignore and continue
}
guard let place = result["place_id"] as? String else {
print("value for place not found or not number")
return // or throw some error or ignore and continue
}
DispatchQueue.main.async
{
self.nameArray.append(name)
let coord = CLLocationCoordinate2D(latitude: lat, longitude: lng)
self.locationArray.append(coord)
self.placeArray.append(place)
counter += 1
if counter == arraylength
{
self.random(counter: counter)
}
}
}
} catch {
print(error)
let title = NSLocalizedString("There was an Error", comment: "")
let message = NSLocalizedString("We encountered an error while trying to connect to Google. Try again later.", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Okay!", style: .default))
self.present(alert, animated: true, completion: nil)
}
}
task.resume()
return ( nameArray, placeArray, locationArray, arraylength)
}
I'm attempting to create a tutorial like view for my app on the first instance it is loaded up. I'm trying to change the initial view controller through that app delegate from different forums that I've found. I'm not getting any errors when running it, but it doesn't change the Initial VC to the one I want. Anything I am doing wrong?
This block is from my AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
GMSServices.provideAPIKey("API Key")
GMSPlacesClient.provideAPIKey("API Key")
let defaults = UserDefaults.standard
//checking to see if app has run before
if defaults.object(forKey: "isFirstTime") == nil {
defaults.set("No", forKey:"isFirstTime")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let viewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as? ViewController else{
fatalError("Unable to instantiate an ViewController from the sotryboard")
}
//setting new vc
self.window?.rootViewController = viewController
}
I'm trying to gather information from a place using Google API and the printed out value is: Optional("Website URL"). Is there anyway to remove the word optional and just use the URL of the place?
@IBAction func Info(_ sender: Any)
{
var website = "https://www.google.com/"
//setting default website
let googlePlaceURLAPI = URLComponents(string: "https://maps.googleapis.com/maps/api/place/details/json?place_id=\(placeArray[number])&fields=name,rating,formatted_phone_number,website&key=API_KEY")!
print(googlePlaceURLAPI.url!)
let placeID = placeArray[number]
//An array that holds the placeIDs obtained from different place API to access this API
// Specify the place data types to return.
let fields: GMSPlaceField = GMSPlaceField(rawValue: UInt(GMSPlaceField.website.rawValue))
let placesClient = GMSPlacesClient()
placesClient.fetchPlace(fromPlaceID: placeID, placeFields: fields, sessionToken: nil, callback: {
(place: GMSPlace?, error: Error?) in
if let error = error {
print("An error occurred: \(error.localizedDescription)")
return
}
if let place = place {
print("The selected place is: \(String(describing: place.website ))")
}
})
let vc = SFSafariViewController(url: URL(string: website)!)
present(vc, animated: true)
}
In attempts to store info from URL string by the google api page, the array only shows population after the second run through. This is what I got:
@IBAction func searchPlace(_ sender: Any) {
nearBy()
}
func nearBy()
{
var googleURLAPI = URLComponents(string: "https://maps.googleapis.com/maps/api/place/nearbysearch/json")!
googleURLAPI.queryItems = [
URLQueryItem(name: "location", value: "\(origin.latitude),\(origin.longitude)"),
URLQueryItem(name: "radius", value: "15000"),
URLQueryItem(name: "type", value: "Fast Food"),
URLQueryItem(name: "keyword", value: "Food"),
URLQueryItem(name: "key", value: "Key"),
]
print(googleURLAPI.url!)
var urlRequest = URLRequest(url: googleURLAPI.url!)
urlRequest.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: urlRequest) {
(data, response, error) in
do {
if let error = error {
throw error
}
guard let data = data else {
print("data is nil")
return
}
//For debugging, show response data as text
//print(String(data: data, encoding: .utf8) ?? "?")
guard let jsonDict = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
print("response data is not a JSON object")
return // or throw some error
}
//setting jsonDict to read datta from url
//Better check "status"
guard let status = jsonDict["status"] as? String, status == "OK" else {
print("API error, status is not OK")
return // or throw some error
}
guard let results = jsonDict["results"] as? [[String: Any]] else {
print("`results` is not an Array of JSON object")
return // or throw some error
}
//print("or here",LocArray)
for result in results {
guard let name = result["name"] as? String else {
print("value for `name` not found or not object")
return // or throw some error or ignore and continue
}
guard let geometry = result["geometry"] as? [String: Any] else {
print("value for `geometry` not found or not object")
return // or throw some error or ignore and continue
}
guard let location = geometry["location"] as? [String: Double] else {
print("value for `location` not found or not object")
return // or throw some error or ignore and continue
}
guard let lat = location["lat"],
let lng = location["lng"] else {
print("value for `lat` or `lng` not found or not number")
return // or throw some error or ignore and continue
}
self.nameArray.append(name)
let coord = CLLocationCoordinate2D(latitude: lat, longitude: lng)
self.locationArray.append(coord)
}
} catch {
print(error)
let title = NSLocalizedString("There was an Error", comment: "")
let message = NSLocalizedString("We encountered an error while trying to connect to Google. Try again later.", comment: "")
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Okay!", style: .default))
self.present(alert, animated: true, completion: nil)
}
}
task.resume()
printNames()
//gotoPlaces()
}
func printNames()
{
print("name array",nameArray)
print("location array",locationArray)
}
Have I somehow cleared the arrays without knowing?
Im attempting to store the lat and lng values from a google maps api url into an array but when ever I try to run it, the array comes out blank. Im able to get the names into the array but not sure why I can't get lat and lng stored.
Code Block - https://developer.apple.com/forums/content/attachment/a7a72b5c-01fb-47c6-90f9-eec12cc13027
Hello, I am trying to display all the content of my array to a label right before a random element is selected and displayed last. I tried the sleep function but it just slowed my whole app down and only displayed the last element. I'm probably doing something wrong with it:
while i<Places
{
label.text = Places[i]
sleep(1)
i +=1
}