Trying to run a PFQuery that will lead to only one result being returned however the parameters that I am envoking are not specific enough - ios

I am trying to run a PFQuery in order to find specific results for an address stored in the server. However, when I try for a specific address I am always returned 0. The fields that this class possesses are objectId, startTime and title. I am unsure if this is the best way to pose the question but is there a type of general format that would allow me to query for the latest address stored and return that as a string in the code? Here is what I have written thus far in my load screen view controller, which is designed to place a user based on her/his location.
import UIKit
import CoreLocation
import Parse
class LoadViewController: UIViewController, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var lastUserLocation = "nil"
var address = ""
var startTime = ""
func findEventProximity(eventObjectId: String){
var eventObjectIdQuery = PFQuery(className: "Events")
eventObjectIdQuery.orderByDescending("createdAt")
eventObjectIdQuery.whereKey("objectId", equalTo: eventObjectId)
eventObjectIdQuery.findObjectsInBackgroundWithBlock({ (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
print(objects!.count)
if let objects = objects as [PFObject]? {
for object in objects {
object["objectId"] = selectedEventObjectId
/* need to decide wether to store Time in createNewEvent as NSDate or just string
if object["date"] != nil {
self.eventDateLabel.text = object["date"] as! NSDate
}
*/
print("\(object["address"] as! String)")
}
} else {
print(error)
}
}
})
}
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
findEventProximity(selectedEventObjectId)
// Do any additional setup after loading the view.
}
/*MARK: LOCATION*/
/*MARK: LOCATION*/
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.locationManager.stopUpdatingLocation()
let userLocation: CLLocation = locations[0]
let userLocationLat = locations[0].coordinate.latitude
let userLocationLong = locations[0].coordinate.longitude
var location = CLLocation(latitude: userLocationLat, longitude: userLocationLong)
print("\(userLocationLat), \(userLocationLong)")
let locationsToCheck: [CLLocation] = [
CLLocation(latitude: lat, long),
CLLocation(latitude: lat, long),
CLLocation(latitude: lat, long),
CLLocation(latitude: lat, long)
]
let locationTags: [String] = [
"P1",
"P2",
"P3",
"P4"
]
var closestInMeters: Double = 50000.0
var closestIndex: Int = -1
for (locationIndex, potentialLocation) in locationsToCheck.enumerate() {
let proximityToLocationInMeters: Double = userLocation.distanceFromLocation(potentialLocation)
if proximityToLocationInMeters < closestInMeters {
closestInMeters = proximityToLocationInMeters
closestIndex = locationIndex
}
}
if (closestIndex == -1) {
self.lastUserLocation = "Other"
// SCLAlertView().showError("No Filter Range", subTitle: "Sorry! We haven’t got a Filter Range for you yet, email us and we’ll get right on it.").setDismissBlock({ () -> Void in
// selectedLocation = self.locationObjectIdArray[0]
// self.performSegueWithIdentifier("eventTableSegue", sender: self)
// })
// self.activityIndicator.stopAnimating()
// UIApplication.sharedApplication().endIgnoringInteractionEvents()
} else if locationTags[closestIndex] != self.lastUserLocation {
self.lastUserLocation = locationTags[closestIndex]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}

Related

Getting longitude and latitude

