NSURLconnection在另一个类中

时间:2013-09-24 17:20:10

标签: ios objective-c nsurlconnection

我正在尝试开发一个应用程序来接收来自Web服务的数据,以便在某些视图中显示。 在应用程序的第一个版本中,我只有一个视图控制器和一个GET请求到Web服务(通过NSURLconnection):NSURLconnection的所有方法都在Viewcontroller中,一切运行良好。

现在我需要添加其他视图并发出一些其他GET请求,所以我认为最好的方法是应用MVC模式:特别是我创建了一个类(FV_Data),我把所有的GET请求和管理NSURLconnections,而在每个ViewController中,我调用方法(在FV_Data类中)以获取所需的GET请求。

我的问题是如何将带有来自Web服务的数据的数组返回到要求数据的ViewController:在我的第一次测试中,NSURLconnection正确启动并且数组(在connectionDidFinishLoading方法中)填充了来自Web服务的数据,但在View Controller中,数组为空。

我读过不同的帖子,但我无法理解我做错了什么。

这是我编写的代码(我省略了有效方法中的代码)。

谢谢, 的Corrado

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

3 个答案:

答案 0 :(得分:2)

哦伙计......网络请求需要时间才能完成,所以你应该设置你查看(energia.text)之后的连接DidFinishLoading:
对不起,看来你正在发明一辆自行车。如果您知道块如何在Objective-C中工作,我建议使用AFNetworking框架。
如果您不知道块是如何工作的 - 首先阅读 Apple doc about blocks - 真的有必要成功开发iOS / OS X

答案 1 :(得分:1)

您的connectionDidFinishLoading已成功完成下载,但您似乎没有采取任何措施告诉视图控制器在数据请求完成时更新用户界面。您希望这样做,因为加载过程是异步进行的。例如,如果您在viewDidLoad中启动此过程,则在viewDidLoad完成之后,加载将始终不完整。

您需要提供一些机制,FV_Data可以通知FV_Live_ViewController请求已完成,此时您的视图控制器将使用新数据更新UI。两种典型的方法是:

  • 实现您自己的委托协议模式,这是一种相当传统的解决方案,通过这种模式,您的FV_Data可以通知视图控制器请求已完成。请参阅 Cocoa Core Competencies 中的Delegation Pattern。这类似于您在NSURLConnectionDataDelegate中实施的FV_Data方法,但在这种情况下,不是NSURLConnection通知FV_Data的机制。信息,它将是FV_Data通知FV_Live_ViewController

  • 的机制
  • 使用完成块,这是一个更现代的解决方案,FV_Live_ViewController可以在请求完成时通知FV_Data该做什么。这类似于您在AFNetworking或sendAsynchronousRequest等Cocoa方法中看到的内容。

但在你深入研究这两种方法之前,我必须说我对你FV_Data做两个单独的请求的架构并不感到骄傲,导致两组类属性和重复方法中的代码。稍微不同的类结构可以最小化这个冗余代码(当前代码只会使错误机会的数量翻倍)。

此外,我将更进一步,第二个Petro建议您考虑使用经过验证的现有第三方框架来管理这些请求,例如AFNetworking。基于NSOperation的方法(如AFNetworking)提供了许多优点,但优雅的实现可能很复杂(因此建议使用AFNetworking,它可以享受这些优势,同时让您远离实施的杂草)。不幸的是,像NSURLConnection这样的sendAsynchronousRequest方法看起来很方便,但却受到了真正的限制。

我们很乐意为您提供帮助,但只是一个建议。

答案 2 :(得分:-1)

看起来你正在尝试使用它 sendAsynchronousRequest:queue:completionHandler: 可能比实施代表更合适。