BeeFramework 系列三 MVC篇上

这两天死了不少人,南北呼应。厦门的兄弟们别挤brt了,公交有风险,挤车需谨慎!

继续介绍Bee的mvc,框架中已经为MVC做了一定程度的封装,我们查看Bee的源码会发现对应着BeeController、BeeModel以及各种常用的View和ViewController,另外ViewLayout添加了View界面布局的灵活性,从v0.3.0版本开始更是加入了基于XML的UI模板模块。

还是先上个例子比较直观些。
[img]http://dl2.iteye.com/upload/attachment/0085/5804/7feeb6d3-8d37-31fd-be70-2f36b64d5395.jpg[/img]
这个例子,通过访问国家气象局天气预报JSON数据接口,[url]http://www.weather.com.cn/data/sk/101010100.html[/url],返回天气数据。
看下目录结构
[img]http://dl2.iteye.com/upload/attachment/0085/5733/3022b928-285c-3386-a703-def737315c5d.png[/img]
把MVC分离出来放到不同的目录下。
Model层代码:
//
// WeatherModel.h
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-8.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import <BeeFramework/Bee.h>

@interface Weather : BeeActiveRecord

@property(nonatomic,strong) NSString *city;//城市
@property(nonatomic,strong) NSString *temp;//气温
@property(nonatomic,strong) NSString *WD;//风向
@property(nonatomic,strong) NSString *WS;//风力
@property(nonatomic,strong) NSString *time;//发布时间

@end

@interface WeatherModel : BeeModel

@property(nonatomic,strong) Weather *weather;

-(void)loadOnline;//查询天气

-(void)loadCache;//读取历史记录

@end


[code]//
// WeatherModel.m
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-8.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import "WeatherModel.h"
#import "WeatherController.h"

@implementation Weather

+(void)mapRelation{
[super mapPropertyAsKey:@"city"];
[super mapRelation];
}

@end

@interface WeatherModel (private)

- (void)saveCache;
- (void)asyncSaveCache;

@end

@implementation WeatherModel

-(void)loadOnline{
[self sendMessage:WeatherController.LOAD_WEATHER];
}

-(void)loadCache{
int count = Weather.DB.WHERE(@"city",@"北京").COUNT().resultCount;
if (count>0) {
self.weather = [Weather.DB.WHERE(@"city",@"北京").GET_RECORDS() lastObject];
}
}

- (void)saveCache
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
[self performSelector:@selector(asyncSaveCache) withObject:nil afterDelay:0.1f];
}


- (void)asyncSaveCache
{
_weather.SAVE();
}

- (void)handleMessage:(BeeMessage *)msg
{
[super handleMessage:msg];
}

- (void)handleWeatherController:(BeeMessage *)msg
{
if ( [msg is:WeatherController.LOAD_WEATHER] )
{
if ( msg.succeed )
{
NSDictionary *dict = [msg.output dictAtPath:@"result"];
if (dict) {
self.weather = (Weather *)[dict objectForClass:[Weather class]];
[self saveCache];
}

}
}
[super handleMessage:msg];
}

@end[/code]
在.h中定义了一个Weather的实体,与天气数据对应,用到了BeeActiveRecord,这是Bee中的ORM框架,实现数据库与BeeActiveRecord的序列和反序列化。通常我们在做离线缓存时采用CoreData,bee采用的是DB的方式。感谢老郭为我们封装了原来的SQL语法,免去了封装枯燥的SQL语句。查看BeeActiveRecord的父类BeeDatabase,可以看到一些开源软件上用的很欢的以Block为参数的写法。
在.m中通过[code][self sendMessage:WeatherController.LOAD_WEATHER];[/code]向Weathercontroller发送了一个LOAD_WEATHER的请求,在handleWeatherController中响应BeeMessage的不同状态,并完成离线数据的保存工作[code][self saveCache];[/code]

再上Controller的实现
[code]//
// WeatherController.h
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-8.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import "Bee_Controller.h"

@interface WeatherController : BeeController

AS_MESSAGE(LOAD_WEATHER)

@end[/code]

[code]//
// WeatherController.m
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-8.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import "WeatherController.h"
#import "JSONKit.h"
#import <BeeFramework/Bee.h>

@implementation WeatherController

DEF_MESSAGE(LOAD_WEATHER)

-(void)LOAD_WEATHER:(BeeMessage *)msg{
if ( msg.sending )
{
NSString * callURL = @"http://www.weather.com.cn/data/sk/101010100.html" ;
msg.HTTP_GET( callURL );
}
else if ( msg.progressed )
{

}
else if ( msg.succeed )
{
NSDictionary * jsonData = [msg.response objectFromJSONData];
if ( nil == jsonData )
{
[msg setLastError];
return;
}

NSDictionary *weatherinfo = (NSDictionary *)[jsonData objectAtPath:@"weatherinfo"];

[msg output:@"result", weatherinfo, nil];
}
else if ( msg.failed )
{

}
else if ( msg.cancelled )
{
}
}

