Как получить список стран в Swift ios?

Я уже видел два вопроса, похожих на мой, но ответы на эти вопросы у меня не работают. У меня есть старый проект со списком стран, напечатанным вручную внутри набора квадратных скобок.

Я могу легко использовать это в своем pickerView, но мне интересно, есть ли более эффективный способ сделать это?

Я буду использовать список стран в UIPickerView.


person LondonGuy    schedule 10.01.2015    source источник
comment
Вы можете использовать этот готовый модуль. Хотя это не бесплатно. Взгляните на этот урок на YouTube. youtube.com/watch?v=tovZRZxcTVY&t=23s   -  person Tulon    schedule 28.05.2020


Ответы (12)


Вы можете получить список стран, используя isoCountryCodes класса NSLocale, который возвращает массив [String]. Оттуда вы получаете название страны, используя метод displayName(forKey:) NSLocale. Это выглядит так:

var countries: [String] = []

for code in NSLocale.isoCountryCodes  {
    let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
    let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
    countries.append(name)
}

print(countries)
person Ian    schedule 10.01.2015
comment
Привет, могу ли я получить все штаты и города, а также отфильтровать, как конкретную страну, все штаты и города. Спасибо - person Yogesh Patel; 03.02.2020

SWIFT 3 и 4

var countries: [String] = []

for code in NSLocale.isoCountryCodes as [String] {
    let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
    let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
    countries.append(name)
}

print(countries)
person Oscar Falmer    schedule 15.06.2017

Свифт 4.2

let languageList = Locale.isoLanguageCodes.compactMap { Locale.current.localizedString(forLanguageCode: $0) }
let countryList = Locale.isoRegionCodes.compactMap { Locale.current.localizedString(forRegionCode: $0) }
person Андрій Вахній    schedule 11.03.2019

То же, что и у Яна, но короче

let countries = NSLocale.ISOCountryCodes().map { (code:String) -> String in
  let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode: code])
  return NSLocale(localeIdentifier: "en_US").displayNameForKey(NSLocaleIdentifier, value: id) ?? "Country not found for code: \(code)"
}

print(countries)
person vedo27    schedule 06.03.2016

Swift Вы можете легко получить названия стран и их эмодзи флагов.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        var countriesData = [(name: String, flag: String)]()

        for code in NSLocale.isoCountryCodes  {

            let flag = String.emojiFlag(for: code)
            let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])

            if let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) {
                countriesData.append((name: name, flag: flag!))
            }else{
                 //"Country not found for code: \(code)"
            }
        }

        print(countriesData)
    }
}


extension String {

    static func emojiFlag(for countryCode: String) -> String! {
        func isLowercaseASCIIScalar(_ scalar: Unicode.Scalar) -> Bool {
            return scalar.value >= 0x61 && scalar.value <= 0x7A
        }

        func regionalIndicatorSymbol(for scalar: Unicode.Scalar) -> Unicode.Scalar {
            precondition(isLowercaseASCIIScalar(scalar))

            // 0x1F1E6 marks the start of the Regional Indicator Symbol range and corresponds to 'A'
            // 0x61 marks the start of the lowercase ASCII alphabet: 'a'
            return Unicode.Scalar(scalar.value + (0x1F1E6 - 0x61))!
        }

        let lowercasedCode = countryCode.lowercased()
        guard lowercasedCode.count == 2 else { return nil }
        guard lowercasedCode.unicodeScalars.reduce(true, { accum, scalar in accum && isLowercaseASCIIScalar(scalar) }) else { return nil }

        let indicatorSymbols = lowercasedCode.unicodeScalars.map({ regionalIndicatorSymbol(for: $0) })
        return String(indicatorSymbols.map({ Character($0) }))
    }
}

Результат:

введите описание изображения здесь

person ZAFAR007    schedule 29.01.2020

также рекомендуется локализовать отображаемое название страны. Таким образом, в дополнение к ответу vedo27 это будет:

let countriesArray = NSLocale.ISOCountryCodes().map { (code:String) -> String in
        let id = NSLocale.localeIdentifierFromComponents([NSLocaleCountryCode: code])
        let currentLocaleID = NSLocale.currentLocale().localeIdentifier
        return NSLocale(localeIdentifier: currentLocaleID).displayNameForKey(NSLocaleIdentifier, value: id) ?? "Country not found for code: \(code)"
    }
person Maciej Chrzastek    schedule 30.09.2016
comment
Почему люди автоматически предполагают, что язык, который кто-то хочет видеть, это en_US, en_UK или что-то в этом роде? Я никогда не понимал, почему многие люди не делают так, как вы предложили. Спасибо, что добавили это! - person Lance Samaria; 11.02.2019

Вот ответ @vedo27 в Swift 3

 let countries = NSLocale.isoCountryCodes.map { (code:String) -> String in
    let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
    return NSLocale(localeIdentifier: "en_US").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
}
person thecloud_of_unknowing    schedule 24.11.2016

SWIFT 4

Вот элегантный способ сделать это в Swift 4

var countries: [String] = {

    var arrayOfCountries: [String] = []

    for code in NSLocale.isoCountryCodes as [String] {
        let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
        let name = NSLocale(localeIdentifier: "en_UK").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
        arrayOfCountries.append(name)
    }

    return arrayOfCountries
}()
person ricks    schedule 23.03.2018
comment
Не могли бы вы сказать мне, как улучшить мой ответ, если вы меня понизите, спасибо - person ricks; 26.03.2019

Swift 3 объявлен как var:

var countries: [String] {
    let myLanguageId = "en" // in which language I want to show the list
    return NSLocale.isoCountryCodes.map {
        return NSLocale(localeIdentifier: myLanguageId).localizedString(forCountryCode: $0) ?? $0
    }
}
person Au Ris    schedule 19.04.2017
comment
localizedString(forCountryCode: code) доступен только с iOS10 - person Rajesh73; 30.07.2017

Обновите ответ vedo27, но в Swift 5:

let countries : [String] = NSLocale.isoCountryCodes.map { (code:String) -> String in
        let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
        return NSLocale(localeIdentifier: "en_US").displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
    }

Также для того, чтобы иметь отсортированный массив для стран в алфавитном порядке, добавьте это ниже в свой порядок после получения списка стран.

let sortedcountries = countries.sorted { $0 < $1 }
person Usman Awan    schedule 10.11.2019

В качестве альтернативы вы можете иметь его в Swift 4 и локализовать на системном языке.

import Foundation

struct Country {
  let name: String
  let code: String
}

final class CountryHelper {
  class func allCountries() -> [Country] {
    var countries = [Country]()

    for code in Locale.isoRegionCodes as [String] {
      if let name = Locale.autoupdatingCurrent.localizedString(forRegionCode: code) {
        countries.append(Country(name: name, code: code))
      }
    }

    return countries
  }
}
person fssilva    schedule 25.05.2018

Вот код для Swift 5.1 (ну, по крайней мере, это работает для меня, так как многие функции были переименованы):

let array = NSLocale.isoCountryCodes.map
{
        (code:String) -> String in
        
        let id = NSLocale.localeIdentifier(fromComponents: [NSLocale.Key.countryCode.rawValue: code])
        let currentLocaleID = NSLocale.current.identifier
        return NSLocale(localeIdentifier: currentLocaleID).displayName(forKey: NSLocale.Key.identifier, value: id) ?? "Country not found for code: \(code)"
}

здесь массив [String]

person Matej P    schedule 16.09.2020