On Xcode 14, Apple added Hashable conformance to CMTime
and CMTimeRange
to iOS16 only. I'm trying to make it Hashable for all iOS versions, because we have many Hashable structs that contain CMTime
, and they depend on CMTime
to be Hashable as well.
Until now, we had an extension on CMTime
that make it conform to Hashable, but on Xcode 14 this extension causes compilation error with this description:
Protocol 'Hashable' requires 'hashValue' to be available in iOS 14.0.0 and newer
If I implement hashValue
like this:
public var hashValue: Int {
var hasher = Hasher()
hash(into: &hasher)
return hasher.finalize()
}
It compile and works, but I'm not sure if it's safe because hashValue
is deprecated so I'm not sure I understand why it's needed (only hash(into:)
should be implemented for Hashable conformance these days).
Can anyone shed some light about whether this solution is safe, or have any other solution?
Another idea that I tried:
I added this extension on CMTime
:
extension CMTime {
struct Hashed: Hashable {
private let time: CMTime
init(time: CMTime) {
self.time = time
}
public func hash(into hasher: inout Hasher) {
// pre iOS16 hash computation goes here.
}
}
func asHashable() -> Hashed {
return Hashed(time: self)
}
}
Then I changed all Hashable structs that contain CMTime
from this:
struct Foo: Hashable {
let time: CMTime
let string: String
}
to this:
struct Foo: Hashable {
let time: CMTime
let string: String
func hash(into hasher: inout Hasher) {
if #available(iOS 16, *) {
hasher.combine(self.time)
} else {
hasher.combine(self.time.asHashable())
}
hasher.combine(self.string)
}
}
I'm not a fan of this since it will make a LOT of changes across the code