I have experience crash of the app when using it in US. In all other countries same code is working. The crash is happening on line:
let latitude = String(format: "%.7f", currentLocation.coordinate.latitude)
I really can't see what is the problem, specially cos is related to US and not to other counties. Any help will be very very much appreciate.
My UserLocation.swift looks like this:
import UIKit
import MapKit
public class GPSLocation {
static let sharedInstance = GPSLocation()
//MARK: Public variables
public var intermediateLatitude: String?
public var intermediateLongitude: String?
public var intermediateCountry: String?
public var intermediateCity: String?
public var intermediateTimeZone: String?
//MARK: Get Longitude, Country Code and City name
func getGPSLocation(completition: #escaping () -> Void) {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locManager = manager
var currentLocation: CLLocation!
locManager.desiredAccuracy = kCLLocationAccuracyBest
if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedAlways) {
currentLocation = locManager.location
if currentLocation != nil {
// Get longitude & latitude
let latitude = String(format: "%.7f", currentLocation.coordinate.latitude)
let longitude = String(format: "%.7f", currentLocation.coordinate.longitude)
self.intermediateLatitude = latitude
self.intermediateLongitude = longitude
// debugPrint("Latitude:",latitude)
// debugPrint("Longitude:",longitude)
// Get local time zone GMT
let localTimeZoneAbbreviation = TimeZone.current.abbreviation() ?? "" // "GMT-2"
let indexStartOfText = localTimeZoneAbbreviation.index(localTimeZoneAbbreviation.startIndex, offsetBy: 3) // 3
let timeZone = localTimeZoneAbbreviation.substring(from: indexStartOfText) // "-2"
self.intermediateTimeZone = timeZone
// debugPrint("GMT:",timeZone)
// Get Country code and City
let location = CLLocation(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude)
fetchCountryAndCity(location: location) { countryCode, city in
self.intermediateCountry = countryCode
self.intermediateCity = city
// debugPrint("Country code:",countryCode)
// debugPrint("City:",city)
completition()
}
} else {
// Location is NIL
}
}
}
locManager.delegate = self // and conform protocol
locationManager.startUpdatingLocation()
}
//MARK: Find countryCode & City name from longitude & latitude
func fetchCountryAndCity(location: CLLocation, completion: #escaping (String, String) -> ()) {
CLGeocoder().reverseGeocodeLocation(location) { placemarks, error in
if let error = error {
debugPrint(error)
} else if let countryCode = placemarks?.first?.isoCountryCode,
let city = placemarks?.first?.locality {
completion(countryCode, city)
}
}
}
}
You need to check location in delegate method
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation() // if you dont want continuously update
currentLocation = manager.location
let location = CLLocation(latitude: currentLocation.coordinate.latitude, longitude: currentLocation.coordinate.longitude)
fetchCountryAndCity(location: location) { countryCode, city in
self.intermediateCountry = countryCode
self.intermediateCity = city
// debugPrint("Country code:",countryCode)
// debugPrint("City:",city)
completition()
}
}
And set delegate
locManager.delegate = self // and conform protocol
locationManager.startUpdatingLocation()

Calling asynchronous tasks one after the other in Swift (iOS)

