How to fetch distinct results based on 1 property in Core Data but still fetch all properties?

My goal is to fetch distinct SearchHistoryItemModel.

My expected result:

[
  {
    id: "1", -> it's a String
    keyword: "abcd", -> it's a String
    timestamp: " time1 " -> it's a Date()
  },
  {
    id: "2",
    keyword: "abcde",
    timestamp: " time2 "
  },
  {
    id: "3",
    keyword: "abcde",
    timestamp: " time3 "
  }
]

My actual result:

[
  {
    keyword: "abcd"
  },
  {
    keyword: "abcde"
  }
]

Example of data in Core Data:

[
  {
    id: "1", -> it's a String
    keyword: "abcd", -> it's a String
    timestamp: " time1 " -> it's a Date()
  },
  {
    id: "2",
    keyword: "abcde",
    timestamp: " time2 "
  },
  {
    id: "3",
    keyword: "abcde",
    timestamp: " time3 "
  }
]

The code:

func getItemsByListTypeAndKeyword(listType: String, keyword: String = "", ascending: Bool = false) -> [[String: Any]]? {
    printIfDebug(instanceType: self, functionName: #function, id: id)
    
    let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "SearchHistoryItemModel")
    fetchRequest.sortDescriptors = [
        NSSortDescriptor(keyPath: \SearchHistoryItemModel.timestamp, ascending: ascending)
    ]
    if keyword.isEmpty {
        fetchRequest.predicate = NSPredicate(
            format: "list.type = %@",
            listType
        )
    } else {
        fetchRequest.predicate = NSPredicate(
            format: "(list.type = %@) AND (keyword beginswith %@)",
            listType,
            keyword
        )
    }
    
    fetchRequest.resultType = .dictionaryResultType
    fetchRequest.propertiesToFetch = [
        "keyword"
    ]
    
    fetchRequest.returnsDistinctResults = true
    
    let objects = try? viewContext.fetch(fetchRequest)
    
    return objects?.compactMap({ item in
        print(item)
        return item as? [String: Any]
    })
}

  • Don’t use dictionaryResultType if you want all attributes. Fetch the whole object instead which is the default so actually don’t set resultType at all.

    – 




  • @JoakimDanielson without it, it will return duplicate keyword i.e. book, book, cat

    – 




  • Well what is really that you want to fetch? What is a distinct result? In your expected result sample you do have duplicate keywords.

    – 

  • I want to fetch both the id, and keyword. but i only want 1 distinct keyword. so if there is two data with exact keyword, i should only get the last one.

    – 

  • 1

    You should update the question with those requirements so it becomes clearer.

    – 

Leave a Comment