11

I'm developing an app with an custom Registration Flow, where the user should set his nationality or his home Country.

My question is, if it's possible to get this information via an native ViewController like ABPeoplePickerNavigationController for contacts.

Should look like this (iPhone 6, iOS 8.x, contacts App 'select a Country'):

enter image description here

Thanks

KonDeichmann
  • 878
  • 1
  • 8
  • 21

4 Answers4

12

It is very easy to make your own Country Picker.

You can get the country list(country codes) easily from NSLocale,

NSArray *countryArray = [NSLocale ISOCountryCodes];

Also you will get the country name list using displayNameForKey method,

NSLocale *locale = [NSLocale currentLocale];

NSMutableArray *sortedCountryArray = [[NSMutableArray alloc] init];

for (NSString *countryCode in countryArray) {

    NSString *displayNameString = [locale displayNameForKey:NSLocaleCountryCode value:countryCode];

    [sortedCountryArray addObject:displayNameString];
}

[sortedCountryArray sortUsingSelector:@selector(localizedCompare:)];

Just use the sortedCountryArray for populating tableView in your picker class.

Anusha Kottiyal
  • 3,855
  • 3
  • 28
  • 45
  • can we get images for flag on this? – Ankit Kumar Gupta Sep 09 '19 at 09:36
  • 1
    @AnkitKumarGupta I don't think the flag is available with Locale. But you can check the following link to create flag emojis with country code. Also some good open source libraries are available for flag icons. https://stackoverflow.com/a/30403199/1434338 – Anusha Kottiyal Sep 09 '19 at 20:17
1

I think you have to make your own one using modal view controller.

Alternatively, you can use this one, which works quite well.

itsji10dra
  • 4,603
  • 3
  • 39
  • 59
Jakehao
  • 1,019
  • 8
  • 15
1

No there isn't a built-in picker for countries. Same about the classic picture reader, its the stuff you have to make yourself.