I'm having problems with trying to run several asynchronous tasks one by one using dispatch async in swift, for an iOS weather app. I want my 'update()' function to:
get the user's location (and store the latitude & longitude in the class variables)
when location services is complete, make a call to the weather API based on newly-populated lat & long variables
when API call (and subsequent XML parsing) is complete, update the UI (an iOS table view)
(Go easy on me, I'm a recently self-taught coder, so I'm assuming the more experienced of you out there will be able to point out various errors! Any help would be massively appreciated.)
var latitude: String = ""
var longitude: String = ""
var locationManager: CLLocationManager!
var forecastData: Weather = Weather() // the weather class has it's own asynchronous NSURLSession called retrieveForecast()
// which calls the Open Weather Map API and parses the XML
func refresh() {
// Here's where I don't know what I'm doing:
let group = dispatch_group_create()
dispatch_group_enter(group)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
self.getLocation()
dispatch_group_leave(group)
}
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
self.getWeather()
}
self.updateUI() // ...and I know that this is in totally the wrong place!
}
// function(s) to get phone's location:
func getLocation() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
locationManager.distanceFilter = 100.0
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.locationManager.stopUpdatingLocation()
manager.stopUpdatingLocation()
for item: AnyObject in locations {
if let location = item as? CLLocation {
if location.horizontalAccuracy < 1000 {
manager.stopUpdatingLocation()
self.latitude = String(location.coordinate.latitude)
self.longitude = String(location.coordinate.longitude)
}
}
}
}
// function to download and parse the weather data within forecastData object
func getWeather() {
let apiCall = "http://api.openweathermap.org/data/2.5/forecast?lat=" + self.latitude
+ "&lon=" + self.longitude + "&mode=xml&appid=" + self.openWeatherMapAPIKey
NSLog("getWeather called with api request: \(apiCall)")
self.forecastData.retrieveForecast(apiCall)
}
For any asynchronous operation it is a good manner to have a finish callback.
In your case, if you have implemented callbacks for getLocation and getWeather you'll never need dispatch_groups, you just call getWeather from getLocation's callback, and then you just call refreshUI from getWeather's callback.
var latitude: String = ""
var longitude: String = ""
var locationManager: CLLocationManager!
var forecastData: Weather = Weather() // the weather class has it's own asynchronous NSURLSession called retrieveForecast()
// which calls the Open Weather Map API and parses the XML
func refresh() {
self.getLocation()
}
// function(s) to get phone's location:
func getLocation() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
locationManager.distanceFilter = 100.0
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.locationManager.stopUpdatingLocation()
manager.stopUpdatingLocation()
for item: AnyObject in locations {
if let location = item as? CLLocation {
if location.horizontalAccuracy < 1000 {
manager.stopUpdatingLocation()
self.latitude = String(location.coordinate.latitude)
self.longitude = String(location.coordinate.longitude)
self.getWeather()
}
}
}
}
// function to download and parse the weather data within forecastData object
func getWeather() {
let apiCall = "http://api.openweathermap.org/data/2.5/forecast?lat=" + self.latitude
+ "&lon=" + self.longitude + "&mode=xml&appid=" + self.openWeatherMapAPIKey
NSLog("getWeather called with api request: \(apiCall)")
self.forecastData.retrieveForecast(apiCall)
// assuming that self.forecastData.retrieveForecast(apiCall) is completely synchronous, we can call updateUI below
self.updateUI()
}
Here is the code, demonstrating how dispatch_group can be used right way:
func refetchOrdersAndChats(remoteNotificationData: [NSObject : AnyObject], completion: ((Bool)->())?) {
var overallSuccess: Bool = true
let refetchGroup = dispatch_group_create();
dispatch_group_enter(refetchGroup);
CPChatController.sharedInstance.updateChat(remoteNotificationData, completion: { success in
overallSuccess = success && overallSuccess
dispatch_group_leave(refetchGroup);
})
dispatch_group_enter(refetchGroup);
CPChatController.sharedInstance.fetchNewOrdersWithNotification(remoteNotificationData, completion: { success in
overallSuccess = success && overallSuccess
dispatch_group_leave(refetchGroup);
})
dispatch_group_notify(refetchGroup,dispatch_get_main_queue(), {
completion?(overallSuccess)
})
}
After going off to learn about closures/blocks, I finally found my answer so thought I'd share. What I needed to do was add a closure to the arguments in my Weather class, which returns a boolean value when the XML parsing is complete, and allows me to wait for that to happen in my View Controller before updating the UI. I hope this helps anyone else looking for a similar answer, and if any pros are able to make this code even better, please do add a comment!
...
// getWeather function in my View Controller (called from location manager)
func getWeather() {
let apiCall = "http://api.openweathermap.org/data/2.5/forecast?lat=" + self.latitude
+ "&lon=" + self.longitude + "&mode=xml&appid=" + self.openWeatherMapAPIKey
NSLog("getWeather called with api request: \(apiCall)")
self.forecastData.retrieveForecast(apiCall, completion: { success in
if success {
self.updateUI()
} else {
NSLog("Parse unsuccessful")
// I'll handle the issue here
}
});
}
...And in the Weather class function:
func retrieveForecast(url: String, completion: ((Bool)->())?) {
self.reset()
let apiCall = NSURL(string: url)
let urlRequest: NSURLRequest = NSURLRequest(URL: apiCall!)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
self.xmlParser = NSXMLParser(data: data!)
self.xmlParser.delegate = self
let success: Bool = self.xmlParser.parse()
if !success {
NSLog("Did not parse. \(error?.localizedDescription)")
completion?(false)
} else {
self.currentParsedElement = ""
self.retrievingForecast = false
completion?(true)
}
}
task.resume()
}

