1

In my application, I have used core data as offline persistence database. Everything is working as expected until my client expects a bit modification in searching records.

What I have to do is if one tries to search with e my query should get all record which has character as é è ê ë ... or whatever another form of 'e' in the non-English language.

This can be achieved in SQL query by COLLATE with the column name. But not able to create NSPredicate with COLLATE, Can anyone help me on this?

My code is something like

let recordFetch = NSFetchRequest<NSFetchRequestResult>(entityName: table)
recordFetch.predicate = NSPredicate(format: "MyItem CONTAINS[cd] 'tem' OR MyItemIndex.MyItemStyleIndex.MyItemStyle.MyItemStyle CONTAINS[cd] 'tem' OR MyItemIndex.breweryIndex.brewery CONTAINS[cd] 'tem'")
let fetchedEmployees = try context.fetch(recordFetch)
return fetchedEmployees as! Array<NSFetchRequestResult>

My Debug log of SQL Query is:

SELECT DISTINCT 0, t0.Z_PK, t0.Z_OPT, t0.ZMYITEM, t0.ZMYITEMAPPEARANCEDESCRIPTION, t0.ZMYITEMAROMADESCRIPTION, t0.ZMYITEMBREWINGMETHOD, t0.ZMYITEMHISTORY, t0.ZMYITEMHOPS, t0.ZMYITEMID, t0.ZMYITEMLANGUAGEID, t0.ZMYITEMMALT, t0.ZMYITEMMOUTHFEELDESCRIPTION, t0.ZMYITEMSLOGAN, t0.ZMYITEMSUMMARY, t0.ZMYITEMTASTEDESCRIPTION, t0.ZINGREDIENTSDESCRIPTION, t0.ZISUPLOADED, t0.ZLANGUAGEID, t0.ZMYITEMINDEX, t0.ZLANGUAGE FROM ZMYITEM t0 LEFT OUTER JOIN ZMYITEMINDEX t1 ON t0.ZMYITEMINDEX = t1.Z_PK LEFT OUTER JOIN ZMYITEMSTYLEINDEX t2 ON t1.ZMYITEMSTYLEINDEX = t2.Z_PK LEFT OUTER JOIN ZMYITEMSTYLE t3 ON t2.Z_PK = t3.ZMYITEMSTYLEINDEX LEFT OUTER JOIN ZBREWERYINDEX t4 ON t1.ZBREWERYINDEX = t4.Z_PK JOIN ZLANGUAGE t5 ON t0.ZLANGUAGE = t5.Z_PK WHERE (( NSCoreDataStringSearch( t0.ZMYITEM, ?, 385, 0) OR  NSCoreDataStringSearch( t3.ZMYITEMSTYLE, ?, 385, 0) OR  NSCoreDataStringSearch( t4.ZBREWERY, ?, 385, 0)) AND  t5.ZLANGUAGECODE = ?) ORDER BY t1.ZCURRENTAVERAGESCORE DESC LIMIT 50

Yes, its working now with contains[cd]... may be some caching issue.

Thanks

Ashwin Kanjariya
  • 1,019
  • 2
  • 10
  • 22
  • you can do something like `"name==[c]"` – Piyush Aug 25 '17 at 11:33
  • Ashwin bhai aa try karo [NSPredicate predicateWithFormat:@"ANY name LIKE[c] %@", @"teste"]; OR change to **[d]** may be work karse sure nathi. – Govaadiyo Aug 25 '17 at 11:46
  • No success with any of your solution yet. My issue is not regarding the case. It's with different characters(Unicode) in diff. language...and I need all related records for the same character. – Ashwin Kanjariya Aug 25 '17 at 12:06

1 Answers1

1

You can add the "d" option for "diacritical insensitive" comparison, e.g.

NSPredicate(format: "name CONTAINS[d] %@", givenName)
NSPredicate(format: "name ==[d] %@", givenName)

In addition, you might want to add the "c" option for case insensitive search, e.g.

NSPredicate(format: "name CONTAINS[cd] %@", givenName)

For more information, see String Comparisons in the "Predicate Programming Guide".

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • Actually, case sensitivity is not the issue... the issue with such characters like ë, if I search with ë then its working fine... but I need 'ë' even if I search with 'e'. – Ashwin Kanjariya Aug 25 '17 at 11:33
  • @AshwinIndianic: Did you try it with the **d** option? – Martin R Aug 25 '17 at 11:34
  • Let me try with cd by replacing my current option c – Ashwin Kanjariya Aug 25 '17 at 11:35
  • Creating predicate like MyItem CONTAINS[cd] 'tem' OR MyItemIndex.MyItemStyleIndex.MyItemStyle.MyItemStyle CONTAINS[cd] 'tem' OR MyItemIndex.breweryIndex.brewery CONTAINS[cd] 'tem' – Ashwin Kanjariya Aug 25 '17 at 11:50
  • No, None of above suggestion is working for me. tried my ways and with [c],[d], [cd]... but no success yet. – Ashwin Kanjariya Aug 25 '17 at 11:54
  • Predicate string is generated dynamically... i have added main logic only. as need predicate string for collate... Thanks – Ashwin Kanjariya Aug 25 '17 at 11:57
  • @AshwinIndianic: How is the *entity* defined and what *properties* does it have?? – Martin R Aug 25 '17 at 12:00
  • Bit complex relationship and huge database... but its stable and relationship added properly and working fine... only I need is searching criteria update. – Ashwin Kanjariya Aug 25 '17 at 12:03
  • I am fairly sure that it works. Without a *concrete* example (including all relevant Core Data definitions) I cannot help any further. – Martin R Aug 25 '17 at 12:09
  • I'm Trying with all the suggestions of a solution... but my predicate is excluding that kind of characters records. Searching working case in sensitive but not like collate is work...Anyway Thanks for your help and suggestion. – Ashwin Kanjariya Aug 25 '17 at 12:17
  • Some web pages say like "It's worth noting that there is one additional parameter you can also pass in: "d". It stands for diacritic insensitive. So if you wanted your filter to be both case and diacritic insensitive just use:" But not working to me... don't know what can bet issue... As i can see. That records were excluded for my return array ;( – Ashwin Kanjariya Aug 25 '17 at 12:42
  • @AshwinIndianic: You can enable Core Data debugging (https://stackoverflow.com/questions/12306343/how-to-print-core-data-debug-values) and inspect the generated SQL query and results. – Martin R Aug 25 '17 at 12:44
  • Hmmm, I have followed and read many of your answers for core data. – Ashwin Kanjariya Aug 25 '17 at 12:46
  • Pleases let me know if you find any of my mistake in the code. above query for contains[cd]. Thanks a ton. – Ashwin Kanjariya Aug 25 '17 at 12:58
  • @AshwinIndianic: I don't see an obvious error, but I don't know your entities. – I would suggest that you start with a simpler request, e.g. `NSPredicate(format: "MyItem CONTAINS[cd] 'ten'")` – Martin R Aug 25 '17 at 12:59
  • It works for me up to one more level... I can continue now for other changes :) So Now I accepted your Answer as it worked for me. Thank you – Ashwin Kanjariya Aug 26 '17 at 04:38