0

I have a searchController, when I try to delete the text in searchController it crash the message is.

supplied identifiers are not unique

I try to fix it with hasher function like this and make my model Hashable, and Equatable. but still not fix the problem, please help. this is my code, if there is something not clear in my code. feel free to mention me I will update it :)

    struct PhotosResults: Decodable {
    var total, totalPages: Int
    var results: [PhotoItem]
}

// MARK: - Result
struct PhotoItem: Decodable {
    var id: String
    var createdAt: String
    var width, height: Int
    var color: String
    var likes: Int
    var likedByUser: Bool
    var description: String?
    var user: User
    var urls: Urls
}

extension PhotoItem: Hashable, Equatable {
    static func == (lhs: PhotoItem, rhs: PhotoItem) -> Bool {
        return lhs.id == rhs.id
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

// MARK: - Urls
struct Urls: Decodable {
    var raw, full, regular, small: String
    var thumb: String
}
// MARK: - User
struct User: Decodable {
    var id, username, name, firstName: String
    var lastName, instagramUsername, twitterUsername: String?
    var portfolioUrl: String?
    var profileImage: ProfileImage
}

extension User: Hashable, Equatable {
    static func == (lhs: User, rhs: User) -> Bool {
        return lhs.id == rhs.id
    }

    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

// MARK: - ProfileImage
struct ProfileImage: Decodable {
    var small, medium, large: String
}

ferryawijayanto
  • 569
  • 4
  • 18
  • A hashing function won't help since the hash of a value is consistent. If your `id` strings aren't unique then the hash of those string won't be unique. Either ensure that the ids are unique or assign some other value, such as a UUID to id – Paulw11 May 20 '20 at 13:41
  • but how @Paulw11? the data come from API when I try to store the id into UUID, it failed to parse the JSON data – ferryawijayanto May 20 '20 at 13:58
  • You need to provide more information; are the identifiers from your api not unique? If so then you need to not use them and use your own identifier. If they are unique then you have a problem in code not shown. – Paulw11 May 20 '20 at 20:30

2 Answers2

1

Base on Apple Documentation:

Hash values are not guaranteed to be equal across different executions of your program. Do not save hash values to use during a future execution.

Although you have conformed to hashable somehow it is possible that two objects have the same id and in this situation, you will get an error so in order to make sure all objects are unique you must add a UUID to your desired struct For Example the PhotoItem should look like this:

struct PhotoItem: Decodable {
      let uuid = UUID()
      var id: String
      var createdAt: String
      var width, height: Int
      var color: String
      var likes: Int
      var likedByUser: Bool
      var description: String?
      var user: User
      var urls: Urls
    }
    extension PhotoItem: Hashable {
        func hash(into hasher: inout Hasher) {
            hasher.combine(uuid)
        }
        static func ==(lhs: PhotoItem, rhs: PhotoItem) -> Bool {
                return lhs.uuid == rhs.uuid
        }
    }
     

you can use this solution for other structs. Hashable conforms to Equatable by default so you don't need to conform to it again.

0

Note: I was accidentally loading my data twice. I only got this when I scrolled back over the cell containing the id's, not first collectionview snapshot apply. So if yours only is doing it sometimes, make sure you are only loading your cells on the initial load.

devjme
  • 684
  • 6
  • 12