swiftmapkitcllocation

How to make CLLocationCoordinate2D conform to Equatable protocol


There have been several discussions about making CLLocationCoordinate2D conform to Equatable protocol, and there seem to be several ways to do.

What I'm wondering is why CLLocation does Equatable protocol, and contains CLLocationCoordinate2D, but CLLocationCoordinate2D itself is not.

My first try at a solution was to look at putting CLLocationCoordinate2D into CLLocation as a placeholder and do the comparison, but CLLocationCoordinate2D isn't equal to itself because CLLocation is forced to compare the timestamp property.

        let here = CLLocationCoordinate2D(latitude: 0, longitude: 0)
        let there = CLLocationCoordinate2D(latitude: 0, longitude: 0)

        func compare (here: CLLocationCoordinate2D, there: CLLocationCoordinate2D) {
            let overHere = CLLocation(latitude: here.latitude, longitude: here.longitude)
            let overThere = CLLocation(latitude: there.latitude, longitude: there.longitude)
            
            if overHere == overThere {
                print ("They are the same")
            } else {
                print ("probably not the same timesamps")
            }
        }
        compare (here: here, there: there)

https://developer.apple.com/documentation/corelocation/cllocation

(NOTE: This obviously doesn't work and further hacking of CLLocation is probably undesirable, but...)

What I'm wondering is why, because depending on the perceived intent, it suggests that some choices about solutions would make more sense than others...


Solution

  • What I'm wondering is why CLLocation does Equatable protocol, and contains CLLocationCoordinate2D, but CLLocationCoordinate2D itself is not

    Because CLLocation is an NSObject. It comes from the Objective-C world, where isEqual can be defined without regard to any particular features of the object's properties. Equatable, however, is a purely Swift concept. To Swift, all NSObjects are Equatable — because all NSObjects implement or inherit isEqual, and so Swift Equatable simply uses isEqual for NSObjects. So the fact that Swift regards CLLocation as Equatable without regard to whether CLLocationCoordinate2D is Equatable is perfectly reasonable.

    Now, as for the question of how to declare CLLocationCoordinate2D as Equatable, I think the considerations you need to worry about are very well covered by the various answers to How can I compare CLLocationCoordinate2D. In particular you need to ask yourself why you are comparing two CLLocationCoordinate2D structs and what circumstances would have to inhere in order for you to consider them "equal" for your purposes. Then you just program that into an implementation of ==.