I'm a recent Swift learner and now I'm trying to use following package: https://github.com/aaronSig/Hunspell-iOS
The package itself is written using C++ and has some headers for Objective-C. I've added *-Bridging-Header.h
file and have been able to use the package inside Swift code, but now I don't understand how to use it properly:
The comments for Objective-C headers for the library say following:
/* suggest(suggestions, word) - search suggestions
* input: pointer to an array of strings pointer and the (bad) word
* array of strings pointer (here *slst) may not be initialized
* output: number of suggestions in string array, and suggestions in
* a newly allocated array of strings (*slts will be NULL when number
* of suggestion equals 0.)
*/
LIBHUNSPELL_DLL_EXPORTED int Hunspell_suggest(Hunhandle *pHunspell, char*** slst, const char * word);
But I don't know how to get correct pointer now. I've tried to utilize answers from here: How to pass an array of Swift strings to a C function taking a char ** parameter
But this is where I got so far
I managed to get it working by using the SpellChecker
class directly. My bridging header only imports "SpellChecker.h"
currently:
// ProjectName-Bridging-Header.h:
#import "SpellChecker.h"
I then created a simple wrapper to make it easier to consume the lib:
class SpellCheckerWrapper {
/// The instance of the Objective-C `SpellChecker`
private let spellChecker: SpellChecker
/// Used to avoid possible exceptions during `getSuggestions`.
private var isLoaded = false
init() {
spellChecker = SpellChecker()
// I set the language directly in the constructor but feel free
// but feel free to make `updateLanguage` public and use it directly.
updateLanguage("hy_AM")
isLoaded = true
}
public func getSuggestions(for word: String) -> [String] {
if !isLoaded {
return []
}
let suggestions = spellChecker.getSuggestionsForWord(word)
// Remove the log if you don't need it :)
NSLog("[SpellCheckerWrapper] suggestions: \(suggestions ?? [])")
return suggestions as? [String] ?? []
}
public func isSpeltCorrectly(_ word: String) -> Bool {
return spellChecker.isSpeltCorrectly(word)
}
private func updateLanguage(_ language: String) {
spellChecker.updateLanguage(language)
}
}
I also had to update the createCharFromCFStringRef
function in SpellChecker.mm
because it crashed otherwise. I don't remember the exact issue, but here is the updated code in case it throws exceptions for you too:
static char *createCharFromCFStringRef(CFStringRef cfstr)
{
if (cfstr == NULL) {
return NULL;
}
CFIndex length = CFStringGetLength(cfstr);
CFIndex maxSize = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
char *buffer = (char *)malloc(maxSize);
if (CFStringGetCString(cfstr, buffer, maxSize, kCFStringEncodingUTF8)) {
return buffer;
}
return NULL;
}
Hope this helps!
Edit: my full implementation can be found in https://github.com/f-person/hayatar/blob/ee8daae5e221dcf192ac2b7d572c80947453e1bb/Armenian/AutocompleteProvider.swift