0

In my ViewController I have a label which displays the name of a club selected in the previous ViewController. I now need to create a query from my parse.com class to retrieve all information on the object that matches the club name displayed as a label. I know how to successfully query parse but I'm finding it hard to find a way to match the query with the label String seeing as the label String can be different depending on what club was selected in the previous view.

Code:

import UIKit
import Parse

class MenuController: UIViewController {

    @IBOutlet weak var clubLabel: UILabel!

    var clubName = String()

    override func viewDidLoad() {
        super.viewDidLoad()

        clubLabel.text = clubName
    }
}

Previous View already queried parse to populate map with club annotations like so:

        let annotationQuery = PFQuery(className: "Clubs")
        annotationQuery.findObjectsInBackgroundWithBlock{
        (clubs, error) -> Void in
        if error == nil {
            // The find succeeded.
            print("Successful query for annotations")
            // Do something with the found objects
            let myClubs = clubs! as [PFObject]
            for club in myClubs {

                //data for annotation
                let annotation = MKPointAnnotation()
                 let place = club["location"] as? PFGeoPoint
                let clubName = club["clubName"] as? String
                let stadiumName = club["stadium"] as? String
                annotation.title = clubName
                annotation.subtitle = stadiumName
                annotation.coordinate = CLLocationCoordinate2DMake(place!.latitude,place!.longitude)

                //add annotations
                self.mapView.addAnnotation(annotation)
ShaneN
  • 7
  • 8
  • but you already had the object in order to populate the label so what did you do with it? use the existing object... – Wain Feb 19 '16 at 12:14
  • what is the more info? how did you get the clubs and why don't those objects hold the data (or relationships to the data) you need ? – Wain Feb 19 '16 at 13:18
  • How is your "club label array" from the previous view populated ? If you got it from Parse, why don't you keep the object ? – Michaël Azevedo Feb 19 '16 at 13:24

2 Answers2

0

Simply add a whereKey to your PFQuery.

annotationQuery.whereKey(clubName, equalTo: "clubName")

Hope this helps.

Pranav Wadhwa
  • 7,666
  • 6
  • 39
  • 61
0

Instead of using default MKPointAnnotation, we will use custom annotations for easier understanding.


First we will create a class ClubAnnotation conforming to the MKAnnotation protocol in a different file.

import UIKit
import MapKit
import Parse

class ClubAnnotation: NSObject, MKAnnotation {

    //MARK: - Instance properties

    let club:PFObject

    //MARK: - Init methods

    init(club:PFObject) {
        self.club = club
    }

    //MARK: - MKAnnotation protocol conformance

    var title: String? { get {       
        return club["clubName"]
        }
    }

    var subtitle: String? { get {
        club["stadium"]
        }
    }

    var coordinate: CLLocationCoordinate2D { get {        
        return CLLocationCoordinate2D(latitude:  club["location"].latitude, longitude: club["location"].longitude)
        }
    }
}

I let you handle the error if the fields "stadium", "clubName" or "location" are empty for a Club object, so you can decide how do display it.


Then, in your class including the MKMapView object (and probably conforming to MKMapViewDelegate protocol), replace the handling of your query result :

let annotationQuery = PFQuery(className: "Clubs")
annotationQuery.findObjectsInBackgroundWithBlock{
    (clubs, error) -> Void in
    if let clubs = clubs where error == nil {
        // The find succeeded.
        print("Successful query for annotations")
        for club in clubs  {
            self.mapView.addAnnotation(ClubAnnotation(club:club))
        }
    } else {
        // Handle the error
    }
}

You realize that i don't have to manually set title, subtitle and coordinate properties since your ClubAnnotation object returns it directly according to it's implementation of MKAnnotation protocol.

Still in this class, add a selectedClub property. This property will be used to save the club from the annotation selected and will be passed to the pushed view controller.

var selectedClub:PFobject!

In your calloutAccessoryControlTapped delegate method, you can then get your PFObject from the annotation, and pass it to a new viewController of do everything you want with it, without having to query it from Parse :

    func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {

    mapView.deselectAnnotation(view.annotation, animated: true)

    if let annotation = view.annotation as? ClubAnnotation {            
       clubSelected = annotation.club
    }
}

You now have saved the club object from your custom annotation class, and you have a reference to it. If you want to present or push a new view controller with more information about this club, just override prepareForSegue and set this value to the pushed/presented view controller. You don't need to query other fields of your club since they are all loaded according to your Parse request.

Michaël Azevedo
  • 3,874
  • 7
  • 31
  • 45
  • `clubSelected` should be a class property and set it, instead of a local variable. You still need prepareforsegue method in order to pass the `clubSelected` variable to the new view controller. If you need parse data other than club, you will need to do other requests. – Michaël Azevedo Feb 26 '16 at 12:45
  • I'll edit my answer for more clarity, wait a little ;) – Michaël Azevedo Feb 26 '16 at 13:01