I am trying to learn Xcode using iOS 14 Programming for Beginners (Packt Pub).
I am now working on the part that adds the pins to the MapView, but when I run the app the map button is unresponsive (Runtime error).
I get the following message in the Debug area:
I get a build error on the final line if I do not apply the fix, which adds the as! MKAnnotation. Is the error in the .plist or does the code need altering? Please can you help?
Here is the full code for the swift file:
Here is the RestaurantItem.swift code:
Here is the MapDataManager.swift code:
Please can anybody help?
I am now working on the part that adds the pins to the MapView, but when I run the app the map button is unresponsive (Runtime error).
I get the following message in the Debug area:
I'm sure that this message means a lot to you experts, but as a beginner I haven't a clue! The runtime error is in this func, in the final line:__2021-07-25 16:08:23.919240+0100 EatOut[1420:21167] Metal API Validation Enabled
Could not cast value of type 'Swift.Array<EatOut.RestaurantItem>' (0x1c31e3588) to '__C.MKAnnotation' (0x1c31e3888).
2021-07-25 16:08:24.003987+0100 EatOut[1420:21167] Could not cast value of type 'Swift.Array<EatOut.RestaurantItem>' (0x1c31e3588) to '__C.MKAnnotation' (0x1c31e3888). Could not cast value of type 'Swift.Array<EatOut.RestaurantItem>' (0x1c31e3588) to '
Code:
func addMap(_ annontations: [RestaurantItem]) {
mapView.setRegion(manager.currentRegion(latDelta: 0.5, longDelta: 0.5), animated: true)
mapView.addAnnotation(manager.annotations as! MKAnnotation)
Here is the full code for the swift file:
Code:
/ MapViewController.swift
// EatOut
//
// Created by Tony Hudson on 15/07/2021.
//
import UIKit
import MapKit
class MapViewController: UIViewController, MKMapViewDelegate {
let manager = MapDataManager()
var selectedRestaurant: RestaurantItem?
@IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
initialise()
func initialise() {
manager.fetch { (annotations) in addMap(annotations)
}
}
func addMap(_ annontations: [RestaurantItem]) {
mapView.setRegion(manager.currentRegion(latDelta: 0.5, longDelta: 0.5), animated: true)
mapView.addAnnotation(manager.annotations as! MKAnnotation)
}
}
}
Code:
// RestaurantItem.swift
// EatOut
//
// Created by Tony Hudson on 12/07/2021.
//
import UIKit
import MapKit
class RestaurantItem: NSObject, MKAnnotation {
var name: String?
var cuisines: [String] = []
var lat: Double?
var long: Double?
var address: String?
var postalCode: String?
var state: String?
var imageURL: String?
var restaurantID: Int?
init (dict: [String: AnyObject]) {
if let lat = dict["lat"] as? Double { self.lat = lat}
if let long = dict["long"] as? Double { self.long = long}
if let name = dict["name"] as? String { self.name = name}
if let cuisines = dict["cuisines"] as? [String] { self.cuisines = cuisines}
if let address = dict["address"] as? String { self.address = address}
if let postalCode = dict["postalCode"] as? String { self.postalCode = postalCode}
if let state = dict["state"] as? String { self.state = state}
if let image = dict["imageURL"] as? String { self.imageURL = image}
if let id = dict["id"] as? Int { self.restaurantID = id}
}
var coordinate: CLLocationCoordinate2D {
guard let lat = lat, let long = long else {
return CLLocationCoordinate2D()
}
return CLLocationCoordinate2D(latitude: lat, longitude: long)
}
var title: String? {
return name
}
var subtitle: String? {
if cuisines.isEmpty { return ""}
else if cuisines.count == 1 { return cuisines.first}
else { return cuisines.joined(separator: ", ")
}
}
}
Code:
// MapDataManager.swift
// EatOut
//
// Created by Tony Hudson on 12/07/2021.
//
import Foundation
import MapKit
class MapDataManager: DataManager {
fileprivate var items: [RestaurantItem] = []
var annotations: [RestaurantItem] {
return items
}
func fetch(completion: (_ annotations: [RestaurantItem]) -> ()){
if items.count > 0 { items.removeAll() }
for data in load(file: "MapLocations") {
items.append(RestaurantItem(dict: data))
}
completion(items)
}
func currentRegion(latDelta: CLLocationDegrees, longDelta: CLLocationDegrees) -> MKCoordinateRegion {
guard let item = items.first else {
return MKCoordinateRegion()
}
let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: longDelta)
return MKCoordinateRegion(center: item.coordinate, span: span)
}
}