IOS_網絡請求中的MVC應用(數據模型類)

來自本羣【言志_iOS_廈門】的投稿,當天預約,當天出稿子,很感謝每一個支持Mark羣的人。附加補充Demo點擊下載

簡單總結下Blog內容就是 “把數據層抽離出來 ,解析MVC模式,是一個MVC的應用實例,在網絡請求時,將MVC分離。

個人覺得這個分享很實用,還包含了設計模式的理念在裏面。

以下是言志兄的分享內容:


1.在初學iOS時,大部分人會遇到的頭疼問題是:用NSURLConnection請求一個URL,然後將返回的數據顯示到UIView上。
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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章