2014-04-30 4 views
8

Ich habe drei Textfelder aus meiner Sicht. 1. Postleitzahl, 2. Stadt und 3. Staat.AutoFill Stadt und Bundesstaat von Postleitzahl in iOS

Wie Auto Stadt und Staat Feld von der Postleitzahl in iOS automatisch ausfüllen?

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 
{ 
    NSString *currentString = [textField.text stringByReplacingCharactersInRange:range withString:string]; 
    int length = [currentString length]; 
    if(length > 5) 
    { 
     return NO; 
    } 
    if(length == 5) 
    { 
     [self getCityAndState]; 
    } 
    return YES; 
} 

- (void) getCityAndState 
{ 
    //How to use google (or any) api to autofill city and state in objective - c? 
} 
+0

Verwenden Goolge GeoCoding API - [Diese] Siehe (https://developers.google.com/maps/documentation/geocoding/?csw=1) – Shruti

+0

prüfen Link http://stackoverflow.com/questions/4749706/lookup-city-and-state-by-zip-google-geocode-api – user2071152

Antwort

10

die Google GeoCoding API verwenden, um Informationen zu extrahieren, wenn Sie Postleitzahl senden möchten andere Informationen zu erhalten, verwenden Sie diese:

NSString *strRequestParams = [NSString stringWithFormat:@"http://maps.googleapis.com/maps/api/geocode/json?address=&components=postal_code:%@&sensor=false",zipCode]; 

strRequestParams = [strRequestParams stringByAddingPercentEscapesUsingEncoding:NSStringEncodingConversionExternalRepresentation]; 

NSURL *url = [NSURL URLWithString:strRequestParams]; 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 

[request setHTTPMethod:@"GET"]; 

NSError *error; 
NSURLResponse *response; 
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; 
if (!response) { 
    // "Connection Error", "Failed to Connect to the Internet" 
} 

NSString *respString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding] ; 
//NSLog(@"RECEIVED DATA : %@", respString); 

Wenn Ihre Postleitzahl Variable 32000 ist, werden Sie das this JSON Ergebnis erhalten :

können Sie diese json analysieren Informationen, die Sie Land, Stadt, Länge, Breite usw.

+2

@Khanwar Ali: Nur der Grund, warum yi Ihre Antwort noch nicht akzeptiert hat, ist shouldChangeCharactersInRange: (NSRange) Bereichsmethode wählt 4 Zeichen aus zip-Feld statt 5 aus dem Textfeld. Wie? –

16

ich möchte mit extrahieren Versuchen Sie, die Dienste von Google zu vermeiden, da sie dazu neigen, bei einem bestimmten Nutzungsgrad Gebühren zu erheben. Hier ist die Lösung mit Apples Frameworks:

#import <CoreLocation/CoreLocation.h> 
#import <AddressBookUI/AddressBookUI.h> 

- (void)didEnterZip:(NSString*)zip 
{ 
    CLGeocoder* geoCoder = [[CLGeocoder alloc] init]; 
    [geoCoder geocodeAddressDictionary:@{(NSString*)kABPersonAddressZIPKey : zip} 
     completionHandler:^(NSArray *placemarks, NSError *error) { 
     if ([placemarks count] > 0) { 
      CLPlacemark* placemark = [placemarks objectAtIndex:0]; 

      NSString* city = placemark.addressDictionary[(NSString*)kABPersonAddressCityKey]; 
      NSString* state = placemark.addressDictionary[(NSString*)kABPersonAddressStateKey]; 
      NSString* country = placemark.addressDictionary[(NSString*)kABPersonAddressCountryCodeKey]; 

     } else { 
      // Lookup Failed 
     } 
    }]; 
} 
4

Die Antwort von a-r-Studios ist vor Ort auf, da es nicht eine Abhängigkeit von Google-Dienst einführt.

Allerdings würde ich auch den Ländercode entweder basierend auf der Eingabe des Benutzers oder US-nur einschränken, wenn es sinnvoll ist. Wenn Sie den Geocoder nicht beschränken, erhalten Sie unvorhersehbare Ergebnisse, da der Geocodierer mehrere Treffer aus verschiedenen Ländern zurückgeben kann.

#import <CoreLocation/CoreLocation.h> 
#import <AddressBookUI/AddressBookUI.h> 

- (void)didEnterZip:(NSString*)zip 
{ 
    CLGeocoder* geoCoder = [[CLGeocoder alloc] init]; 
    [geoCoder geocodeAddressDictionary:@{(NSString*)kABPersonAddressZIPKey : zip, 
      (NSString*)kABPersonAddressCountryCodeKey : @"US"} 
     completionHandler:^(NSArray *placemarks, NSError *error) { 
     if ([placemarks count] > 0) { 
      CLPlacemark* placemark = [placemarks objectAtIndex:0]; 

      NSString* city = placemark.addressDictionary[(NSString*)kABPersonAddressCityKey]; 
      NSString* state = placemark.addressDictionary[(NSString*)kABPersonAddressStateKey]; 
      NSString* country = placemark.addressDictionary[(NSString*)kABPersonAddressCountryCodeKey]; 

     } else { 
      // Lookup Failed 
     } 
    }]; 
} 
3