Save to parse manually after data has been queried

I am using Parse pinInBackground feature to pin data (image, text, date, coordinates) in the background and that data is queried every time the app is opened.The app is used to log a photo and the location and coordinates.So every entry you make is queried and displays in a tableview (only the count of entries yet).
I want to be able to let the user manually sink with Parse.com and not use the saveEventually feature.
Meaning I want a button and when pressed the queried data must sink with Parse and the be in pinned.
Here is how my data is pinned
#IBAction func submitButton(sender: AnyObject) {
locationLogs["title"] = log.title
locationLogs["description"] = log.descriptionOf
println("log = \(log.title)")
println("log = \(log.descriptionOf)")
locationLogs.pinInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
if (success) {
}else{
println("error = \(error)")
}}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let location:CLLocationCoordinate2D = manager.location.coordinate
let altitude: CLLocationDistance = manager.location.altitude
println("new long= \(location.longitude)")
println("new lat= \(location.latitude)")
println("new altitude= \(altitude)")
println("new timestamp = \(timestamp)")
locationLogs["longitude"] = location.longitude
locationLogs["latitude"] = location.latitude
locationLogs["altitude"] = altitude
locationLogs["timestamp"] = timestamp
}
And here I query it
var result : AnyObject?
override func viewDidLoad() {
super.viewDidLoad()
let query = PFQuery(className:"LocationLogs")
query.fromLocalDatastore()
query.findObjectsInBackgroundWithBlock( { (NSArray results, NSError error) in
if error == nil && results != nil {
self.result = results
println("count = \(self.result!.count)")
self.loggedItemsTableView.reloadData()
}else{
println("ERRRROOOORRRR HORROOORRR= \(error)")
}
})
}
I have tried to use this command:
result?.saveAllInBackground()
But this only gave back an error.
Can someone please give me the correct code on how to do this or give me a link showing me how.
Here is a full code explanation on how I solved it:
//create an Array
var tableData: NSArray = []
func queryAll() {
let query = PFQuery(className:"LocationLogs")
query.fromLocalDatastore()
query.findObjectsInBackgroundWithBlock( { (NSArray results, NSError error) in
if error == nil && results != nil {
println("array = \(results)" )
self.tableData = results!
self.loggedItemsTableView.reloadData()
}else{
println("ERRRROOOORRRR HORROOORRR= \(error)")
}
})
}
//Call save on the class and not the object
PFObject.saveAllInBackground(self.tableData as [AnyObject], block: { (success: Bool, error: NSError?) -> Void in
if (success) {
//Remember to unpin the data if it will no longer be needed
PFObject.unpinAllInBackground(self.tableData as [AnyObject])
println("Pinned Data has successfully been saved")
}else{
println("error= \(error?.localizedDescription)")
}
})
Use this to safely cast/checked your object
if let results = self.result { // this will verify if your self.result is a non-nil array of object
// if it has a value then it will be passed to results
// you can now safely proceed on saving your objects
PFObject.saveAllInBackground(results, block: { (succeeded, error) -> Void in
// additional code
if succeeded {
// alert, remove hud ......
}else{
if let reqError = error {
println(reqError.localizedDescription)
}
}
})
}
struct log {
// this is dummy datastructure that imitate some part of your code ... you dont need it
var title = ""
var descriptionOf = ""
}
struct LocationInfo{
var title:String!
var description:String!
var location:PFGeoPoint!
var timestamp:NSDate!
var username:String
}
var locationManager = CLLocationManager()
var arrayOfLocations = [LocationInfo]()
func submitButton(sender: AnyObject) {
var logData = log()
var point = OneLocation(locationManager)
let username = PFUser.currentUser()?.username
var locationLogs = PFObject(className: "")
locationLogs["title"] = logData.title
locationLogs["description"] = logData.descriptionOf
locationLogs["Location"] = point
locationLogs["username"] = username
locationLogs["TimeStamp"] = locationManager.location.timestamp
locationLogs.saveInBackgroundWithBlock { (success:Bool, error:NSError?) -> Void in
if error == nil
{
println("data was save")
}
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
CLGeocoder().reverseGeocodeLocation (manager.location, completionHandler: {(placemarks, error)->Void in
var UserCurrentLocation:CLLocationCoordinate2D = manager.location.coordinate
// println("User's parking Location : \(UserCurrentLocation.latitude) \(UserCurrentLocation.longitude)")
if (error != nil) {
println("Error")
return
}
locationManager.stopUpdatingLocation()
})
}
func OneLocation(Manager:CLLocationManager)->PFGeoPoint{
var latitude = Manager.location.coordinate.latitude
var longitude = Manager.location.coordinate.longitude
var point = PFGeoPoint(latitude: latitude, longitude: longitude)
return point
}
func QueryFromParse(){
var query = PFQuery(className: "")
query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in
if error == nil
{
if let new_objects = objects as? [PFObject]
{
for SingleObject in new_objects
{
// with this single object you could get the description, title , username,etc
var location = SingleObject["Location"] as! PFGeoPoint
var username = SingleObject["username"] as! String
var title = SingleObject["title"] as! String
var time = SingleObject["TimeStamp"] as! NSDate
var description = SingleObject["description"] as! String
var singleLocationInfo = LocationInfo(title: title, description: description, location: location, timestamp: time, username: username)
arrayOfLocations.append(singleLocationInfo)
// reload data for the tableview
}
}
}
else
{
println("error")
}
}
}
Therefore you have an arrayoflocations that can be used to populate data in your tableView
Struct log is a dummy datastructure
And also I don't know if that was what you wanted ... but you should get the idea..
Hope that helps..

