swiftavspeechsynthesizeravspeechutterance

Get list of countries from AVSpeechSynthesisVoice


I'm trying to get the Region Code found in AVSpeechSynthesisVoice instead of e.g: en-GB.

The output I'm aiming for is as follow

enter image description here

This is my current code, while it works, I feel there must be a more elegant solution and from what I read, split by - could product errors for some languages

let speechVoices = AVSpeechSynthesisVoice.speechVoices()

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    let language = Locale.current.localizedString(forLanguageCode: speechVoices[row].language)!
    let languageCode = speechVoices[row].language

    var regionCodeArray = languageCode.split(separator: "-") // FIXME: buggy may break
    let regionCode = regionCodeArray.removeLast()

    // Must be a more elegant way to get RegionCode
    let country = Locale.current.localizedString(forRegionCode: String(regionCode))

    return "\(language) (\(country ?? ""))"
}

Thanks!


Solution

  • So I thought of another alternative that doesn't require splitting and this is what I got, but I welcome alternative answers or perhaps a comment on my code as I am learning and looking to improve

    let speechVoices = AVSpeechSynthesisVoice.speechVoices()
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        let language = Locale.current.localizedString(forLanguageCode: speechVoices[row].language)!
        let languageCode = speechVoices[row].language
    
        var regionCode:String = ""
        for region in Locale.isoRegionCodes {
            // Test if provided region codes has voices or not
            if languageCode.contains(region) {
                regionCode = region
            }
        }
    
        let country = Locale.current.localizedString(forRegionCode: String(regionCode))
    
        return "\(language) (\(country ?? ""))"
    }