Während die Antworten von alex_c und ar-Studios gut funktionieren, wenn Sie nicht das Gefühl mit AddressBookUI oder Wörterbücher wie Getue, können Sie einfach die geocodeAddressString:completionHandler: Methode auf dem geocoder in der Postleitzahl allein vorbei, das ist ausreichend für die Suche:

[[CLGeocoder new] geocodeAddressString:zip completionHandler:^(NSArray *placemarks, NSError *error) { 
    if (placemarks.count) { 
     CLPlacemark *placemark = placemarks.firstObject; 

     NSString *city = placemark.locality; 
     NSString *state = placemark.administrativeArea; 
    } 
}]; 

In Swift:

CLGeocoder().geocodeAddressString(zip) { (placemarks, error) in 
    if let result = placemarks?.first { 
     let city = result.locality 
     let state = result.administrativeArea 
    } 
} 
0
static func zipToAddress(zip: String, onSuccess: (String, String) -> Void, onFail:() -> Void) { 
    var geoCoder = CLGeocoder(); 

    var params = [ 
      String(kABPersonAddressZIPKey): zip, 
      String(kABPersonAddressCountryCodeKey): "US", 
    ] 

    geoCoder.geocodeAddressDictionary(params) { 
     (plasemarks, error) -> Void in 
     var plases = plasemarks as? Array<CLPlacemark> 

     if plases != nil && plases?.count > 0 { 
      var firstPlace = plases?[0] 

      var city = firstPlace?.addressDictionary[String(kABPersonAddressCityKey)] as? String 
      var state = firstPlace?.addressDictionary[String(kABPersonAddressStateKey)] as? String 
      var country = firstPlace?.addressDictionary[String(kABPersonAddressCountryKey)] as? String // US 

      onSuccess(city != nil ? city! : "", state != nil ? state! : "") 
      return; 
     } 

     onFail() 
    } 
} 

gleich mit swift, kann ich das nicht als Kommentar hinzufügen (Punkte nicht enoght)

3

Hier ist die Swift 3 Version mit allen oben genannten Korrekturen.

func zipToAddress(zip: String, onSuccess: @escaping (String, String, String) -> Void, onFail: @escaping() -> Void) { 
    let geoCoder = CLGeocoder(); 

    let params = [ 
     String(CNPostalAddressPostalCodeKey): zip, 
     String(CNPostalAddressISOCountryCodeKey): "US", 
     ] 

    geoCoder.geocodeAddressDictionary(params) { 
     (plasemarks, error) -> Void in 

     if let plases = plasemarks { 

      if plases.count > 0 { 
       let firstPlace = plases[0] 

       print("City \(firstPlace.locality) state \(firstPlace.administrativeArea) and country \(firstPlace.country) and iso country \(firstPlace.country)") 

       let city = firstPlace.locality 
       let state = firstPlace.administrativeArea 
       let country = firstPlace.country 

       onSuccess(city != nil ? city! : "", state != nil ? state! : "", country ?? "Not found") 
       return; 
      } 
     } 

     onFail() 
    } 
} 
0

Hier ist die Swift-4-Version, mit einem richtigen optionals als Bonus Handhabung. Verwenden Sie dies, wenn Sie das Land der abgefragten Postleitzahl manuell angeben möchten.

private func zipToAddress(zip: String?, onSuccess: @escaping (String, String) -> Void, onFail: ((Error?) -> Void)?) { 

    guard let zip = zip else { 
     onFail?(nil) 
     return 
    } 

    let geoCoder = CLGeocoder() 

    let params: [String: Any] = [ 
     String(CNPostalAddressPostalCodeKey): zip, 
     String(CNPostalAddressISOCountryCodeKey): "US" 
     ] 

    geoCoder.geocodeAddressDictionary(params) { placemarks, error -> Void in 
     /// Read CLPlacemark documentation to see all available fields 
     if let place = placemarks?[0], let city = place.locality, let state = place.administrativeArea { 
      onSuccess(city, state) 
     } else { 
      onFail?(error) 
     } 
    } 
} 

Und hier ist die Lösung basierend auf der Nathan's Antwort. Verwenden Sie diese Option, um basierend auf dem Benutzergebietsschema nach der Stadt und dem Verwaltungsbereich abzufragen.

private func localZipToAddress(zip: String?, onSuccess: @escaping (String, String) -> Void, onFail: ((Error?) -> Void)?) { 

    guard let zip = zip else { 
     onFail?(nil) 
     return 
    } 

    CLGeocoder().geocodeAddressString(zip) { placemarks, error in 
     if let result = placemarks?.first, let city = result.locality, let state = result.administrativeArea { 
      onSuccess(city, state) 
     } else { 
      onFail?(error) 
     } 
    } 
} 
Verwandte Themen