Reputation: 116
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
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
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
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