Matty
Matty

Reputation: 343

iOS Simulator and reverseGeocodeLocation

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

Answers (1)

beyowulf
beyowulf

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

Related Questions