上架的一个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"
                    }
                }
            }
        }
    }
}