Reputation: 343
Is it normal for the iOS simulator to not work every so often with regards to grabbing the location? My project for this app keeps crashing 50% of the time whenever I run the simulator...but I can't seem to pinpoint the problem within the code itself. If the problem is indeed in the code itself, can anyone please help me find the problem? The error is "fatal error: unexpectedly found nil while unwrapping an Optional value" and it says it occurs in my refreshPost function on the line
eventsPostedQuery.whereKey("CityName", equalTo: self.usersLocation)
I am using Parse as part of this app. Also, I have a viewDidAppear to refresh the "Posts", is this a correct way to go about this? Greatly appreciated!
import UIKit
import Parse
class HomeTableViewController: UITableViewController, CLLocationManagerDelegate {
@IBOutlet weak var navigationBar: UINavigationItem!
@IBOutlet weak var menuButton: UIBarButtonItem!
@IBAction func cancelPost(segue: UIStoryboardSegue) {
}
var users = [String: String]()
var usernames = [String]()
var eventInfo = [String]()
var imageFiles = [PFFile]()
var usersLocation: String!
var locationManager: CLLocationManager!
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation: CLLocation = locations[0]
CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) -> Void in
if error != nil {
print(error)
} else {
let p = placemarks?.first // ".first" returns the first element in the collection, or nil if its empty
// this code above will equal the first element in the placemarks array
let city = p?.locality != nil ? p?.locality : ""
let state = p?.administrativeArea != nil ? p?.administrativeArea : ""
self.navigationBar.title = ("\(city!), \(state!)")
self.usersLocation = ("\(city!), \(state!)")
self.locationManager.stopUpdatingLocation()
print(self.usersLocation)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
menuButton.target = self.revealViewController()
menuButton.action = Selector("revealToggle:")
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 250.0
}
override func viewDidAppear(animated: Bool) {
refreshPosts()
}
func refreshPosts() {
let query = PFUser.query()
query?.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if let users = objects {
self.users.removeAll(keepCapacity: true)
self.usernames.removeAll(keepCapacity: true)
self.eventInfo.removeAll(keepCapacity: true)
self.imageFiles.removeAll(keepCapacity: true)
for object in users {
if let user = object as? PFUser {
self.users[user.objectId!] = user.username!
}
}
}
let eventsPostedQuery = PFQuery(className: "PostEvent")
eventsPostedQuery.whereKey("CityName", equalTo: self.usersLocation)
eventsPostedQuery.orderByDescending("createdAt")
eventsPostedQuery.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
if let events = objects {
for event in events {
self.imageFiles.append(event["imageFile"] as! PFFile)
self.eventInfo.append(event["eventInfo"] as! String)
self.usernames.append(self.users[event["userId"] as! String]!)
self.tableView.reloadData()
}
}
})
})
}
Upvotes: 1
Views: 281
Reputation: 15321
You should call
refreshPosts()
from inside the else block of this completion block:
CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) -> Void in
if error != nil {
print(error)
} else {
let p = placemarks?.first // ".first" returns the first element in the collection, or nil if its empty
// this code above will equal the first element in the placemarks array
let city = p?.locality != nil ? p?.locality : ""
let state = p?.administrativeArea != nil ? p?.administrativeArea : ""
self.navigationBar.title = ("\(city!), \(state!)")
self.usersLocation = ("\(city!), \(state!)")
self.locationManager.stopUpdatingLocation()
print(self.usersLocation)
}
}
As in only update the post if the reverse geocoder is finished and didn't return an error.
Upvotes: 2