IOS 开发心得(1)

来源:互联网 发布:机床主轴结构优化设计 编辑:程序博客网 时间:2024/06/05 15:24

不定期更新吧。

这次做一个从天气软件。基本上是这样设计的。

首先,找个免费的 free weather api, 然后用某种格式获取所选地区的信息。

其实网上有很多的这种提供天气服务的网站,之前看到中国有个网站叫做中国气象网,提供相关的数据。不过当时是因为要在某网站上添加定制的天气服务。不太一样。

但是数据源是相同的,所以真正需要注意的是如何用IOS SDK处理不用格式的数据。

找到一个网站,http://www.wunderground.com。这个网站提供免费和收费两种套餐。免费的可以提供两天的某地区预报。收费的提供当地五百天之内的天气信息和未来一周的天气预报。明显我不需要这么专业的数据。搞个免费的玩玩就行了。

======================================================

一般的网站都提供JSON和XML两种数据格式。我看有的网站也提供CSV格式的数据。既然这个App的数据十分轻量级,所以不妨用JSON当数据源。

在上面这个网站上申请一个账号,然后添加一个App的类型,之后网站会提供一个key,利用这个key构成提取数据的url连接。

前期准备大概就这么多了。

======================================================

之后需要考虑的是怎么实现用户界面,或者说在试图上应该放什么东西。
因为是练手玩玩而已,我只提供四个信息,一是用户搜索的城市名称,二是当地城市的zip code,三是当地城市的天气情况,四是当地城市的当前温度。
我允许用户在text field中输入州的名称和城市名称。然后用户通过点击button获取所选城市的天气情况。大概就是这么设计的。

======================================================

从元件中把这些个东西都拖出来,然后向viewController.h 文件中增加outlet。另外Button元件有一个获取数据的动作,同样添加一个action。

大概就是这么个样子。
-(IBAction)getWeather:(id)sender;
这个动作就是点击button然后获取数据。
-(IBAction)pushThenReturn:(sender)

======================================================


======================================================


我在这个程序中,使用了两种方法实现关闭键盘的目的。
第一个是使用上述的pushThenReturn方法。这个实现方法特别简单,在该视图上添加一个button元件,然后将这个元件放到所有元件的最下面,建立一个action,当用户点击这个覆盖整个视图的button之后,释放第一响应状态。就ok了。
具体代码如下:

- (IBAction)pushThenReturn:(id)sender {

    [_cityNameTextFieldresignFirstResponder];

    [_stateNameTextFieldresignFirstResponder];

}

第二种方法是当键盘出来之后,在键盘的右下角有一个return或者是done之类的按键,我们允许用户点击该按键,然后退出键盘。
首先我们需要将我们构造的两个text field元件委托给view试图。然后添加协议<UITextFieldDelegate>,最后添加如下代码到viewController.m文件中。

-(BOOL)textFieldShouldReturn:(UITextField *)textField

{

    if((textField == _cityNameTextField) || (textField ==_stateNameTextField))

    {

        [textField resignFirstResponder];

    }

    return YES;

}

代码的意思是,当第一个文本输入元件或者第二个文本输入元件被激活,点击return按键,我们就释放当前的第一响应状态。

======================================================

这里说下委托是什么意思。
委托是一种设计模式,在之前我也不是很明白这个设计模式的优势是什么。
所谓委托,就是我们不需要关心具体的代码应该什么时候在什么位置执行,我们只需要将我们希望实现的功能委托给相应的程序,然后该程序或者该组件就能在合适的时候调用。大概就是这么个意思。
可以举个更实际话的例子。一个公司里面有一个经理,经理负责整体公司的运营,但是经理的精力有限,他不可能什么事情都自己来做,那么,经理就招聘了一个秘书,这个秘书负责收发文件,接电话,端茶送水什么的乱起八糟的事情。当经理需要收发文件,接电话或者别的事情的时候,他只用通知秘书,说,给我送杯水来。经理不需要具体操心水是怎么接的,应该怎么送来,这些问题由秘书自己解决。在这个例子中,委托的对象就是秘书,经理就是主程序,端茶送水就是委托的具体事情。
那么具体到上一个例子中,我们将text field委托给整个视图程序,当视图检测到text field被激活的时候,某段代码就被激活了。程序员就不用操心到底如何才能退出键盘,只用给一个判断的条件。在上个例子中,当用户点击return按钮的时候,系统就会自动调用。

