來自本羣【言志_iOS_廈門】的投稿,當天預約,當天出稿子,很感謝每一個支持Mark羣的人。附加補充Demo點擊下載
簡單總結下Blog內容就是 “把數據層抽離出來 ,解析MVC模式,是一個MVC的應用實例,在網絡請求時,將MVC分離。
個人覺得這個分享很實用,還包含了設計模式的理念在裏面。
以下是言志兄的分享內容:
2.如果沒有很好的MVC概念,估計會把這些東西東西全部寫在ViewController裏面。
================================華麗的分割線===============================
一.講解如何將這個過程區分開
1.曾經我一直堅信不疑的以爲ViewController是一個C()。後來才知道ViewController類和所有的控件都是屬於MVC中的V(View)(當我知道這個以後,萬念俱灰啊)。
2.C的作用就是將ViewController和Modal相連接。
3.MVC的順序: V->C->M M-C->V。下面4-9就闡述了這麼一個過程。
4.ViewController類中的click()方法調用了Controller類中refresh()方法。
5.getInformation()方法裏調用了NetWork()類中的request();
6.request()請求完成後,等待系統調用- (void)connectionDidFinishLoading:(NSURLConnection *)connection()方法。
7.- (void)connectionDidFinishLoading:(NSURLConnection *)connection()方法通過NetWork類中的delegate,去調用refresh()方法[_delegate refresh]。
8.在Controller中具體實現refresh(),通過Controller中的delegate,去調用getInformationFromRequest()協議 [delegate getInformationFromRequest];
9.最後在ViewController中具體實現getInformationFromRequest()方法。
=======================V->C->NetWork->Modal========================
ViewController類中點擊按鈕觸發事件
//請求Flurry API
- (IBAction)getEventsInformation:(id)sender
{
Reachability *r = [Reachability reachabilityWithHostName:@"baidu.com"];
switch ([r currentReachabilityStatus]) {
case NotReachable:
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"網絡異常" message:@"請檢查下網絡" delegate:self cancelButtonTitle:@"好的" otherButtonTitles:nil, nil];
[alert show];
break;
}
case ReachableViaWWAN:
{
}
case ReachableViaWiFi:
{
}default:
{
//調用MBProgressHUD這個方法,在網絡請求的時候就會轉圈圈了!圈圈啊~畫圈圈詛咒你。
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
//_requestController是MVC中的C(Controller)
[_requestController getInformation];
}
}
}
//RequestController類
- (void)getInformation
{
//_request爲網絡請求的實例
[_request requestFlurry];
}
//EventRequest類
@protocol EventRequestDelegate <NSObject>
@required
- (void)refresh;
- (void)refreshFail;
@end
@interface EventRequest : NSObject<NSURLConnectionDataDelegate>
@property (nonatomic,weak) id<EventRequestDelegate> delegate;
@implementation EventRequest
//請求Flurry
- (void) requestFlurry
{
_eventData = [[NSMutableData alloc] init];
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:Flurry_Event_URL,Access_Code,BEAUTY_FLURRY_APPKEY,Start_Time,[EventRequest getAmericaTime]]];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection start];
}
//因爲網絡數據是分批進來的,所以將每次獲得的data數據追加到 _eventData中
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[_eventData appendData:data];
}
//獲取數據並寫到plist文件中
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
_totalInformation = [[TotalInformation alloc] init];
NSError *jsonError;
//TotalInformation爲Modal,Request請求後所獲得的數據保存到_totalInformation中。
_totalInformation.totalDic = [NSJSONSerialization JSONObjectWithData:_eventData options:0 error:&jsonError];
//將數據寫到plist文件中,以後讀取數據可以直接訪問本地的plist文件進行讀取
[_totalInformation writeToPlist];
//通過委託調用refresh
[_delegate refresh];
// [MatchingData match:[_totalInformation readFromPlist] withPlist:@"1001"];
NSLog(@"Finish");
}
//數據獲取失敗調用該方法
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
if (error) {
NSLog(@"%@",error);
//通過委託調用refreshFail
[_delegate refreshFail];
}
}
//TotalInformation類
@property (nonatomic,strong) NSDictionary *totalDic;
@property (nonatomic,strong) NSArray *event;
//至於是NSDictionary還是NSArray,需要根據你返回的數據來決定
//存入plist文件
- (void)writeToPlist
{
_event = [_totalDic objectForKey:@"event"];
NSFileManager* fm = [NSFileManager defaultManager];
[fm createFileAtPath:Total_Information_Path contents:nil attributes:nil];
NSLog(@"%@",Total_Information_Path);
[_event writeToFile:Total_Information_Path atomically:YES];
NSLog(@"%@",_event);
}
//從plist文件中讀取
- (NSArray *)readFromPlist
{
_event = [NSArray arrayWithContentsOfFile:Total_Information_Path];
return _event;
}
=======================NetWork->C->View========================
//RequestController類
@protocol RequestControllerDelegate <NSObject>
@required
- (void)getInformationFromRequest;
- (void)getInformationFromRequestFail;
@end
@interface RequestController : NSObject<EventRequestDelegate>
@property (nonatomic,strong) TotalInformation *totalInformation;
@property (nonatomic,weak) id<RequestControllerDelegate> delegate;
@implementation RequestController
//初始化時設置request.delegte = self; 這樣纔會調用下面的refresh()和refreshFail()方法
- (id)init
{
if (self = [super init])
{
_request = [[EventRequest alloc]init];
_request.delegate = self;
}
return self;
}
//實現EventRequestDelegate協議中的方法
//網絡請求成功時
- (void)refresh
{
[_delegate getInformationFromRequest];
}
//網絡請求失敗時
- (void)refreshFail
{
[_delegate getInformationFromRequestFail];
}
//ViewController
//記得寫RequestControllerDelegate
@interface ViewController : UIViewController<MBProgressHUDDelegate,RequestControllerDelegate>
@implementation ViewController
//設置RequestController的delegate.
- (void)viewDidLoad
{
_finishLabel.hidden = YES;
_requestController = [[RequestController alloc] init];
_requestController.delegate = self;
[super viewDidLoad];
// self.delegate = self;
// Do any additional setup after loading the view, typically from a nib.
}
//實現RequestControllerDelegate中的兩個方法
#pragma mark - RequestControllerDelegate methods
//刷新完成,隱藏指示器和Label
- (void)getInformationFromRequest
{
//請求成功後將圈圈隱藏掉
[MBProgressHUD hideHUDForView:self.view animated:YES];
//To-do 這裏可以通過Controller類來調用Modal中的數據,將Modal中的數據賦值給對應的視圖
}
//刷新異常,隱藏指示器和Label
- (void)getInformationFromRequestFail
{
//請求失敗後也將圈圈隱藏掉
[MBProgressHUD hideHUDForView:self.view animated:YES];
//To-do 這裏可以通過Controller類來調用Modal中的數據,將Modal中的數據賦值給對應的視圖
}
-------------------------------------------------------------------------------------------------------------------------------------
附上言志兄弟的原稿JPG