【问题标题】:Swift: CoreData Conforming to MKAnnotationSwift:符合 MKAnnotation 的 CoreData
【发布时间】:2018-04-21 08:14:13
【问题描述】:

我正在尝试实现我的自定义 CoreData Carpark 实体以符合 MKAnnotation 就像我们如何使 class 对象符合 MKAnnotation 一样。

我根据以下帖子调整了我的实现:thisthis

到目前为止我的实现:

//At Carpark+CoreDataClass.swift
import Foundation
import CoreData
import Mapkit

@objc(Carpark)
public class Carpark: NSManagedObject, MKAnnotation {

    var coordinate: CLLocationCoordinate2D {
        return CLLocationCoordinate2D(latitude: Double(self.lat), longitude: Double(self.long))
    }

    var title: String {
        return self.carparkName
    }

}

//At Carpark+CoreDataProperties.swift
import Foundation
import CoreData
import Mapkit

extension Carpark {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Carpark> {
        return NSFetchRequest<Carpark>(entityName: "Carpark")
    }

    @NSManaged public var carparkName: String?
    @NSManaged public var sundayAndPublicHolRate: String?
    @NSManaged public var saturdayRate: String?
    @NSManaged public var weekdayRate1: String?
    @NSManaged public var weekdayRate2: String?
    @NSManaged public var lat: Double
    @NSManaged public var long: Double
}

//At VC where I addAnnotations
var allCarparks: [Carpark]?
var nearbyCarparks = [Carpark]()
var searchedCarpark: Carpark!

func filterCarparksWithinRadius() {

    var allAnnotations = [Carpark]()

    let searchRadius = UserDefaults.standard.object(forKey: Constants.UserDefaults.SearchRadius) as! Double
    let searchedCarparkLocation = CLLocation(latitude: searchedCarpark.lat, longitude: searchedCarpark.long)

    allCarparks?.forEach({ (carpark) in
        let carparkLocation = CLLocation(latitude: carpark.lat, longitude: carpark.long)
        let distance = carparkLocation.distance(from: searchedCarparkLocation)

        if distance <= searchRadius && distance != 0 {
            nearbyCarparks.append(carpark)
            allAnnotations.append(carpark)
        }
    })

    allAnnotations.append(searchedCarpark)
    mapView.addAnnotations(allAnnotations as! [MKAnnotation]) //Problem here

    let zoomCoordinate = CLLocationCoordinate2D(latitude: searchedCarpark.lat, longitude: searchedCarpark.long)
    zoomToLocation(coordinate: zoomCoordinate)

}

上面的代码会抛出错误:

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[停车场坐标]: 无法识别的选择器发送到实例 0x60400009e690'

有没有一种方法可以让 CoreData 符合 MKAnnotation,就像我们可以为类对象做的那样?类似这样的东西?:

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

    var carparkName: String?
    var lat: Double?
    var long: Double?

    init(carparkName: String?, lat: Double?, long: Double?) {
        self.title = carparkName
        self.carparkName = carparkName
        self.lat = lat
        self.long = long
        self.coordinate = CLLocationCoordinate2DMake(lat!, long!)
    }
}

非常感谢任何建议,谢谢。

【问题讨论】:

  • 您为什么按照问题中的方式实现坐标,而不是在your linked question 的答案中声明的那样?
  • @JoakimDanielson 因为我没有设置坐标参数,只有纬度和经度。添加get{} 也给出了相同的错误消息。
  • 好的,我以为你需要 get 和 set 但不需要仔细观察它。
  • 调用 addAnnotations 时不需要对 allAnnotations 进行类型转换
  • @JoakimDanielson 我必须这样做。否则它会说Cannot convert value of type [Carpark] to expected argument type of [MKAnnotation]

标签: swift


【解决方案1】:

您需要将您的坐标属性公开,以便在您的模块之外看到(在 MapView 框架之外)。也许这也是您需要转换数组的原因。

这是我的定义

public class Location: NSManagedObject, MKAnnotation {

  public var coordinate: CLLocationCoordinate2D {
    return CLLocationCoordinate2DMake(latitude, longitude)
  }
  //....more code
}

在我的视图控制器中我有一个属性

 var locations = [Location]()

然后我进入它并像这样添加到地图视图中

private func updateLocations() {
    mapView.removeAnnotations(locations)

    let entity = Location.entity()
    let fetchRequest = NSFetchRequest<Location>()
    fetchRequest.entity = entity
    do {
        locations = try managedObjectContext.fetch(fetchRequest)
    } catch {
        fatalCoreDataError(error)
    }
    mapView.addAnnotations(locations)
}

【讨论】:

  • 您好,我尝试了您的解决方案,但仍然给出了相同的错误消息。
  • 您能否将完整的 func filterCarparksWithinRadius() 添加到您的问题中?
  • 我没有看到您的代码有任何问题。您是否尝试过自己在代码中访问坐标属性?否则,也许您可​​以在该函数中添加一些打印语句,例如打印 carpark.coordinate 和 searchedCarpark.coordinate
  • 我试图访问坐标属性,但不知何故无法访问。它说Value of type 'Carpark' has no member 'coordinate'。这真的是我最糟糕的噩梦。
  • 所以代码编译但 Carpark 行为不端。远射,但也许 Xcode 搞砸了,尝试通过选择 Product->Clean 来清理项目,也许还可以重新启动 Xcode。更改 NSManagedObject 子类后,我遇到了 Xcode 问题
【解决方案2】:

我设法通过将 Codegen 设置为 Manual/None 来解决它,然后可以访问属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多