可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I was wondering if it was possible to get the state abbreviations from CLPlacemark?
In the CLPlacemark Reference from Apple it states:
administrativeArea
The state or province associated with the placemark. (read-only)
@property(nonatomic, readonly) NSString *administrativeArea
Discussion
If the placemark location is Apple’s headquarters, for example, the value for this property would be the string “CA” or “California”.
but whenever I use it, I only get the full state (i.e California) and not the abbreviation (i.e CA). Can anyone help me here?
回答1:
For anyone else that needs a solution for this, I've created a category class for CLPlacemark that returns the short state string. All you need to do is call myPlacemark shortState
CLPlacemark+ShortState.h
#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
@interface CLPlacemark (ShortState)
- (NSString *)shortState;
@end
CLPlacemark+ShortState.m
#import "CLPlacemark+ShortState.h"
@interface CLPlacemark (ShortStatePrivate)
- (NSDictionary *)nameAbbreviations;
@end
@implementation CLPlacemark (ShortState)
- (NSString *)shortState {
NSString *state = [self.administrativeArea lowercaseString];
if (state.length==0)
return nil;
return [[self nameAbbreviations] objectForKey:state];
}
- (NSDictionary *)nameAbbreviations {
static NSDictionary *nameAbbreviations = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
nameAbbreviations = [NSDictionary dictionaryWithObjectsAndKeys:
@"AL",@"alabama",
@"AK",@"alaska",
@"AZ",@"arizona",
@"AR",@"arkansas",
@"CA",@"california",
@"CO",@"colorado",
@"CT",@"connecticut",
@"DE",@"delaware",
@"DC",@"district of columbia",
@"FL",@"florida",
@"GA",@"georgia",
@"HI",@"hawaii",
@"ID",@"idaho",
@"IL",@"illinois",
@"IN",@"indiana",
@"IA",@"iowa",
@"KS",@"kansas",
@"KY",@"kentucky",
@"LA",@"louisiana",
@"ME",@"maine",
@"MD",@"maryland",
@"MA",@"massachusetts",
@"MI",@"michigan",
@"MN",@"minnesota",
@"MS",@"mississippi",
@"MO",@"missouri",
@"MT",@"montana",
@"NE",@"nebraska",
@"NV",@"nevada",
@"NH",@"new hampshire",
@"NJ",@"new jersey",
@"NM",@"new mexico",
@"NY",@"new york",
@"NC",@"north carolina",
@"ND",@"north dakota",
@"OH",@"ohio",
@"OK",@"oklahoma",
@"OR",@"oregon",
@"PA",@"pennsylvania",
@"RI",@"rhode island",
@"SC",@"south carolina",
@"SD",@"south dakota",
@"TN",@"tennessee",
@"TX",@"texas",
@"UT",@"utah",
@"VT",@"vermont",
@"VA",@"virginia",
@"WA",@"washington",
@"WV",@"west virginia",
@"WI",@"wisconsin",
@"WY",@"wyoming",
nil];
});
return nameAbbreviations;
}
@end
回答2:
I think you can't get the abbreviations of the states but you can make your own class for this..
- List all the states(states are standards)
- compare those states and return the abbreviation
Code..
Class StateAbbreviation
StateAbbreviation.h
@interface StateAbbreviation : NSString {
}
+ (NSString *)allStates:(int)index;
+ (NSString *)abbreviatedState:(NSString *)strState;
@end
StateAbbreviation.m
@implementation StateAbbreviation
+ (NSString *)allStates:(NSString *)strState {
// Remove all space on the string
strState = [strState stringByReplacingOccurrencesOfString:@" " withString:@""];
//Sample states
NSArray *states = [[NSArray alloc] initWithObjects:
@"ALABAMA",
@"ALASKA", //AK
@"AMERICANSAMOA", //AS
@"ARIZONA", //AZ
@"ARKANSAS", //AR
@"CALIFORNIA", //CA
nil];
NSUInteger n = [states indexOfObject:strState];
if (n > [states count] - 1) {
strAbbreviation = @"NOSTATE";
}
else {
strAbbreviation =[self abbreviatedState:n];
}
[states release];
return strAbbreviation;
}
+ (NSString *)abbreviatedState:(int)index {
NSArray *states = [[NSArray alloc] initWithObjects:
@"AL",
@"AK",
@"AS",
@"AZ",
@"AR",
@"CA",
nil];
NSString *strAbbreviation = [states objectAtIndex:index];
[states release];
return strAbbreviation;
}
@end
When you call the class it should be something like this
NSString *upperCase = [@"California" uppercaseString]; // California could be from (NSString *)placemark.administrativeArea;
NSString *abbr = [StateAbbreviation allStates:upperCase];
NSLog(@"%@", abbr); // Result should be CA
This are only samples you can research all states something like this, states and their abbreviations also like this states and their abbreviations
回答3:
I believe the documentation is just incorrect. The administrativeArea is always going to return the full state name for places in the United States. To get the state abbreviation you'll most likely have to create a dictionary look up table so that searching for the key "California" will return you the value "CA".
回答4:
Here is another category using FormattedAddressLines, it returns a result like California, CA
-(NSString *) stateWithAbbreviation {
if ([[self.addressDictionary objectForKey:@"CountryCode"] isEqualToString:@"US"] && self.addressDictionary) {
NSDictionary *addressLines = [self.addressDictionary objectForKey:@"FormattedAddressLines"];
for (NSString* addressLine in addressLines) {
NSRange stateRange = [addressLine rangeOfString:self.postalCode options:NSCaseInsensitiveSearch];
if (stateRange.length > 0) {
NSRange lastSpace = [addressLine rangeOfString:@" " options:NSBackwardsSearch];
if (lastSpace.length > 0) {
NSString *state = [[addressLine substringToIndex:lastSpace.location] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
lastSpace = [state rangeOfString:@" " options:NSBackwardsSearch];
if (lastSpace.length > 0) {
NSString *abbr = [[state substringFromIndex:lastSpace.location] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
return [NSString stringWithFormat:@"%@, %@", self.administrativeArea, abbr];
}
}
}
}
}
return self.administrativeArea;
}
Not perfect but it works as long as Apple changes the format of the address lines I think.
回答5:
For people who need the state list with objects and keys swapped (e.g. on iOS 7 I get "CA" from placemark.administrativeArea
):
NSDictionary *nameAbbreviations = [NSDictionary dictionaryWithObjectsAndKeys:
@"alabama",@"AL",
@"alaska",@"AK",
@"arizona",@"AZ",
@"arkansas",@"AR",
@"california",@"CA",
@"colorado",@"CO",
@"connecticut",@"CT",
@"delaware",@"DE",
@"district of columbia",@"DC",
@"florida",@"FL",
@"georgia",@"GA",
@"hawaii",@"HI",
@"idaho",@"ID",
@"illinois",@"IL",
@"indiana",@"IN",
@"iowa",@"IA",
@"kansas",@"KS",
@"kentucky",@"KY",
@"louisiana",@"LA",
@"maine",@"ME",
@"maryland",@"MD",
@"massachusetts",@"MA",
@"michigan",@"MI",
@"minnesota",@"MN",
@"mississippi",@"MS",
@"missouri",@"MO",
@"montana",@"MT",
@"nebraska",@"NE",
@"nevada",@"NV",
@"new hampshire",@"NH",
@"new jersey",@"NJ",
@"new mexico",@"NM",
@"new york",@"NY",
@"north carolina",@"NC",
@"north dakota",@"ND",
@"ohio",@"OH",
@"oklahoma",@"OK",
@"oregon",@"OR",
@"pennsylvania",@"PA",
@"rhode island",@"RI",
@"south carolina",@"SC",
@"south dakota",@"SD",
@"tennessee",@"TN",
@"texas",@"TX",
@"utah",@"UT",
@"vermont",@"VT",
@"virginia",@"VA",
@"washington",@"WA",
@"west virginia",@"WV",
@"wisconsin",@"WI",
@"wyoming",@"WY",
nil];
回答6:
As of at least iOS 8, CLPlacemark
's administrativeArea
returns a two-letter abbreviation for US States.
You don't need to extend CLPlacemark with a category like the one in the accepted answer as long as you're targeting iOS 8 and newer (which you should be by now).
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:@"1 Infinite Loop, Cupertino, CA" completionHandler:^(NSArray *placemarks, NSError *error) {
CLPlacemark *placemark = [placemarks firstObject];
NSLog(@"State: %@", placemark.administrativeArea);
}];
Run this and you'll get:
State: CA