標籤:
參考網址:
經緯度定位:http://blog.csdn.net/whaomian/article/details/6807739
位置解析:http://www.cocoachina.com/bbs/read.php?tid=134893&keyword=%B5%D8%C0%ED%CE%BB%D6%C3
百度天氣免費API:http://www.cnblogs.com/txw1958/p/baidu-weather-forecast-api.html
AFNetworking訪問網路和簡單JSON解析:http://e673.com/index.php/afnetworking-conclu-json/
解決URL中中文編碼不被識別:http://blog.csdn.net/typingios/article/details/9136005
最近心血來潮,就想學習一下定位和擷取天氣。剛開始感覺挺難的,做下來花費了將近四天的時間,收貨頗多。像我這種新手,剛開始是有需求但不知道怎麼實現,很多時間都花費在找資料上了。其實熟練了就幾不花時間了。
進入正題:
1.定位。
首先在項目中加入庫CoreLocaltion.framework。單單是定位的話,用CoreLocaltion.framework和mapkit.framework是沒有區別的,但是mapkit.framework支援地圖方面的擴充也更臃腫。
在.h檔案中加入引用:
1 #import <CoreLocaltion/CoreLocaltion.h>
實現代理:CLLocationManagerDelegate
並定義兩個變數:
1 CLLocationManager *localManager;2 CLLocation *newLocation;
在.m檔案中的viewDidLoad方法中初始化localManager並設定代理為自己:
1 //初始化LocationManager2 locationManager = [[CLLocationManager alloc] init];3 //設定定位精度4 locationManager.desiredAccuracy = kCLLocationAccuracyBest;5 //設定代理6 locationManager.delegate = self;
並實現方法locationManager:didUpdateLocations:,用於在定位成功時進行處理事務
1 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations2 {3 newLocation = [locations firstObject];//第一個是當前的位置,第二個是原先的位置4 5 //定位成功後的處理,如顯示到視圖中去6 //緯度:newLocation.coordinate.latitude, 經度:newLocation.coordinate.longitude7 8 [localManager stopUpdatingLocation];//關閉定位9 }
順便提一下以前的方法locationManager:didUpdateToLocation:fromLocation:,建議用上面的新的方法!
1 - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {2 newLocation = newLocation;3 //定位成功後的處理,如上4 }
上面的方法從函數名上應該能看出來,是位置更新後自動調用的方法,但是位置更新卻是要程式控制的,比如,程式中的一個按鈕被點擊時開始更新位置,則要在點擊事件中加入對定位服務的判斷和對更新位置的請求:
1 if ([CLLocationManager locationServicesEnabled]) { 2 //如果是iOS8的話則要手動請求一下定位的授權 3 if (CurrentVesion >= 8.0) { 4 [locationManager requestWhenInUseAuthorization]; 5 } 6 //更新位置 7 [locationManager startUpdatingLocation]; 8 }else{ 9 //給出提示,定位服務不可用或沒有授權擷取位置資訊10 }
2.解析位置
剛只是擷取了位置資訊,下面來對位置資訊(上面定義的location)進行解碼,這樣就可以得到位置資訊的文字描述,如“河南省開封市金明區***街道***號”。
在.h檔案中加入一個變數:CLPlacemark *placemark;//這裡不是特別必要非要在這裡建這個變數,但是後面通過天氣API擷取天氣資料要用到
在.m檔案中,開始進行解碼。可加到上面“定位成功後的處理”部分:
1 //位置的文字串描述 2 __block NSString *locationInfo = @""; 3 4 CLGeocoder *geocoder = [[CLGeocoder alloc] init]; 5 [geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) { 6 if (placemarks.count > 0) { 7 placemark = [placemarks objectAtIndex:0]; 8 9 locationInfo = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];10 11 //列印placemark的各個欄位資訊12 NSLog(@"I am currently at %@",locationInfo);13 NSLog(@"placemark.ISOcountryCode %@",placemark.ISOcountryCode);14 NSLog(@"placemark.country %@",placemark.country);15 NSLog(@"placemark.postalCode %@",placemark.postalCode);16 NSLog(@"placemark.administrativeArea %@",placemark.administrativeArea);17 NSLog(@"placemark.locality %@",placemark.locality);18 NSLog(@"placemark.subLocality %@",placemark.subLocality);19 NSLog(@"placemark.subThoroughfare %@",placemark.subThoroughfare);20 }21 }];
3.使用天氣介面擷取天氣
在網上搜了好久的天氣介面,發現還是百度的好用(穩定,免費),就果斷用了百度。
使用介面時要訪問網路擷取資料的,所以這裡還要注意連網的。網上說AFNetworking不錯,也是果斷用了,先實現出來再挑好壞。
在AFNetworking官網下載好zip包,把其中的AFNetworking檔案夾加入到項目中去。
在.h檔案中加入引用:
1 #import "AFHTTPRequestOperation.h"
添加變數:
1 //儲存結構化的天氣資料,為了程式中複用,建議使用Model,然後方便操作再封上一層ModelService2 NSDictionary *responseDic;
然後在設定參數請求資料(如在另一個button事件中):
1 //注意參數“ak”後面的資料在自己做應用時一定自己去百度申請 2 //參數“location”,有說能用經緯度的,但是我測試失敗,不知道是不是我當時處理時寫錯了 3 //參數“output”,指定返回資料類型,json或者xml 4 5 //連結字串 6 NSString *RequestStr = [NSString stringWithFormat:@"http://api.map.baidu.com/telematics/v3/weather?location=%@&output=json&ak=******", placemark.locality]; 7 //連結字串,utf8格式,這個我在另一個demo中沒有特意設定為utf8也正常使用 8 NSString *weatherRequestStr = [RequestStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 9 //URL連結10 NSURL *weatherRequestUrl = [NSURL URLWithString:weatherRequestStr];11 //請求12 NSURLRequest *weatherRequest = [NSURLRequest requestWithURL:weatherRequestUrl];13 14 //AF庫提供的請求操作,初始化15 AFHTTPRequestOperation *weatherRequestOperation = [[AFHTTPRequestOperation alloc]initWithRequest:weatherRequest];16 //佈建要求操作成功和失敗的回呼函數17 [weatherRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject){18 NSLog(@"請求成功!");19 20 //用NSJSONSerialization解析JSON21 NSString *responseStr = [NSString stringWithString:operation.responseString];22 NSLog(@"%@", responseStr);23 NSData *responseData = [[NSData alloc] initWithData:[responseStr dataUsingEncoding:NSUTF8StringEncoding]];24 responseDic = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:nil];25 } failure:^(AFHTTPRequestOperation *operation, NSError *error){26 NSLog(@"請求失敗: %@", error);27 }];28 //開始請求操作29 [weatherRequestOperation start];
4.解析天氣資料
得到結構化的天氣資料後,就可以進行資料讀取了,這裡採用的是JSON。JSON的解析其實就是對NSArray和NSDictionary的取值操作。建議封裝到相應Model的Service中去,方便使用。
初學者注意一下:在存取資料時一定要仔細分析JSON(XML)的結構,否則你會耗好久時間找錯誤,中間可能還會以為是函數方法寫錯誤了。在JSON檔案中,“{”和“}”中間的資料是NSDictionary類型的資料,“[”和“]”中間的資料是NSArray類型的,特別是當好幾個“{”或“}”和“[”或“]”挨著時,一定分析好再寫。
OK,至此,就可以寫一個自己的天氣小應用了。
IOS - 位置及天氣擷取解析