2013-09-24 23 views
0

我想開發一個應用程序接收來自Web服務的數據,以顯示在一些視圖。 在應用程序的第一個版本中,我只有一個視圖控制器和一個對Web服務的GET請求(通過NSURLconnection):NSURLconnection的所有方法都在Viewcontroller中,並且一切正常。在不同的類NSURLconnection

現在我需要添加其他視圖並做出其他的GET請求,所以我想最好的辦法是應用MVC模式:特別是我創建了一個類(FV_Data),我把所有的GET請求並管理NSURLconnections,而在每個ViewController中,我調用方法(在FV_Data類中)獲取所需的GET請求。

我的問題是如何將數據從Web服務返回到請求數據的ViewController:在我的第一次測試中,NSURLconnection已正確啓動,並且數組(在connectionDidFinishLoading方法中)中填充了來自Web服務的數據,但在View Controller中,數組是空的。

我讀過不同的帖子,但我不明白我做錯了什麼。

這是我寫的代碼(我省略了工作方法中的代碼)。

感謝, 科拉多

FV_Data.h

#import <Foundation/Foundation.h> 

@interface FV_Data: NSObject { 

    NSMutableData *responseStatistic; 
    NSMutableData *responseGetStatus; 

    NSURLConnection *connectionStatistic; 
    NSURLConnection *connectionGetStatus; 
} 

-(NSArray *)richiediGetStatistic; 
-(NSArray *)richiediGetStatus; 


@property (nonatomic, retain) NSArray *ArrayStatistic; 
@property (nonatomic, retain) NSArray *ArrayGetStatus; 


@end 

FV_Data.m

#import "FV_Data.h" 

@implementation FV_Data 

-(id)init { 
    self = [super init]; 
    return self; 
} 

-(void)richiediGetStatistic{ 
    ... 
} 

-(void)richiediGetStatus{ 
    ... 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 
... 
} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 
    ... 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 

    if(connection == connectionStatistic){ 
     NSString *responseStatisticString = [[NSString alloc] initWithData:responseStatistic encoding:NSUTF8StringEncoding]; 
     self.ArrayStatistic = [responseStatisticString componentsSeparatedByString:@","]; 
    } 

    else if(connection == connectionGetStatus){ 
     NSString *responseGetStatusString = [[NSString alloc] initWithData:responseGetStatus encoding:NSUTF8StringEncoding]; 
     self.ArrayGetStatus = [responseGetStatusString componentsSeparatedByString:@","]; 
    } 
} 

@end 

FV_Live_ViewController.h

#import <UIKit/UIKit.h> 
#import "FV_Data.h" 

@interface FV_Live_ViewController : UIViewController { 
    IBOutlet UILabel *energia; 
} 

@property (nonatomic, retain) FV_Data *PVOutputData; 

@end 

FV_Live_ViewController.m

#import "FV_Live_ViewController.h" 

@implementation FV_Live_ViewController 

-(void)viewWillAppear:(BOOL)animated{ 

    self.PVOutputData = [[FV_Data alloc] init]; 

    [self.PVOutputData richiediGetStatistic]; 

    energia.text = [self.PVOutputData.ArrayStatistic objectAtIndex:0]; 
} 

@end 
+0

我建議你考慮採用Apple建立的[命名約定](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Conventions/Conventions.html),特別是使用camelCase,小寫第一個字母的變量,只使用前導大寫字母的類,不使用下劃線等。 – Rob

回答

1

connectionDidFinishLoading成功完成下載,但你似乎並沒有做任何事告訴視圖控制器在數據請求完成時做任何事情來更新用戶界面。你想這樣做,因爲加載過程是異步發生的。例如,如果您在viewDidLoad中啓動此過程,則裝載將始終不完全,直到完成viewDidLoad之後。

您需要提供某種機制,FV_Data可以通過該機制通知FV_Live_ViewController請求已完成,此時您將讓視圖控制器使用新數據更新UI。這兩種典型的方式是:

  • 實現自己的委託協議模式,一個相當傳統的解決這類問題,通過你的FV_Data可以通知要求完成視圖控制器。請參閱可可核心競爭力中的Delegation Pattern)。這類似於您在FV_Data中實施的NSURLConnectionDataDelegate方法,但在這種情況下,它不是通知FV_Data通知FV_Data的機制,而是FV_Data通知FV_Live_ViewController的機制。

  • 使用完成塊,更現代的解決方案,FV_Live_ViewController可以通知FV_Data請求完成後該怎麼做。這與您在AFNetworking中看到的類似,或類似於sendAsynchronousRequest等可可方法。

但是你潛入進過多任一方法之前,我必須說,我不是瘋了約由你FV_Data做兩個獨立的請求架構,導致兩套類的屬性和重複的代碼在方法中。稍微不同的類結構可以使這種冗餘代碼最小化(目前的代碼只會使出錯機會增加一倍)。

此外,我會更進一步,第二個Petro建議您考慮使用經過驗證的現有第三方框架來管理這些請求,例如AFNetworking。像AFNetworking這樣的基於的方法提供了許多優點,但優雅的實現可能是複雜的(因此建議使用AFNetworking,它享有這些優點,同時避免實施雜草)。不幸的是,NSURLConnection方法如sendAsynchronousRequest看起來方便,但受到實際限制。

我們很樂意爲您提供幫助,但只是一個建議。

+0

感謝您的詳細解答。我仍然有點困惑(還有很多要了解塊,...),但我會嘗試研究和實施這個解決方案。 – Corrado

+0

@Corrado如果您使用AFNetworking,它使用塊,但也比從頭開始實施基於塊的解決方案容易得多。 AFNetworking將是一個很好的方式來獲得使用塊的一些舒適。一旦你非常熟悉這種模式,那麼你可以考慮實現你自己的基於塊的實現。祝你好運。如果有什麼我們可以幫助的,請告訴我們。 – Rob

-1

它看起來像你想使用 sendAsynchronousRequest:queue:completionHandler: 可能是一個比實現委託更適合做什麼。

2

噢,夥計......網絡請求需要時間來完成,所以你應該設置你瀏覽(energia.text)後connectionDidFinishLoading:
我很抱歉,但似乎你正在發明自行車。如果你知道在Objective-C中塊如何工作,我建議使用AFNetworking框架。
如果你不知道如何塊工作 - 讀 Apple doc about blocks第一 - 這是真的有必要研製成功適用於iOS/OS X

+0

AFNetworking(或某種基於操作的方法)當然是比OP建議的更好的體系結構。好建議。 – Rob