ALTVisual
ALTVisual

Reputation: 116

Swift add array of objects as map annotations

I have an array of objects that I'm getting from my CloudKit database that is being returned as an array of location() objects.

location() is defined as...

class location {
var title: String?
var subtitle: String?
var coordinate: CLLocationCoordinate2D
}

I need to be able to create annotations from the array, but I can't seem to wrap my head around it.

When I try to pass the array as an MKAnnotation it says it doesn't conform properly, though it does have all of the data needed to conform, I just can't figure out how to get it out of the array and into annotations.

My class

class Locations: NSObject, MKAnnotation {
var title: String?
var subtitle: String?
var coordinate: CLLocationCoordinate2D

override init()
{
    self.title = "Test Title"
    self.subtitle = "Test Subtitle"
    self.coordinate = CLLocationCoordinate2D.init()
}
}

in my view controller "objects" is created... var objects = [Locations]()

This is the part of the fuction that I use to get the data from CK and store it in an object ...

for locations in results! {
                let newLocation = Locations()
                newLocation.title = ckData["Name"] as? String
                newHaunted.subtitle = ckData["Subtitle"] as? String
                let location = ckData["Location"] as! CLLocation

                self.objects.append(newLocation)

Lastly I call a function in ViewDidAppear that has the following code...

    let locationsToAdd = objects
    mapView.showAnnotations(locationsToAdd, animated: true)

At this point I'm getting an empty array from objects. If I try to use Locations() instead of objects it says it can't convert it to MKAnnotation, which it should already be.

The following is the function that I use to get the data from CloudKit.

func getRecordsFromCloud() {
// Fetch data using Convenience API
let cloudContainer = CKContainer.defaultContainer()
let publicData = cloudContainer.publicCloudDatabase
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Locations", predicate: predicate)

publicData.performQuery(query, inZoneWithID: nil) { results, error in
    if error == nil { //no error
        for locations in results! {
            let newLocation = Locations()
            newLocation.title = locations["Name"] as? String
            newLocation.subtitle = locations["Subtitle"] as? String
            let location = locations["Location"] as! CLLocation

            let newLocationCoords: CLLocationCoordinate2D = location.coordinate
            newLocation.coordinate = newLocation
            self.objects.append(newHaunted)


            dispatch_async(dispatch_get_main_queue(), {() -> Void in
                self.locationsTable.reloadData()
            })
        }
    }
    else {
        print(error)
    }
}
}

After this I call getRecordsFromCloud() in viewDidLoad.

Upvotes: 0

Views: 1832

Answers (3)

Rob
Rob

Reputation: 438092

You can define your Location class like so:

class Location: NSObject, MKAnnotation {
    let title: String?
    let subtitle: String?
    var coordinate: CLLocationCoordinate2D

    init(title: String?, subtitle: String?, coordinate: CLLocationCoordinate2D) {
        self.title = title
        self.subtitle = subtitle
        self.coordinate = coordinate

        super.init()
    }
}

Then you can add annotations to your map like so:

let annotation = Location(title: name, subtitle: locality, coordinate: coordinate)
mapView.addAnnotation(annotation)

Clearly, you'd set the title and subtitle however you want, but hopefully this illustrates the idea.

Upvotes: 0

nielsbot
nielsbot

Reputation: 16031

You can use @Jelly's suggestion or just declarare that your class conforms (implements) MKAnnotation with an extension:

extension Location : MKAnnotation 
{
}

Upvotes: 1

Jelly
Jelly

Reputation: 4532

To specify that your class conforms to a certain protocol you must use class ClassName: ProtocolName notation. So in your case you should replace class location with class location: MKAnnotation to tell the compiler that your class conforms to MKAnnotation protocol.

Upvotes: 1

Related Questions