一.系统功能概览图
从系统功能概览图中可知,天气预报分为服务器端(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 }
以上两步完成代理工作。
五 个人期待
应用尚不完善,我希望能够到一家公司学习,与公司一起成长。最后,能够独立开发出一款优秀的应用。
希望有公司给一个机会。