iOS天气预报

一.系统功能概览图

从系统功能概览图中可知,天气预报分为服务器端(python编写),客户端(objective-c编写),还有没有标明的通讯端(Thrift框架)。


 

二.服务器端

服务器由python编写,负责从(http://www.weather.com.cn/)抓取数据。

我在这里遇到的较大的问题是,如何从网页中抓取获得通过javascript动态添加的标签中的数据。如果通过请求(request),让后打开url(urlopen)是无法将数据加载进来的。我通过查阅资料"pygtkwebkit"是一个不错的解决方案。我使用"pyqt"来解决我的问题。同样是GUI模块+webkit。pyqt完全可以做到pygtkwebkit能做的,而且参考资料更加丰富。

服务器在抓取完数据后,将数据格式化为json格式,然后在客户端请求时,告诉客户端json的URL(http协议)。

服务器端为上传的图片保存"服务器保存路径"及"图片描述"。考虑到Thrift的传输数据不能是大量数据,我还是使用的http协议来传输图片,告诉客户端图片URL,让客户端去下载图片,减轻通讯压力。


 

三.客户端

客户端由iOS编写,使用ARC+Storyboard。

上图为天气预报的Stroyboard,清晰展示了所有界面以及他们之间的联系。

图下面有对图的说明。

这是应用主界面,以上数据均来自中国天气网,由服务器端抓取。客户端负责抓取。

点击下面那个箭头,将缓慢展开一个view,里面是当天的生活气象指数,一共有9个,我选用scrollview,可以左右滑动来看这些指数。图中看到化妆指数,过敏指数(数据来自中国天气网)。

应用采用侧边栏样式作为基本样式,用手指向右滑动,将看到如图所示的界面。

删除城市用了tableview自带的删除功能,这也是我觉得需要改进的地方。

这边是搜索界面,以及搜索三亚,界面不够好看。只能对中文进行过滤,并不支持拼音搜索,这里也需要改进。

新浪微博发送,以及我微博的一个截图。

这是图片上传界面,左边时从相册中选取的图片,右边是对图片的描述。在上传图片时,使用base64编码将图片转换成字符串形式。服务器获取数据后则用base64解码,将字串重新转换成图片。这样做的好处,便于数据的分次传输,最后到达服务器只需要做字串拼接就可以了,大大方便了传输。从另一外方面来说,Thrift有原生string类型,免去了自定义数据结构的麻烦。

这个是查看同城图片功能,最后一张是我刚刚上传的图片,这里用到了线程池技术,使用NSOperation和NSOPerationQueue这两个类大大简化了线程管理难度。这样做首先不会阻塞UI,在使用者的机子资源充足的情况下,下载速度将高于单线程下载速度。

说明:界面并没有优化,本想使用瀑布流样式,当目前并未加入。这个功能设计是想让用户看到同一个城市其他用户上传的图片,类似“墨迹天气的时景”。但是在许多方面,还是不尽如人意。


 

三.Thrift框架

这个框架时Facebook的一个开源项目,简单易用并且跨语言。这为我解决了服务器端和客户端通讯问题。

Thrift的参考资料并不多,以我目前的水平,阅读whitepaper,完全读懂还是有压力。但在使用过程中我还是认为thrift是一个好东西,简单易用。

举例来说,thrift让服务器与客户端进行1对多的连接提供几种方法:TSimpleServer(单连接),TThreadPoolServer(1对多,阻塞连接),TNonblockingServer(无阻塞连接)。而开发者需要做的只是调用这个函数(或类)。就可以完成,很方便。

由于自己堆这个研究也是一知半解,不敢赘述。


四.自己的总结

ARC大大减少了开发者的负担,开发者并不需要手动管理内存。ARC不是垃圾回收机制,而是编译器的优化。苹果公司鼓励开发者使用这个技术,我也尝试使用,的确方便。

block是对c语言的扩展,是一个神奇的技术,objective-c基础编程第二版中,已经单独为这个技术写了一章介绍,可惜目前只有英文版,没有中文版。

block的多线程:

 1     //异步加载数据
 2     [SVProgressHUD showWithStatus:kWeatherloadTip maskType:SVProgressHUDMaskTypeGradient];
 3     dispatch_queue_t queue = dispatch_queue_create("com.mfj.queue",nil);
 4     dispatch_async(queue, ^{
 5         CYCity *city = [[CYCity alloc] initWithCityName:[CYSingleton shared].currentCity];
 6         dispatch_async(dispatch_get_main_queue(), ^{
 7             //将城市添加到单例字典中区
 8             [[CYSingleton shared].cityModel setObject:city forKey:city.name];
 9             [self showWithCity:city];
10             [SVProgressHUD dismiss];
11         });
12     });

苹果公司在iOS中也开始大量使用block,比如动画:

 1 -(void)hidePanel
 2 {
 3     __block CGRect frame = self.frame;
 4     if (self.isExpend) {
 5         [self.eb setImage:[UIImage imageNamed:@"iconExpand.png"] forState:UIControlStateNormal];
 6         
 7         [UIView animateWithDuration:0.7f animations:^{
 8             frame.origin.y += 106;
 9             self.frame = frame;
10             self.isExpend = NO;
11         }];
12     }
13 }

block还能代替delegate:

 1 //赋值
 2 self.panelView.panelBlock = ^{
 3         return city.indexArray;
 4    }; 
 5   
 6 //调用
 7 NSArray *indexArray = [NSArray array];
 8  if (self.panelBlock != nil) {
 9         indexArray = self.panelBlock();
10     }

以上两步完成代理工作。


五 个人期待

应用尚不完善,我希望能够到一家公司学习,与公司一起成长。最后,能够独立开发出一款优秀的应用。

希望有公司给一个机会。

 

 

 

posted on 2013-06-14 11:54  week_translator  阅读(826)  评论(0编辑  收藏  举报