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
EDIT 2:
The code below works with iOS 16 simulator, but crashes with iOS 15 and lower. Odd, since it compiles.
My suggestion is to implement an extension and make it available only for iOS 15 and lower:
As for why
hashValue
is still needed, I agree it's not suppose to be there. Might be an XCode false alarm, the error is really confusing. Notice Apple doesn't say when it was deprecated, and also it was deprecated as a requirement, it's still there behind the scenes, I'm guessing: https://developer.apple.com/documentation/swift/hashable/hashvalueEDIT 1:
CMTime
already conforms toHashable
. Tested with iOS 13, 14, 15 and 16. I don't think you need your extension.