Search code examples
swifthashableswift5

Swift: 'Hashable.hashValue' is deprecated as a protocol requirement;


I've been facing following issue (it's just a warning) with my iOS project.

'Hashable.hashValue' is deprecated as a protocol requirement; conform type 'ActiveType' to 'Hashable' by implementing 'hash(into:)' instead

  • Xcode 10.2
  • Swift 5

Source Code:

public enum ActiveType {
    case mention
    case hashtag
    case url
    case custom(pattern: String)

    var pattern: String {
        switch self {
        case .mention: return RegexParser.mentionPattern
        case .hashtag: return RegexParser.hashtagPattern
        case .url: return RegexParser.urlPattern
        case .custom(let regex): return regex
        }
    }
}

extension ActiveType: Hashable, Equatable {
    public var hashValue: Int {
        switch self {
        case .mention: return -1
        case .hashtag: return -2
        case .url: return -3
        case .custom(let regex): return regex.hashValue
        }
    }
}

enter image description here

Any better solution? The warning itself suggesting me to implement 'hash(into:)' but I don't know, how?

Reference: ActiveLabel


Solution

  • As the warning says, now you should implement the hash(into:) function instead.

    func hash(into hasher: inout Hasher) {
        switch self {
        case .mention: hasher.combine(-1)
        case .hashtag: hasher.combine(-2)
        case .url: hasher.combine(-3)
        case .custom(let regex): hasher.combine(regex) // assuming regex is a string, that already conforms to hashable
        }
    }
    

    It would be even better (in case of enums and struct) to remove the custom hash(into:) implementation (unless you need a specific implementation) as the compiler will automatically synthesize it for you.

    Just make your enum conforming to it:

    public enum ActiveType: Hashable {
        case mention
        case hashtag
        case url
        case custom(pattern: String)
    
        var pattern: String {
            switch self {
            case .mention: return RegexParser.mentionPattern
            case .hashtag: return RegexParser.hashtagPattern
            case .url: return RegexParser.urlPattern
            case .custom(let regex): return regex
            }
        }
    }