這一次分享一下BeeMessage, BeeModel, 和BeeUISignal。這三個東東就是Controller, Model, 和Event的主要實現。您也可以到Bee的/documents/developer_manual.pdf中查看詳細的開發手冊,希望您看了這篇文章能對這幾個組件理解更深,適合干什麼,從而更得心應手得使用。本文試圖解答幾個問題:
BeeMessage是如何實現的?如何做到封裝Http過程的,有什麼優缺點和適用場合? BeeModel是如何實現的?和Core Data在使用上有何取捨?有哪些使用方式滿足不同的需求? BeeUISignal是如何實現的?為了滿足什麼需求而實現成這樣?與NSNotification比較有什麼優缺點和適用場合? A1:BeeMessage就是對網絡數據請求的封裝,也就是常說的“協議”。BeeMessage和BeeHttpRequest(ASIDataFormRequest的封裝)協同工作,通過內置的多個狀態更新同步BeeHttpRequest的狀態。包括發送和接收請求,解析數據,將數據發送給感興趣的上層對象(UI或Model)。BeeMessage和BeeHttpRequest都持有responder數據成員,其中BeeHttpRequest的Responder就是對應的BeeMessage, BeeMessage對應的Responder就是對BeeMessage感興趣的UI或者Model。看下圖:
可以看到,UIResponder將創建BeeMessage,填入Http參數,並將自己傳入做為Responder。BeeMessage將自己傳入BeeHttpRequest。UIResponder通過BeeMessage提供的Block來檢查BeeMessage的狀態。BeeMessage和BeeHttpRequest都實現為6個子狀態,表示Http請求的狀態流轉並同步。這些狀態流轉都在BeeMessage的routine函數裡完成。來看看UIResponder,和BeeMessage
routine的代碼:
-(void) getNewsList {
BeeMesage * api = [API_NEWS_LIST api];//加入Http參數
api.INPUT( @"uid", [NSString stringWithFormat:@"%d", _uid]);api.whenUpdate = ^ { if ( api.sending ) { //處理發送 } else if(api.succeed) {
//發送成功,獲得BeeMessage解析好的數據
[self.news addObjectsFromArray:api.resp.news];
}
else if ( api.failed )
{ //處理失敗
}
else if ( api.cancelled )
{ //處理取消
}
};
[api send];}
- (void)routine
{
if ( self.sending )
{
NSString * requestURI = [[[ServerConfig sharedInstance] url] stringByAppendingString:api_news_list];
self.HTTP_GET( requestURI );
}
else if ( self.succeed )
{
NSError* error; //通過XML解析回文
CXMLDocument * document = [[CXMLDocument alloc] initWithXMLString:self.responseString options:NSUTF8StringEncoding error:&error];
NSArray* newslist = [document nodesForXPath:@"oschina/newslist/news" error:&error];
for ( CXMLElement* newsXML in newslist )
{
if(newsXML == nil) continue;
NEWS* news = [NEWS createByXML:newsXML];
[self.resp.news addObject:news];
}
if ( nil == self.resp || NO == [self.resp validate] )
{
self.failed = YES;
return;
}
}
else if ( self.failed )
{
}
else if ( self.cancelled )
{
}
}
@end- (void)firstPage
{
_pages = 0;
[API_POST_LIST cancel];
API_POST_LIST *api = [API_POST_LIST api];
//每頁20個
api.INPUT( @"pageIndex", @"0" );
api.INPUT( @"pageSize", @"20" );
api.whenUpdate = ^
{
@normalize( api );
if ( api.sending )
{
[self sendUISignal:self.RELOADING];
}
else if ( api.succeed )
{
//第一頁拉取成功
[self.posts removeAllObjects];
[self.posts addObjectsFromArray:api.resp.posts];
self.loaded = YES;
self.pages = 1;
[self sendUISignal:self.RELOADED];
}
else if ( api.failed )
{
[self sendUISignal:self.RELOADED];
}
};
[api send];
}
- (void)nextPage
{
[API_POST_LIST cancel];
API_POST_LIST *api = [API_POST_LIST api];
int curBegin = self.pages * 20;
int curEnd = curBegin + 20;
api.INPUT( @"pageIndex", [NSString stringWithFormat:@"%d", curBegin]);
api.INPUT( @"pageSize", [NSString stringWithFormat:@"%d", curEnd] );
api.whenUpdate = ^
{
@normalize( api );
if ( api.sending )
{
[self sendUISignal:self.RELOADING];
}
else if ( api.succeed )
{ //處理下一頁
if( _pages == 0)
{
[self.posts removeAllObjects];
}
[self.posts addObjectsFromArray:api.resp.posts];
self.loaded = YES;
self.pages = self.pages + 1;
[self sendUISignal:self.RELOADED];
}
else if ( api.failed )
{
[self sendUISignal:self.FAILED];
}
else if ( api.cancelled )
{
[self sendUISignal:self.CANCELLED];
}
};
[api send];
}