How to download my object? (issue with optionals in old Xcode version)

Since I developed this my app with Xcode 6.2, I found some problems, many solved, but this one, maybe requires to rebuild my app again.
In the code below, filterByProximity function gives an error.
I SUPPOSE is a matter of optionals (Nils Ziehn warned me here about it). Another developer told me: "download the position object using cache, and then make the query".
Well, is it possible? how can I do it? here my code:
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var locationManager = CLLocationManager()
var lat = locationManager.location.coordinate.latitude
var lon = locationManager.location.coordinate.longitude
let location = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: true)
let anotation = MKPointAnnotation()
anotation.setCoordinate(location)
anotation.title = "my title"
anotation.subtitle = " my subtitle"
mapView.addAnnotation(anotation)
println("****** Welcome in MapViewController")
//MARK: (471) Crossing Positions
//*******************************************************
let myGeoPoint = PFGeoPoint(latitude: lat, longitude:lon)
let myParseId = PFUser.currentUser().objectId //PFUser.currentUser().objectId
println("****** this is my geoPoint from map view controller: \(myGeoPoint)")
//
// var inspector = PFQuery(className:"GameScore")
// inspector.saveInBackgroundWithBlock {
// (success: Bool, error: NSError?) -> Void in
// if (success) {
// // The object has been saved.
// var the = inspector.objectId
// } else {
// // There was a problem, check error.description
// }
// }
//
//
//
//MARK: *** let's look for other users ***
// func filterByProximity() {
// PFQuery(className: "Position")
// .whereKey("where", nearGeoPoint: myGeoPoint, withinKilometers: 500.0) //(474)
// .findObjectsInBackgroundWithBlock ({
// objects, error in
// if let proximityArray = objects as? [PFObject] {
// println("****** here the proximity matches: \(proximityArray)")
// for near in proximityArray {
// println("here they are \(near)")
//
// let position = near["where"] as? PFGeoPoint
//
//// if let position = near["where"] as! PFGeoPoint {
//// let theirLat = position.latitude
//// let theirLon = position.longitude
//// }
//
// let theirLat = near["where"].latitude as Double
// let theirlong = near["where"].longitude as Double
// let location = CLLocationCoordinate2DMake(theirLat, theirlong)
// let span = MKCoordinateSpanMake(0.05, 0.05)
// let region = MKCoordinateRegionMake(location, span)
// self.mapView.setRegion(region, animated: true)
// let theirAnotation = MKPointAnnotation()
// theirAnotation.setCoordinate(location)
// self.mapView.addAnnotation(anotation)
//
//
// }
// }
// })
// }
//
// filterByProximity()
// //MARK: *** let's update my position (on Parse) ***
//
// func exists() {
// PFQuery(className:"Position")
// .whereKey("who", containsString: myParseId)
// .findObjectsInBackgroundWithBlock({
// thisObject, error in
// if let result = thisObject as? [PFObject] {
// println("here the result: \(result)")
//
// let gotTheId = result[0].objectId
// println("ecco l'id singolo \(gotTheId)")
//
// //******** update function ********
// var query = PFQuery(className:"Position")
// query.getObjectInBackgroundWithId(gotTheId) {
// (usingObject: PFObject?, error: NSError?) -> Void in
// if error != nil {
// println(error)
// } else if let objectToupdate = usingObject {
// println("else occurred")
// objectToupdate["where"] = myGeoPoint
// println("position should be updated")
// objectToupdate.saveInBackgroundWithBlock(nil)
// println("position should be saved")
//
// }
// }
// //******** end update function ********
// }
// })
// }
//
// exists()
//*******************************************************
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