@end
[/code]
WeatherController完成与天气预报服务器交互的工作,和UISignle类似,在.h中通过AS_MESSAGE(LOAD_WEATHER)定义了一个LOAD_WEATHER的方法声明,在.m中用DEF_MESSAGE(LOAD_WEATHER)对应,并完成LOAD_WEATHER的方法实现。在bee中网络层使用的是ASIHTTPRequest框架,至于为什么不用AFNetworking,这实际上是个人习惯的问题,虽然ASIHTTPRequest已经N久没更新过了,不过也够用了。BeeMessage中对ASIHTTPRequest做了很多工作,通过BeeRequestQueue,对post和get过程中状态的分离。

再来看view层,其实在这个例子中做真正做逻辑的是ViewController,注意它的父类为BeeUIBoard,正是这个类做了UIMessage的消息转发,还实现了ViewController生命周期中的UISignal化。
[code]//
// ViewController.h
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-3.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <BeeFramework/Bee.h>
#import "WeatherModel.h"

@interface ViewController : BeeUIBoard{
__strong WeatherModel *_weatherModel;
__weak IBOutlet UITextView *textView;
}

@end[/code]

[code]//
// ViewController.m
// BeeFrameWorkTest
//
// Created by he songhang on 13-6-3.
// Copyright (c) 2013年 he songhang. All rights reserved.
//

#import "ViewController.h"
#import "WeatherController.h"

@implementation ViewController

-(void)load{
_weatherModel = [[WeatherModel alloc]init];
[_weatherModel addObserver:self];
}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (void)handleUISignal:(BeeUISignal *)signal
{
[super handleUISignal:signal];
}

- (void)handleUISignal_BeeUIBoard:(BeeUISignal *)signal
{
[super handleUISignal:signal];

if ( [signal is:BeeUIBoard.CREATE_VIEWS] )
{
[self showNavigationBarAnimated:YES];
[self showBarButton:UINavigationBar.BARBUTTON_RIGHT system:UIBarButtonSystemItemRefresh];
self.title = @"天气预报";
}
else if ( [signal is:BeeUIBoard.DELETE_VIEWS] )
{
}
else if ( [signal is:BeeUIBoard.LOAD_DATAS] )
{
[_weatherModel loadCache];
[self refushTextView];
}
else if ( [signal is:BeeUIBoard.WILL_APPEAR] )
{

}
else if ( [signal is:BeeUIBoard.DID_DISAPPEAR] )
{
}
}

- (void)handleUISignal_UINavigationBar:(BeeUISignal *)signal
{
if ( [signal is:UINavigationBar.BACK_BUTTON_TOUCHED] )
{
}
else if ( [signal is:UINavigationBar.DONE_BUTTON_TOUCHED] )
{
[self loadOnline];
}
}

-(void)loadOnline{
[_weatherModel loadOnline];
}

-(void)refushTextView{
if (_weatherModel.weather) {
Weather *weather = _weatherModel.weather;
NSString *weatherInfo = [NSString stringWithFormat:@"城市:%@\n气温:%@\n风向:%@\n风力%@\n发布时间:%@,",weather.city,weather.temp,weather.WD,weather.WS,weather.time];
textView.text = weatherInfo;
}
}

- (void)handleMessage:(BeeMessage *)msg
{
[super handleMessage:msg];
}

- (void)handleWeatherController:(BeeMessage *)msg
{
[super handleMessage:msg];

if ( [msg is:WeatherController.LOAD_WEATHER] )
{
if ( msg.sending )
{
BeeUIActivityIndicatorView * indicator = [BeeUIActivityIndicatorView spawn];
[self showBarButton:UINavigationBar.BARBUTTON_RIGHT custom:indicator];
[indicator startAnimating];
}
else
{
[self showBarButton:UINavigationBar.BARBUTTON_RIGHT system:UIBarButtonSystemItemRefresh];
}


if ( msg.succeed )
{
[self refushTextView];
}
}
}

@end
[/code]

[img]http://dl2.iteye.com/upload/attachment/0085/5788/9e6fe758-a095-36fd-aeab-d72a8db22776.jpg[/img]

这里应注意ViewController.m中的代码:[code]-(void)load{
_weatherModel = [[WeatherModel alloc]init];
[_weatherModel addObserver:self];//注意点!!!
}[/code],结合WeatherModel.m中的[code]- (void)handleWeatherController:(BeeMessage *)msg
{
if ( [msg is:WeatherController.LOAD_WEATHER] )
{
if ( msg.succeed )
{
NSDictionary *dict = [msg.output dictAtPath:@"result"];
if (dict) {
self.weather = (Weather *)[dict objectForClass:[Weather class]];
[self saveCache];
}

}
}
[super handleMessage:msg];//注意点
}[/code]
如果把[code][super handleMessage:msg];[/code]去掉,那么ViewController中的handleMessage和handleWeatherController将无法响应。

本篇通过天气预报介绍了Bee中的MVC的实现场景,当然你也可以根据自己的需要选择适用的模块,你可以在Model中直接实现网络层交互,也可以去掉model层,直接在UIBoard中调用BeeController,怎么选择还是看个人习惯。

以上代码下载:[url]https://github.com/ilikeido/BeeFrameworkTest/tree/master/lesson4[/url]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值