======================================================

大概就是这么个意思。
下面说说在IOS中如何处理JSON。
事实上,在IOS5.0 以上的版本中,已经内置了解析JSON类的函数。但是考虑到很多用户还是5.0以下的系统(例如我妈和我爹),要解决这个问题可以考虑引入一个第三方的类。
我们使用SBJSON这个第三方的类包(名字起的太好了- -)。
其实我们只需要解析JSON格式中的数据就行了。不需要增删改查等等乱七八糟的功能。基本上我是这么考虑的。
首先我们需要跟目标网站建立连接,然后将获取到的数据读取到内存中,但是这个时候读取到的内容是JSON格式,我们不太好识别,之后我们需要解析JSON文件,将这些内容转换成可以识别的键值表。最后在元件中输出内容就行了。

======================================================

- (IBAction)getWeather:(id)sender {

    NSString *requestUrlSectionOne=[[NSStringalloc]initWithFormat:@"%@",@"http://api.wunderground.com/api/e9777d6c3a883d5b/conditions/q/"];

    NSString *requestUrlSectionTwo=_stateNameTextField.text;

    NSString *requestUrlSectionThree=_cityNameTextField.text;

    NSString *requestUrlSlash=@"/";

    NSString *requestUrlLast=@".json";

    NSString *requestUrl = [NSStringstringWithFormat:@"%@%@%@%@%@", requestUrlSectionOne,requestUrlSectionTwo,requestUrlSlash,requestUrlSectionThree,requestUrlLast];

    //    NSString *requestUrl =@"http://api.wunderground.com/api/e9777d6c3a883d5b/conditions/q/KS/hays.json";

    NSURL *url=[NSURLURLWithString:requestUrl];

    NSURLRequest *urlRequest = [[NSURLRequestalloc]initWithURL:url];

    NSURLConnection *connection = [[NSURLConnectionalloc]initWithRequest:urlRequestdelegate:self];

    [urlRequest release];

    [connection release];

}

这段程序负责获取用户输入内容,然后跟网站建立链接。
其中_stateNameTextField.text和_cityNameTextField.text是用户输入的具体内容,分别是洲的简写和城市名称。当获取到用户数据之后,我们将这些字符串拼接成能够申请数据的合法url。最后建立链接。
在此之前,我们需要使用协议<NSURLConnectionDataDelegate>,但是貌似不添加这个协议同样可以运行相应的协议中的程序。我也不知道为啥- -。

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

    outString = [[NSStringalloc]initWithData:data encoding:NSUTF8StringEncoding];

}

这段程序将获取到的内容放入到一个String类型的字符串中,留作以后处理。

-(void)connectionDidFinishLoading:(NSURLConnection *)connection

{

    NSMutableDictionary *allJsonContent = [outStringJSONValue];

    NSMutableDictionary *jsonValueLevelOne = [allJsonContentobjectForKey:@"current_observation"];

    NSMutableDictionary *jsonValueLevelTwo = [jsonValueLevelOneobjectForKey:@"display_location"];

    _cityNameLabel.text=[[NSStringalloc]initWithFormat:@"%@", [jsonValueLevelTwoobjectForKey:@"full"]];

    _zipCodeLabel.text=[[NSStringalloc]initWithFormat:@"%@", [jsonValueLevelTwoobjectForKey:@"zip"]];

    _weatherLabel.text=[[NSStringalloc]initWithFormat:@"%@", [jsonValueLevelOneobjectForKey:@"weather"]];

    _tempLabel.text=[[NSStringalloc]initWithFormat:@"%@",[jsonValueLevelOneobjectForKey:@"temperature_string"]];

}

首先将获取到得整个数据转换成一层键值表。然后,获取第二层键值表,接着获取第三层键值表。

在之后从键值表中获取具体的内容,并输入到相应的元件中。

然后- -就结束了。


PS:在使用这个免费的天气api之前,我还尝试了另外一个api,程序写得很顺利,但是在测试的时候总是提示 NSInvalidArgumentException', reason: '-[__NSArrayM objectForKey:]: unrecognized selector sent to instance错误,最后仔细的看了一边,才发现这个狗屎网站提供的JSON格式的文件不规范,JSON无法解析,然后就会报错。后来换成NSMutableDictionary类型储存就行了。

原创粉丝点击