Reputation: 343
I'm fairly new to the understanding of using CoreLocation and Parse so please bear with me! I code with swift and a lot of SO posts I've been searching have been in Obc-C which i am very unfamiliar with.
.................................................................UPDATE....................................................................... Trying to store current users location into the Parse database but its not working. I get the error:
[Error]: invalid session token (Code: 209, Version: 1.9.1) Optional(Error Domain=kCLErrorDomain Code=0 "(null)")"
Any suggestions / help to point me in the right direction?
import UIKit
import Parse
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
var manager: CLLocationManager!
var activityIndicator:UIActivityIndicatorView = UIActivityIndicatorView()
@IBOutlet weak var username: UITextField!
@IBOutlet weak var password: UITextField!
@IBAction func signUp(sender: AnyObject) {
activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 50, 50))
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
let user = PFUser()
user.username = username.text
user.password = password.text
user.signUpInBackgroundWithBlock { (success, error) -> Void in
self.activityIndicator.stopAnimating()
UIApplication.sharedApplication().endIgnoringInteractionEvents()
if error == nil {
PFGeoPoint.geoPointForCurrentLocationInBackground { (geoPoint: PFGeoPoint?, error: NSError?) -> Void in
if error == nil {
print("got location successfully")
PFUser.currentUser()!.setValue(geoPoint, forKey:"location")
PFUser.currentUser()!.saveInBackground()
} else {
print(error)
}
}
self.performSegueWithIdentifier("login", sender: self)
} else {
print(error)
}
}
}
@IBAction func login(sender: AnyObject) {
activityIndicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 50, 50))
activityIndicator.center = self.view.center
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
UIApplication.sharedApplication().beginIgnoringInteractionEvents()
PFUser.logInWithUsernameInBackground(username.text!, password: password.text!) { (success, error) -> Void in
if error == nil {
self.activityIndicator.stopAnimating()
UIApplication.sharedApplication().endIgnoringInteractionEvents()
self.performSegueWithIdentifier("login", sender: self)
} else {
print(error)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
}
Upvotes: 1
Views: 754
Reputation: 3089
I would recommend storing the geopoint within your User
class. Also, rather than adding a geopoint to each Post
, you should add a pointer to the User
who created it. This eliminates the redundancy of storing the location twice and makes sure you don't have to mess with keeping the two variables in sync. Additionally, this is also much better practice than storing the objectId directly.
Update your Post
class to have a User
pointer column called user
. Then instead of
postEvent["userId"] = PFUser.currentUser()!.objectId!
Use
postEvent["user"] = PFUser.currentUser()!
It's also worth pointing out that Parse includes helper methods to get the current user's locations. It's as simple as the following
PFGeoPoint.geoPointForCurrentLocationInBackground {
(geoPoint: PFGeoPoint?, error: NSError?) -> Void in
if error == nil {
// do something with the new geoPoint
}
}
If you do decide to handle the CLLocationManager
yourself, make sure to call stopUpdatingLocation()
to save battery life once you've updated the user's location, assuming you don't need continuous location updates.
From there, you can use query constraints and a compound query to get all of the nearby Post
objects. In particular, you will want to use whereKey: matchesQuery:
as the compound query which only counts as 1 API request.
// User's location
let userGeoPoint = userObject["location"] as PFGeoPoint
// Query nearby Users
let nearbyUserQuery : PFQuery = PFUser.query()
nearbyUserQuery.whereKey("location", nearGeoPoint:userGeoPoint)
// Query Posts constrained to nearby Users
let nearbyPostQuery : PFQuery = PFQuery(className: "Post")
// Use a compound query to constrain the results to nearby Users
nearbyPostQuery.whereKey("user", matchesQuery: nearbyUserQuery)
// Limit the number of Posts if needed
nearbyPostQuery.limit = 20
nearbyPostQuery.findObjectsInBackgroundWithBlock {
(posts: [PFObject]?, error: NSError?) -> Void in
// Do something with the Posts
}
Upvotes: 2