2

I am creating a map type application, once the user presses a button a pin is dropped to the map at their current location. I am trying to save map pins to an array so that they remain once the app is closed.

Here is my code so far:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations.last
    let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.004, longitudeDelta: 0.004))
    self.placesMap?.setRegion(region, animated: true)
    self.locationManager.stopUpdatingLocation()
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
    print("Error code: " + error.localizedDescription)
}

// Add button action
@IBAction func addButton(sender: AnyObject) {
    let annotation = MKPointAnnotation()
    annotation.coordinate = CLLocationCoordinate2D(latitude: self.placesMap.userLocation.coordinate.latitude, longitude: self.placesMap.userLocation.coordinate.longitude)
    self.placesMap.addAnnotation(annotation)
    self.locationManager.startUpdatingLocation()
}

How can I save the pin information to an array which is reloaded each time the app is opened?

Hugo Alonso
  • 6,684
  • 2
  • 34
  • 65
Oscar
  • 511
  • 2
  • 10
  • 25

1 Answers1

2

If you want to persist data between application launches, and you are not storing much data, the easy way is to use NSUserDefaults. You can do this by saying something like:

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations.last
    let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.004, longitudeDelta: 0.004))
    self.placesMap?.setRegion(region, animated: true)
    self.locationManager.stopUpdatingLocation()



     let locationDictionary:[String:Double] = ["latitude":center.latitude,"longitude":center.longitude]
     var locationArray = [[String:Double]]()
     if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") != nil {
        locationArray = NSUserDefaults.standardUserDefaults().objectForKey("locationArray") as! [[String:Double]]

    }

    locationArray.append(locationDictionary)

    NSUserDefaults.standardUserDefaults().setObject(locationArray, forKey: "locationArray")
    NSUserDefaults.standardUserDefaults().synchronize()
    }

You will then need to read out those locations when the app relaunches. You can do that in viewDidLoad. For example:

override func viewDidLoad(){
    super.viewDidLoad()
    if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") != nil {
    for dictionary in NSUserDefaults.standardUserDefaults().objectForKey("locationArray") as! [[String:Double]]{
        let center = CLLocationCoordinate2D(latitude: dictionary["latitude"]!, longitude: dictionary["longitude"]!)
        let annotation = MKPointAnnotation()
        annotation.coordinate = center
        self.placesMap.addAnnotation(annotation)
    }
  }
}

If you want to remove all of the stored locations you can say something like:

    func removeStoredLocations(){
     NSUserDefaults.standardUserDefaults().removeObjectForKey("locationArray")
     NSUserDefaults.standardUserDefaults().synchronize()
    }
beyowulf
  • 15,101
  • 2
  • 34
  • 40
  • Thanks a lot for your answer, I appreciate it! I tried what you suggested but still the map pins disappear once the application is relaunched :( any ideas? – Oscar Mar 18 '16 at 17:54
  • In viewDidLoad place `print(center)` after `let center = CLLocationCoordinate2D(latitude: dictionary["latitude"]!, longitude: dictionary["longitude"]!)` Let me know what it says in the console. – beyowulf Mar 18 '16 at 18:32
  • Tried it but nothing gets printed to the console :( I really dont know why. Is there anything else I can try to get this to work? – Oscar Mar 18 '16 at 19:05
  • Put a breakpoint or print something on line `locationArray.append(locationDictionary)` – beyowulf Mar 18 '16 at 19:07
  • Now I get lots of CLLocationCoordinate2D info, several rows of latitude and longitude values like: "CLLocationCoordinate2D(latitude: 51.4012167882653, longitude: -0.122878281399722)" which is the last line printed – Oscar Mar 18 '16 at 19:21
  • Are the regions showing up on the map? If not, it's just a matter of taking those coordinate, creating a region, and setting those regions on the map view. I don't know when your map view is added to the view hierarchy, so you may need to do that later in your view controller's lifecycle. – beyowulf Mar 18 '16 at 19:30
  • No, the pins arent displayed when I reopen the map still. I want the red pins to keep their place until the user wishes to reset them. How would I go about creating a pin from the stored locations? The map view is on the main view controller, first position in view hierarchy – Oscar Mar 18 '16 at 19:36
  • Awesome! This shows all the pins that I had previously stored up to this point :D Is there a simple way to reset the array which contains the pins? I want to ideally have a reset all pins button. Thanks so much for your help – Oscar Mar 18 '16 at 19:51
  • Thanks again :) However now when I press the the remove pins button the app crashes. I get this error in the terminal: "2016-03-18 20:40:44.884 PlacesFinal[4287:2569682] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key resetMemories.'" The class is set correctly when I check it, so I dont know why this is happening :( – Oscar Mar 18 '16 at 20:44
  • My app displays the reset pins button on a popover window, this window is displayed over the mapview. When I click the button to show the popover, the app crashes. – Oscar Mar 18 '16 at 20:58
  • Where are you using a tableView? How are you loading the data? – beyowulf Mar 18 '16 at 21:15
  • tableview is a table of buttons which include the reset pins button displayed via a popover segue, I have a seperate class for the tableview called "Popover", I also get a notice saying "Unknown class Popover in Interface Builder file." so I think maybe it isnt seeing the class file? I am not sure how to fix this – Oscar Mar 18 '16 at 21:17
  • Is the class private? – beyowulf Mar 18 '16 at 21:22
  • No it isnt private – Oscar Mar 18 '16 at 21:24
  • Are you using xibs or storyboards? – beyowulf Mar 18 '16 at 21:59
  • I am using Storyboards – Oscar Mar 18 '16 at 23:13
  • Hi, I managed to avoid this error. The button works fine but the code to remove pins still does nothing. Is there any way you could help me further with this to get the reset pins button functioning? I have posted a new question about this – Oscar Mar 26 '16 at 15:48