Тип аргумента не соответствует ожидаемому типу MKAnnotation - PullRequest
0 голосов
/ 06 августа 2020

Я использую эту статью как ссылку https://www.thorntech.com/2016/01/how-to-search-for-location-using-apples-mapkit/ для создания своего приложения. Я пытаюсь использовать matchItem, когда searchBarText равны, а затем добавлять в matchingItems. В настоящее время у меня есть сообщение об ошибке, что тип аргумента ServiceLocation не соответствует ожидаемому типу MKAnnotation, что означает, что мне нужно изменить тип переменной для соответствияItem. Я не уверен, какие типы переменных лучше всего использовать, если вы хотите сохранить ServiceLocation позже для использования в качестве MapView. Есть предложения?

var matchingItems = [MKAnnotation]()
        var handleMapSearchDelegate:HandleMapSearch? = nil
    var allServiceLocations : [ServiceLocation] = []
        
        func updateSearchResults(for searchController: UISearchController) {
            
           
            matchingItems = []
            guard let mapView = mapView,
                let searchBarText = searchController.searchBar.text else { return }
            for location in allServiceLocations{
                if(location.locationName == searchBarText){
                   matchingItems.append(location)
                    
                }
            }

ServiceLocation.swift

struct ServiceLocation: Codable {
    var id: Int
    var locationType : LocationType
    var locationName: String
    var latitude: Double
    var longitude: Double
    var active: Bool
    var home : Bool
    var numAvailableChargers : Int
    var acronym : String?
    var eta: Int?
}

Ответы [ 2 ]

1 голос
/ 06 августа 2020

Несколько вариантов:

  1. Вы можете сделать ServiceLocation аннотацией, сделав его подклассом NSObject, который соответствует MKAnnotation. Итак, сначала сделайте его классом:

     class ServiceLocation: NSObject, Codable {
         var id: Int
         var locationType: LocationType
         var locationName: String
         var latitude: Double
         var longitude: Double
         var active: Bool
         var home: Bool
         var numAvailableChargers: Int
         var acronym: String?
         var eta: Int?
    
         init(id: Int, locationType: LocationType, locationName: String, latitude: Double, longitude: Double, active: Bool, home: Bool, numAvailableChargers: Int, acronym: String?, eta: Int?) {
             self.id = id
             self.locationType = locationType
             self.locationName = locationName
             self.latitude = latitude
             self.longitude = longitude
             self.active = active
             self.home = home
             self.numAvailableChargers = numAvailableChargers
             self.acronym = acronym
             self.eta = eta
    
             super.init()
         }
     }
    

    Во-вторых, добавьте MKAnnotation соответствие протокола с несколькими вычисленными свойствами:

     extension ServiceLocation: MKAnnotation {
         var coordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: latitude, longitude: longitude) }
         var title: String? { locationName }
         var subtitle: String? { "\(numAvailableChargers) chargers" }
     }
    
  2. В качестве альтернативы вы можете создайте класс аннотации, в качестве свойства которого будет указано ваше исходное местоположение службы struct:

     class ServiceLocationAnnotation: NSObject, MKAnnotation {
         var coordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: serviceLocation.latitude, longitude: serviceLocation.longitude) }
         var title: String? { serviceLocation.locationName }
         var subtitle: String? { "\(serviceLocation.numAvailableChargers) chargers" }
    
         let serviceLocation: ServiceLocation
    
         init(serviceLocation: ServiceLocation) {
             self.serviceLocation = serviceLocation
             super.init()
         }
     }
    

    Есть и другие варианты этой идеи, но главное - просто создать аннотацию, в которой ваш struct как свойство, а затем, вместо добавления ServiceLocation к аннотациям карты, добавьте ServiceLocationAnnotation.

Очевидно, сделайте субтитры такими, какими хотите, но, надеюсь, это иллюстрирует идея.

1 голос
/ 06 августа 2020

Итак, компилятор сообщает вам, что у вас есть массив MKAnnotation, но вы пытаетесь вставить в него ServiceLocation, который не связан с типом. Поскольку Swift строго типизирован, это просто недопустимо (квадратный колышек - ситуация с круглым отверстием).

Что вам нужно сделать, так это сопоставить ваш ServiceLocation с MKAnnotation, например, так:

var matchingItems = [MKAnnotation]()
var handleMapSearchDelegate:HandleMapSearch? = nil
var allServiceLocations : [ServiceLocation] = []
        
func updateSearchResults(for searchController: UISearchController) {
      guard let mapView = mapView,
            let searchBarText = searchController.searchBar.text else { return }

        matchingItems = allServiceLocations.filter({ $0.locationName == searchBarText })
        .map({ 
            let annotation = MKPointAnnotation()
            annotation.coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(exactly: $0.latitude)!, longitude: CLLocationDegrees(exactly: $0.longitude)!)
            annotation.title = $0.locationName
            annotation.subtitle = $0.locationType
        return annotation
       })
}
...