本文轉載至 http://blog.csdn.net/lvxiangan/article/details/28101119
以下內容摘抄自網路,著作權屬於原作者
方法1:使用ios自帶聯網查詢功能,斷網會報 PBRequester failed with Error Error Domain=NSURLErrorDomain Code=-1009 "似乎已斷開與網際網路的連線。" UserInfo=0x1e2ea840 {NSErrorFailingURLStringKey=https://gsp4-cn.ls.apple.com/PlaceSearchServlet, NSErrorFailingURLKey=https://gsp4-cn.ls.apple.com/PlaceSearchServlet, NSLocalizedDescription=似乎已斷開與網際網路的連線。, NSUnderlyingError=0x1e1172c0 "似乎已斷開與網際網路的連線。"}
獲取當前所在地的地理位置資訊需要使用一個新的類,MKReverseGeocoder。這個類在MapKit.framework中。我們把框架加進來,並將標頭檔案匯入就可以用了。
敲了一會程式碼,結果發現這個類iOS5.0就不用了。真是的。為了照顧相容性,我們先研究MKReverseGeocoder,等下再來研究這個新類,恩,名字叫做CLGeocoder,恩,沒拼錯。在CoreLocation裡面。
先說MKReverseGeocoder的用法。(忍不住出來吐個槽,一般看見被劃掉的紅線,一邊敲回車,還真是說不出來的違和啊。)
。。。。。。。。。。。。。。。
表示測試完成了,IOS的網路總是假死,一假死,各種需要使用網路的的功能,就不怎好用了。桑心。
MKReverseGeocoder的初始化,很簡單。
MKReverseGeocoder *geocoder = [[MKReverseGeocoder alloc] initWithCoordinate:currentCoordinate2D];
geocoder.delegate = self;
[geocoder start];
呼叫以上程式碼後呢,會自動呼叫反向地址編碼的API。我們這邊使用代理來接收。至於代理方法麼,我們要實現兩個。
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark {
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error{
}
第一個方法是獲取反向編碼的。第二個是當反向編碼失敗時,處理錯誤使用的。
我們主要討論第一個方法。
placemark(MKPlacemark類的物件)其實是geocoder(MKReverseGeocoder類的物件)的一個屬性。從geocoder裡面取placemark這個和直接取placemark這個其實區別不大。而我們需要的資訊主要就在這個裡面了。
// 這個字典存放基礎資料
@property (nonatomic, readonly) NSDictionary *addressDictionary;
讓我們試試看,能從這個字典裡面倒出來些什麼東西。
以下是我用這個addressDictionary屬性倒出來的字典。我們分析看看。
{
City = "\U897f\U5b89\U5e02";// 城市名字
Country = "\U4e2d\U56fd";// 國家名字
CountryCode = CN;// 國家編碼
FormattedAddressLines = (
"\U4e2d\U56fd",
"\U9655\U897f\U7701\U897f\U5b89\U5e02\U96c1\U5854\U533a",
"\U9ad8\U65b0\U516d\U8def34\U53f7"
); // 這個應該是格式化後的地址了
State = "\U9655\U897f\U7701"; // 省
Street = "\U9ad8\U65b0\U516d\U8def 34\U53f7";// 街道完整名稱
SubLocality = "\U96c1\U5854\U533a";//區名
SubThoroughfare = "34\U53f7";//具體地址
Thoroughfare = "\U9ad8\U65b0\U516d\U8def";//街道名稱
}
注意:上面的這個字典是可以直接轉化為聯絡人的字典的,通過這個ABCreateStringWithAddressDictionary屬性。
以下是placemark的其他屬性。大家可以隨意取用。
// address dictionary properties
@property (nonatomic, readonly) NSString *name; // eg. Apple Inc.
@property (nonatomic, readonly) NSString *thoroughfare; // street address, eg. 1 Infinite Loop
@property (nonatomic, readonly) NSString *subThoroughfare; // eg. 1
@property (nonatomic, readonly) NSString *locality; // city, eg. Cupertino
@property (nonatomic, readonly) NSString *subLocality; // neighborhood, common name, eg. Mission District
@property (nonatomic, readonly) NSString *administrativeArea; // state, eg. CA
@property (nonatomic, readonly) NSString *subAdministrativeArea; // county, eg. Santa Clara
@property (nonatomic, readonly) NSString *postalCode; // zip code, eg. 95014
@property (nonatomic, readonly) NSString *ISOcountryCode; // eg. US
@property (nonatomic, readonly) NSString *country; // eg. United States
@property (nonatomic, readonly) NSString *inlandWater; // eg. Lake Tahoe
@property (nonatomic, readonly) NSString *ocean; // eg. Pacific Ocean
@property (nonatomic, readonly) NSArray *areasOfInterest; // eg. Golden Gate Park
注意:我在使用的過程中發現,如果網路假死,則有可能較長時間無法獲得逆向的結果。這一點可能需要大家注意。
哎呀呀呀,差點忘了,IOS5下不推薦使用我上面講的一大堆。我們需要用這個CLGeocoder類。
使用方法也很簡單。參照如下步驟:
首先建立一個CLGeocoder物件,然後呼叫他的- (void)reverseGeocodeLocation:(CLLocation *)location completionHandler:(CLGeocodeCompletionHandler)completionHandler;方法。按照需要的引數型別傳參。有的筒子會問這個CLGeocodeCompletionHandler東西怎麼寫?這個其實是IOS4之後就被官方大力推薦使用的BLOCK,不會用的同學快去看文件吧。
CLGeocodeCompletionHandler的定義就是這樣的。typedef void(^CLGeocodeCompletionHandler)(NSArray *placemarks, NSError *error); 我們只要寫好一個block物件傳進去就好了。
以下是使用CLGeocoder的參考程式碼。不用代理了是不是很開心呢?
CLGeocoder* geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray* placemarks, NSError* error){
NSLog(@"%@",placemarks);
}];
方法2: 利用google地圖api
//根據經緯度 查詢地址 - (void)getAddress:(NSString *)aLongitude withLatitude:(NSString *)aLatitude withBlock:(void(^)(id result))callback { callbackBlock = callback; NSString *url = @"http://maps.googleapis.com/maps/api/geocode/json"; NSString *coordinateStr = [NSString stringWithFormat:@"%@,%@",aLatitude,aLongitude]; NSMutableDictionary *params = [[NSMutableDictionary alloc] init]; [params setValue:@"true" forKey:@"sensor"]; [params setValue:@"cn" forKey:@"language"]; [params setObject:coordinateStr forKey:@"latlng"]; NSString *tempParamStr = [self addParametersToRequest:params]; NSString *tempUrl = [NSString stringWithFormat:@"%@?%@",url,tempParamStr]; NSMutableURLRequest *operationRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:tempUrl]]; NSURLConnection *operationConnection = [[NSURLConnection alloc] initWithRequest:operationRequest delegate:self startImmediately:NO]; [operationConnection start]; } - (NSString *)addParametersToRequest:(NSMutableDictionary*)parameters { NSMutableArray *paramStringsArray = [NSMutableArray arrayWithCapacity:[[parameters allKeys] count]]; for(NSString *key in [parameters allKeys]) { NSObject *paramValue = [parameters valueForKey:key]; if ([paramValue isKindOfClass:[NSString class]]) { [paramStringsArray addObject:[NSString stringWithFormat:@"%@=%@", key, [(NSString *)paramValue encodedURLParameterString]]]; } else { [paramStringsArray addObject:[NSString stringWithFormat:@"%@=%@", key, paramValue]]; } } NSString *paramsString = [paramStringsArray componentsJoinedByString:@"&"]; return paramsString; }