Thankfully, it's rather easy to make and find, wether you want someone else's (lockwood is a very realiable programmer, i'm sure his CountryPicker is great).

Or you can go the harder way and make one yourself from scratch.

Note that if you have all the country codes (BE, FR, EN, NL, PT, etc.) you can find the localized name with iOS.

What I did in my code was importing a massive static dictionary of all country codes, and simply use their localized names in the tableview.

This is how I got all the codes (and international prefixes, because my app needs that).

- (NSMutableDictionary*)dialCodeDict{
    NSMutableDictionary *dialCodeDict = [[NSMutableDictionary alloc]initWithObjectsAndKeys:
                                  @"972", @"IL",
                                  @"93", @"AF",
                                  @"355", @"AL",
                                  @"213", @"DZ",
                                  @"1", @"AS",
                                  @"376", @"AD",
                                  @"244", @"AO",
                                  @"1", @"AI",
                                  @"1", @"AG",
                                  @"54", @"AR",
                                  @"374", @"AM",
                                  @"297", @"AW",
                                  @"61", @"AU",
                                  @"43", @"AT",
                                  @"994", @"AZ",
                                  @"1", @"BS",
                                  @"973", @"BH",
                                  @"880", @"BD",
                                  @"1", @"BB",
                                  @"375", @"BY",
                                  @"32", @"BE",
                                  @"501", @"BZ",
                                  @"229", @"BJ",
                                  @"1", @"BM", @"975", @"BT",
                                  @"387", @"BA", @"267", @"BW", @"55", @"BR", @"246", @"IO",
                                  @"359", @"BG", @"226", @"BF", @"257", @"BI", @"855", @"KH",
                                  @"237", @"CM", @"1", @"CA", @"238", @"CV", @"345", @"KY",
                                  @"236", @"CF", @"235", @"TD", @"56", @"CL", @"86", @"CN",
                                  @"61", @"CX", @"57", @"CO", @"269", @"KM", @"242", @"CG",
                                  @"682", @"CK", @"506", @"CR", @"385", @"HR", @"53", @"CU",
                                  @"537", @"CY", @"420", @"CZ", @"45", @"DK", @"253", @"DJ",
                                  @"1", @"DM", @"1", @"DO", @"593", @"EC", @"20", @"EG",
                                  @"503", @"SV", @"240", @"GQ", @"291", @"ER", @"372", @"EE",
                                  @"251", @"ET", @"298", @"FO", @"679", @"FJ", @"358", @"FI",
                                  @"33", @"FR", @"594", @"GF", @"689", @"PF", @"241", @"GA",
                                  @"220", @"GM", @"995", @"GE", @"49", @"DE", @"233", @"GH",
                                  @"350", @"GI", @"30", @"GR", @"299", @"GL", @"1", @"GD",
                                  @"590", @"GP", @"1", @"GU", @"502", @"GT", @"224", @"GN",
                                  @"245", @"GW", @"595", @"GY", @"509", @"HT", @"504", @"HN",
                                  @"36", @"HU", @"354", @"IS", @"91", @"IN", @"62", @"ID",
                                  @"964", @"IQ", @"353", @"IE", @"972", @"IL", @"39", @"IT",
                                  @"1", @"JM", @"81", @"JP", @"962", @"JO", @"77", @"KZ",
                                  @"254", @"KE", @"686", @"KI", @"965", @"KW", @"996", @"KG",
                                  @"371", @"LV", @"961", @"LB", @"266", @"LS", @"231", @"LR",
                                  @"423", @"LI", @"370", @"LT", @"352", @"LU", @"261", @"MG",
                                  @"265", @"MW", @"60", @"MY", @"960", @"MV", @"223", @"ML",
                                  @"356", @"MT", @"692", @"MH", @"596", @"MQ", @"222", @"MR",
                                  @"230", @"MU", @"262", @"YT", @"52", @"MX", @"377", @"MC",
                                  @"976", @"MN", @"382", @"ME", @"1", @"MS", @"212", @"MA",
                                  @"95", @"MM", @"264", @"NA", @"674", @"NR", @"977", @"NP",
                                  @"31", @"NL", @"599", @"AN", @"687", @"NC", @"64", @"NZ",
                                  @"505", @"NI", @"227", @"NE", @"234", @"NG", @"683", @"NU",
                                  @"672", @"NF", @"1", @"MP", @"47", @"NO", @"968", @"OM",
                                  @"92", @"PK", @"680", @"PW", @"507", @"PA", @"675", @"PG",
                                  @"595", @"PY", @"51", @"PE", @"63", @"PH", @"48", @"PL",
                                  @"351", @"PT", @"1", @"PR", @"974", @"QA", @"40", @"RO",
                                  @"250", @"RW", @"685", @"WS", @"378", @"SM", @"966", @"SA",
                                  @"221", @"SN", @"381", @"RS", @"248", @"SC", @"232", @"SL",
                                  @"65", @"SG", @"421", @"SK", @"386", @"SI", @"677", @"SB",
                                  @"27", @"ZA", @"500", @"GS", @"34", @"ES", @"94", @"LK",
                                  @"249", @"SD", @"597", @"SR", @"268", @"SZ", @"46", @"SE",
                                  @"41", @"CH", @"992", @"TJ", @"66", @"TH", @"228", @"TG",
                                  @"690", @"TK", @"676", @"TO", @"1", @"TT", @"216", @"TN",
                                  @"90", @"TR", @"993", @"TM", @"1", @"TC", @"688", @"TV",
                                  @"256", @"UG", @"380", @"UA", @"971", @"AE", @"44", @"GB",
                                  @"1", @"US", @"598", @"UY", @"998", @"UZ", @"678", @"VU",
                                  @"681", @"WF", @"967", @"YE", @"260", @"ZM", @"263", @"ZW",
                                  @"591", @"BO", @"673", @"BN", @"61", @"CC", @"243", @"CD",
                                  @"225", @"CI", @"500", @"FK", @"44", @"GG", @"379", @"VA",
                                  @"852", @"HK", @"98", @"IR", @"44", @"IM", @"44", @"JE",
                                  @"850", @"KP", @"82", @"KR", @"856", @"LA", @"218", @"LY",
                                  @"853", @"MO", @"389", @"MK", @"691", @"FM", @"373", @"MD",
                                  @"258", @"MZ", @"970", @"PS", @"872", @"PN", @"262", @"RE",
                                  @"7", @"RU", @"590", @"BL", @"290", @"SH", @"1", @"KN",
                                  @"1", @"LC", @"590", @"MF", @"508", @"PM", @"1", @"VC",
                                  @"239", @"ST", @"252", @"SO", @"47", @"SJ", @"963",
                                  @"SY",@"886",
                                  @"TW", @"255",
                                  @"TZ", @"670",
                                  @"TL",@"58",
                                  @"VE",@"84",
                                  @"VN",
                                  @"284", @"VG",
                                  @"340", @"VI",
                                  @"678",@"VU",
                                  @"681",@"WF",
                                  @"685",@"WS",
                                  @"967",@"YE",
                                  @"262",@"YT",
                                  @"27",@"ZA",
                                  @"260",@"ZM",
                                  @"263",@"ZW",
                                  nil];

    return dialCodeDict;
}

And then I did this :

- (void)viewDidLoad {
    _dialCodes = [self dialCodeDict];
    [self setCodes];
}

- (void)setCodes{
    CTTelephonyNetworkInfo *network_Info = [CTTelephonyNetworkInfo new];
    CTCarrier *carrier = network_Info.subscriberCellularProvider;

    NSArray *keys   = [_dialCodes allKeys];
    NSArray *values = [_dialCodes allValues];
    _countries = [[NSMutableArray alloc]initWithCapacity:[_dialCodes count]];

    NSString *baseCountry = [_dialCodes objectForKey:carrier.isoCountryCode.uppercaseString];
    for (int i = 0; i < [_dialCodes count] ; i++){

        Country *c = [[Country alloc]init];

        c.isoC  = [keys objectAtIndex:i];
        c.dialC = [values objectAtIndex:i];
        c.nameC =  [[NSLocale currentLocale] displayNameForKey:NSLocaleCountryCode value:c.isoC];
        c.isLocal = NO;
        if ([baseCountry isEqualToString:[values objectAtIndex:i]]){
            c.isLocal = YES;
            _myCountry = c;
        }

        [_countries addObject:c];

    }

    [_countries sortUsingComparator:^(Country *firstObject, Country *secondObject) {
        return [firstObject.nameC caseInsensitiveCompare:secondObject.nameC];
    }];

    [self.tableView reloadData];
    idx = [NSIndexPath indexPathForRow:[_countries indexOfObject:_myCountry] inSection:0];
    [self.tableView selectRowAtIndexPath:idx animated:YES scrollPosition:UITableViewScrollPositionMiddle];
}

I think there is too much code for what you need but, what this does is fill a tableview of all countries and align the view to the current country (if the user has a sim card or an NSLocale)

This is how i designed the tableview :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    static NSString *cellIdentifier = @"InternationalCell";
    CustomCellInternationalTableViewCell *cell;

    cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if (cell == nil){
        [tableView registerNib:[UINib nibWithNibName:@"CustomCellInternationalTableViewCell" bundle:nil] forCellReuseIdentifier:cellIdentifier];
        cell = [[CustomCellInternationalTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }else{
        cell.lbCountry.text = [[_countries objectAtIndex:indexPath.row]nameC];
        cell.lbCode.text    = [NSString stringWithFormat:@"+%@",[[_countries objectAtIndex:indexPath.row]dialC]];
        if ([[_countries objectAtIndex:indexPath.row]isLocal] == YES){
            cell.contentView.backgroundColor = FlatGray;
        }else{
            cell.contentView.backgroundColor = ClearColor;
        }
    }

    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [_countries count];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    _myCountry = [_countries objectAtIndex:indexPath.row];
    self.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self dismissViewControllerAnimated:YES completion:nil];
}

Again, there are some lines that i could remove because this is straight from my code, and because it's not well commented (my bad :D) I don't remember which would be important to you and which wouldn't ! But i'll re-read and edit if necessary.

Gil Sand
  • 5,802
  • 5
  • 36
  • 78
0

Here is a country picker I made as a cocoapod.

Usage is very simple:

class ViewController: UIViewController, MRCountryPickerDelegate {

    @IBOutlet weak var countryPicker: MRCountryPicker!
    @IBOutlet weak var countryName: UILabel!
    @IBOutlet weak var countryCode: UILabel!
    @IBOutlet weak var countryFlag: UIImageView!
    @IBOutlet weak var phoneCode: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        countryPicker.countryPickerDelegate = self
        countryPicker.showPhoneNumbers = true
        countryPicker.setCountry("SI")
    }

    func countryPhoneCodePicker(picker: SwiftCountryPicker, didSelectCountryWithName name: String, countryCode: String, phoneCode: String, flag: UIImage) {
        self.countryName.text = name
        self.countryCode.text = countryCode
        self.phoneCode.text = phoneCode
        self.countryFlag.image = flag
    }

}
Jagat Dave
  • 1,643
  • 3
  • 23
  • 30
xtrinch
  • 2,232
  • 1
  • 24
  • 46