上架的一个App用到了天气API,最初没考虑海外用户,用了weather.com的天气信息,结果发现海外用户占了不少,就不得不更新API了。网上各种搜国外能用天气API,发现都是以前的,现在要么接口关闭了要么改接口了,只好自己去各个官网查。
海外的天气API我只比较了Yahoo和Wunderground两家,各有缺点。 Yahoo的缺点是需要先获取woeid(城市ID),再通过woeid查询天气信息;Wunderground的缺点是…返回请求的信息结构很乱,我担心会改接口。Yahoo接口改过了,只需要城市名和国家代码,相较老版还算易用。
Yahoo天气API https://developer.yahoo.com/weather/
我在App中用到定位和异步请求
@interface LocationViewController ()<CLLocationManagerDelegate,NSURLConnectionDataDelegate>
先定位获得城市名称和国家代码
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
CLLocation *location=[locations lastObject];
//geo获得城市名、国家代码
CLGeocoder *geocoder=[[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:_mapView.userLocation.location completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (placemarks.count>0) {
CLPlacemark *place=[placemarks lastObject];
self.cityName=[NSString stringWithFormat:@"%@",place.locality];
self.countryCode=[NSString stringWithFormat:@"%@",place.ISOcountryCode];
}
}];
}
接口后面的env我没搞清楚是什么,官网上也没查到,估计是key,乱填或删掉都能请求到数据。
#pragma mark - 请求天气信息
-(void)loadWeatherData{
NSString *str=[NSString stringWithFormat:@"https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='%@, %@')&format=json&env=store://datatables.org/alltableswithkeys",self.cityName,self.countryCode];
NSURL *url=[NSURL URLWithString:[str stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSMutableURLRequest *req=[NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10];
NSURLConnection *connection=[NSURLConnection connectionWithRequest:req delegate:self];
[connection start];
}
解析请求返回的结果
#pragma mark NSURLConnectionDataDelegate
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"get error====%@",error);
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.data appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSError *error=nil;
NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:self.data options:NSJSONReadingMutableLeaves error:&error];
if (error) {
NSLog(@"解析错误");
}
else {
if (dic[@"query"][@"results"]) {
NSString *temperature=dic[@"query"][@"results"][@"channel"][@"item"][@"condition"][@"temp"];//温度
NSString * windSpeed=dic[@"query"][@"results"][@"channel"][@"wind"][@"speed"];//风速
NSString *sunUp=dic[@"query"][@"results"][@"channel"][@"astronomy"][@"sunrise"];//日出时间
NSString *sunDown=dic[@"query"][@"results"][@"channel"][@"astronomy"][@"sunset"];//日落时间
......
NSLog(@"解析成功");
self.data=[NSMutableData dataWithCapacity:0];
}
else {
NSLog(@"解析失败");
}
}
}
附上返回的json数据:
{
"query": {
"count": 1,
"created": "2016-09-14T11:51:25Z",
"lang": "zh-CN",
"results": {
"channel": {
"units": {
"distance": "mi",
"pressure": "in",
"speed": "mph",
"temperature": "F"
},
"title": "Yahoo! Weather - Beijing, Beijing, CN",
"link": "http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2151330/",
"description": "Yahoo! Weather for Beijing, Beijing, CN",
"language": "en-us",
"lastBuildDate": "Wed, 14 Sep 2016 07:51 PM CST",
"ttl": "60",
"location": {
"city": "Beijing",
"country": "China",
"region": " Beijing"
},
"wind": {
"chill": "81",
"direction": "203",
"speed": "11"
},
"atmosphere": {
"humidity": "55",
"pressure": "1010.0",
"rising": "0",
"visibility": "16.1"
},
"astronomy": {
"sunrise": "5:56 am",
"sunset": "6:23 pm"
},
"image": {
"title": "Yahoo! Weather",
"width": "142",
"height": "18",
"link": "http://weather.yahoo.com",
"url": "http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif"
},
"item": {
"title": "Conditions for Beijing, Beijing, CN at 06:00 PM CST",
"lat": "39.90601",
"long": "116.387909",
"link": "http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2151330/",
"pubDate": "Wed, 14 Sep 2016 06:00 PM CST",
"condition": {
"code": "34",
"date": "Wed, 14 Sep 2016 06:00 PM CST",
"temp": "80",
"text": "Mostly Sunny"
},
"forecast": [
{
"code": "30",
"date": "14 Sep 2016",
"day": "Wed",
"high": "83",
"low": "65",
"text": "Partly Cloudy"
},
{
"code": "32",
"date": "15 Sep 2016",
"day": "Thu",
"high": "85",
"low": "66",
"text": "Sunny"
},
{
"code": "4",
"date": "16 Sep 2016",
"day": "Fri",
"high": "86",
"low": "67",
"text": "Thunderstorms"
},
{
"code": "26",
"date": "17 Sep 2016",
"day": "Sat",
"high": "75",
"low": "66",
"text": "Cloudy"
},
{
"code": "28",
"date": "18 Sep 2016",
"day": "Sun",
"high": "74",
"low": "61",
"text": "Mostly Cloudy"
},
{
"code": "32",
"date": "19 Sep 2016",
"day": "Mon",
"high": "73",
"low": "56",
"text": "Sunny"
},
{
"code": "30",
"date": "20 Sep 2016",
"day": "Tue",
"high": "76",
"low": "57",
"text": "Partly Cloudy"
},
{
"code": "28",
"date": "21 Sep 2016",
"day": "Wed",
"high": "75",
"low": "60",
"text": "Mostly Cloudy"
},
{
"code": "30",
"date": "22 Sep 2016",
"day": "Thu",
"high": "68",
"low": "60",
"text": "Partly Cloudy"
},
{
"code": "47",
"date": "23 Sep 2016",
"day": "Fri",
"high": "81",
"low": "57",
"text": "Scattered Thunderstorms"
}
],
"description": "<![CDATA[<img src=\"http://l.yimg.com/a/i/us/we/52/34.gif\"/>\n<BR />\n<b>Current Conditions:</b>\n<BR />Mostly Sunny\n<BR />\n<BR />\n<b>Forecast:</b>\n<BR /> Wed - Partly Cloudy. High: 83Low: 65\n<BR /> Thu - Sunny. High: 85Low: 66\n<BR /> Fri - Thunderstorms. High: 86Low: 67\n<BR /> Sat - Cloudy. High: 75Low: 66\n<BR /> Sun - Mostly Cloudy. High: 74Low: 61\n<BR />\n<BR />\n<a href=\"http://us.rd.yahoo.com/dailynews/rss/weather/Country__Country/*https://weather.yahoo.com/country/state/city-2151330/\">Full Forecast at Yahoo! Weather</a>\n<BR />\n<BR />\n(provided by <a href=\"http://www.weather.com\" >The Weather Channel</a>)\n<BR />\n]]>",
"guid": {
"isPermaLink": "false"
}
}
}
}
}
}