how to retrive location from a PFGeopoint - (Parse.com and Swift) and show it on the map with Xcode 6.2

There are some answer on this, but related to different problems and all in objective-c.
I save in a parse class "Position" positions of users with this:
var locationManager = CLLocationManager()
var lat = locationManager.location.coordinate.latitude
var lon = locationManager.location.coordinate.longitude
let myGeoPoint = PFGeoPoint(latitude: lat, longitude:lon)
let myParseId = PFUser.currentUser().objectId //PFUser.currentUser().objectId
println("****** this is my geoPoint: \(myGeoPoint)")
func sendPosition(userOfPosition: User) {
let takePosition = PFObject(className: "Position")
takePosition.setObject(myParseId, forKey: "who") //who
takePosition.setObject(myGeoPoint, forKey: "where")
takePosition.saveInBackgroundWithBlock(nil)
}
sendPosition(currentUser()!)
so this is my result:
then I want to show them on map, but how? don't understand how to retrive latitude and longitude from "where" column the code below doesn't work:
import UIKit
import MapKit
class MapViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
var locationManager : CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var locationManager = CLLocationManager()
var lat = locationManager.location.coordinate.latitude
var lon = locationManager.location.coordinate.longitude
let location = CLLocationCoordinate2D(latitude: lat, longitude: lon)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegionMake(location, span)
mapView.setRegion(region, animated: true)
let anotation = MKPointAnnotation()
anotation.setCoordinate(location)
anotation.title = "my title"
anotation.subtitle = " my subtitle"
mapView.addAnnotation(anotation)
println("****** Welcome in MapViewController")
//MARK: (471) Crossing Positions
//*******************************************************
let myGeoPoint = PFGeoPoint(latitude: lat, longitude:lon)
let myParseId = PFUser.currentUser().objectId //PFUser.currentUser().objectId
println("****** this is my geoPoint from map view controller: \(myGeoPoint)")
//
// var inspector = PFQuery(className:"GameScore")
// inspector.saveInBackgroundWithBlock {
// (success: Bool, error: NSError?) -> Void in
// if (success) {
// // The object has been saved.
// var the = inspector.objectId
// } else {
// // There was a problem, check error.description
// }
// }
//
//
//
func filterByProximity() {
PFQuery(className: "Position")
.whereKey("where", nearGeoPoint: myGeoPoint, withinKilometers: 500.0) //(474)
.findObjectsInBackgroundWithBlock ({
objects, error in
if let proximityArray = objects as? [PFObject] {
println("****** here the proximity matches: \(proximityArray)")
for near in proximityArray {
println("here they are \(near)")
if let position = near["where"] as! PFGeoPoint {
let theirLat = position.latituide
let theirLon = position.longitude
}
let theirLat = near["where"].latitude as Double
let theirlong = near["where"].longitude as Double
let location = CLLocationCoordinate2DMake(theirLat, theirlong)
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegionMake(location, span)
self.mapView.setRegion(region, animated: true)
let theirAnotation = MKPointAnnotation()
theirAnotation.setCoordinate(location)
self.mapView.addAnnotation(anotation)
}
}
})
}
filterByProximity()
// //update my position
//
// func exists() {
// PFQuery(className:"Position")
// .whereKey("who", containsString: myParseId)
// .findObjectsInBackgroundWithBlock({
// thisObject, error in
// if let result = thisObject as? [PFObject] {
// println("here the result: \(result)")
//
// let gotTheId = result[0].objectId
// println("ecco l'id singolo \(gotTheId)")
//
// //******** update function ********
// var query = PFQuery(className:"Position")
// query.getObjectInBackgroundWithId(gotTheId) {
// (usingObject: PFObject?, error: NSError?) -> Void in
// if error != nil {
// println(error)
// } else if let objectToupdate = usingObject {
// println("else occurred")
// objectToupdate["where"] = myGeoPoint
// println("position should be updated")
// objectToupdate.saveInBackgroundWithBlock(nil)
// println("position should be saved")
//
// }
// }
// //******** end update function ********
// }
// })
// }
//
// exists()
//*******************************************************
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Update after first answers
tried to check for optionals, but have this message:
after not down casting the double:
the 'where' is a PFGeoPoint, you can just call latitude and longitude on them
Try something like this - I'm not 100% sure in Swift syntax, yet
if(geoPoint)
{
if(geoPoint!.latitude)
{
let latitude = geoPoint!.latitude as double;
}
}
this worked. Was both a matter of optionals, and a matter of variables, I was using the wrong ones:
//MARK: (471) Crossing Positions
//*******************************************************
let myGeoPoint = PFGeoPoint(latitude: lat, longitude:lon)
let myParseId = PFUser.currentUser().objectId //PFUser.currentUser().objectId
var radius = 100.0
println("****** this is my geoPoint from map view controller: \(myGeoPoint)")
//MARK: *** let's look for other users ***
var nearArray : [CLLocationCoordinate2D] = []
func filterByProximity() {
PFQuery(className: "Position")
.whereKey("where", nearGeoPoint: myGeoPoint, withinKilometers: radius) //(474)
.findObjectsInBackgroundWithBlock ({
objects, error in
if let proximityArray = objects as? [PFObject] {
// println("****** here the proximity matches: \(proximityArray)")
for near in proximityArray {
// println("here they are \(near)")
let position = near["where"] as? PFGeoPoint
var theirLat = position?.latitude //this is an optional
var theirLong = position?.longitude //this is an optional
var theirLocation = CLLocationCoordinate2D(latitude: theirLat!, longitude: theirLong!)
nearArray.append(theirLocation)
if nearArray.isEmpty {
println("*** ERROR! anyone close by ***")
} else
{
for person in nearArray {
let span = MKCoordinateSpanMake(2.50, 2.50)
let region = MKCoordinateRegionMake(theirLocation, span)
self.mapView.setRegion(region, animated: true)
let theirAnotation = MKPointAnnotation()
theirAnotation.setCoordinate(theirLocation)
theirAnotation.title = near["who"] as String
self.mapView.addAnnotation(theirAnotation)
}
}
}
println("****** in a radius of \(radius) there are \(nearArray.count) bikers ******")
}
})
}
filterByProximity()

Resources