NSURLConnection代表

时间:2012-06-04 18:25:46

标签: objective-c ios nsurlconnection

... REVISED

应用程序的关键是与数据库服务器通信。从服务器到应用程序的响应都是XML格式的。有几个屏幕。例如,屏幕1列出了用户的信息,屏幕2列出了用户的过去交易,允许新的交易,等等。

以下是我的AppDelegate的一些代码:

StartViewController *svc = [[StartViewController alloc] init];
TradeViewController *tvc = [[TradeViewController alloc] init];
CashViewController *cvc = [[CashViewController alloc] init];
ComViewController *covc = [[ComViewController alloc] init];
PrefsViewController *pvc = [[PrefsViewController alloc] init];

NSMutableArray *tabBarViewControllers = [[NSMutableArray alloc] initWithCapacity:5];
UITabBarController *tabBarController = [[UITabBarController alloc] init];

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:svc];
[tabBarViewControllers addObject:navigationController];
navigationController = nil;

navigationController = [[UINavigationController alloc] initWithRootViewController:tvc];
[tabBarViewControllers addObject:navigationController];
navigationController = nil;

navigationController = [[UINavigationController alloc] initWithRootViewController:cvc];
[tabBarViewControllers addObject:navigationController];
navigationController = nil;

navigationController = [[UINavigationController alloc] initWithRootViewController:covc];
[tabBarViewControllers addObject:navigationController];
navigationController = nil;

navigationController = [[UINavigationController alloc] initWithRootViewController:pvc];
[tabBarViewControllers addObject:navigationController];
navigationController = nil;

[tabBarController setViewControllers:tabBarViewControllers];

[[self window] setRootViewController:tabBarController];

self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];

尝试坚持MVC风格,我有一个单独的类,可以完成所有的“处理”。

现在举例说明我如何碰壁...用户可以在屏幕上更改他们的电子邮件地址5.在文本字段中输入新的电子邮件地址,然后单击保存按钮。该按钮然后从singleton类调用一个方法,该方法将新的电子邮件地址发送到服务器并(通过URL)并接收确认更改的XML响应。

以下是我的问题: 1.在我进行单例类方法调用之前,我从视图控制器启动微调器 - 但不知道服务器发送/接收的应用程序何时完成,如何让微调器在正确的时间停止?我不能从单身课那里得到它,我试过了。据我所知,它必须来自VC内部,或者有没有办法从我的单例类改变VC输出?

  1. 单例类NSURLConnection正在处理我的所有通信。从简单的电子邮件一直到更新事务表的所有内容。这对我来说似乎不对,并且很难跟踪谁在调用什么。再次,我将通过我对MVC的解释。我认为为每个VC创建一个NSURLConnection并在这些类中进行一些处理要容易得多。然而,那不是MVC(ish)。

  2. 我接近100个变量,数组等...在我的单例类中,我用它来为我的所有VC赋值。这对我来说似乎也是错的,但我想不出任何其他方式。

5 个答案:

答案 0 :(得分:3)

  

我如何区分NSURLConnection委托   (connectionDidFinishLoading)正在进行哪个URL调用?

每个委托方法(例如-connectionDidFinishLoading:)都有一个connection参数,告诉您哪个连接发送了该消息。给定的连接一次只能加载一个URL,因此URL和连接之间存在一对一的对应关系。

  

下载完成后如何在“connectionDidFinishLoading”之外说出来?

该方法在连接完成时告诉您。您可以将这些信息存储在对您的应用程序有用的地方。

更新:根据您添加的内容,您的“处理”类是您应用的型号。应用程序的其余部分不应该关心每个事务都涉及到服务器的消息 - 这只是模型的业务。此外,模型不必是单个对象(更不用说单个对象) - 它可以是一组协同工作的对象。

所以,你可能有一个类(让我们称之为Processor)代表应用程序与模型的接口(有些人甚至称之为“模型控制器”)。 Processor的实例可能会创建一个本地数据库来存储app的当前本地状态。您可能还有一个Transaction类,它表示与服务器的单个事务。事务可以创建请求,将其发送到服务器,获取响应,更新数据库,并告知处理器事务已完成。或者,当应用程序的某个其他部分(如您的一个视图控制器)要求处理器处理新事务时,处理器会将请求对象传递给它创建的事务,以便事务可以直接更新请求程序。

很难说你的应用程序的最佳计划是什么,而不知道你计划在哪里采取它,但通常的指导方针有:

  • 将您的问题分解为更容易解决的部分

  • 限制每个班级职责的范围

  • 如果事情似乎很复杂,可能是

将您的模型分解为几个类也会使测试更容易。您可以想象为Transaction类编写一组单元测试是多么容易。处理器也是如此 - 如果服务器事务处理器处于不同的类中,则更容易测试处理器正在做正确的事情。

答案 1 :(得分:1)

如果同一个委托有多个NSURLConnections,请考虑使用全局(好吧,更确切地说是一个实例变量)NSMutableDictionary实例,在该实例中,根据调用的NSURLConnection存储数据。例如,您可以使用转换为NSString的连接的内存中地址(类似

[NSString stringWithFormat:@"%p", connection]

应该做的伎俩。)

此外,在connectionDidFinishLoading:connection:didFailLoadWithError:方法中,删除与NSURLConnections对应的键。因此,如果连接完成,您可以从“外部”告诉它:只检查它是否在字典中。

答案 2 :(得分:1)

如果您通过网络连接下载任何数据,我建议您使用ASIHttpRequest。这将允许您异步下载文件,这意味着您的界面在下载过程中不会冻结。

如果您使用ASIHttpRequest,还可以设置didFinishSelector。通过这样做,您可以控制在特定URL加载完成后调用哪个方法。

看看这个:

NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

[request setDelegate:self];
[request startAsynchronous];
[request setDidFinishSelector:@selector(requestDone:)];

然后:

- (void)requestDone:(ASIHTTPRequest *)request
{
   // Use when fetching text data
   NSString *responseString = [request responseString];

   // Use when fetching binary data
   NSData *responseData = [request responseData];

   // If you want, you can get the url of the request like this
   NSURL *url = [request url];
}

至于问题的第二部分,如果未调用requestDone:方法,则表示下载尚未完成。

如果您想要通过多次下载执行更复杂的操作,ASIHttpRequest也提供了队列功能。看看here

答案 3 :(得分:1)

我建议继承NSURLConnection。只需添加两个属性:NSInteger,tag和BOOL,isFinished。这样,您可以为每个不同的请求#define标记,然后在您的委托方法中通过标记来标识它们。在connectionDidFinishLoading中,您可以将isFinished BOOL设置为YES,然后您可以检查其他方法是否已完成连接。


这是我自己的NSURLConnection子类,TTURLConnection:

<强> TTURLConnection.h:

#import <Foundation/Foundation.h>

@interface TTURLConnection : NSURLConnection <NSURLConnectionDelegate>

@property (nonatomic) NSInteger tag;
@property (nonatomic) BOOL isLocked;

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:
    (BOOL)startImmediately tag:(NSInteger)tagParam;

@end

<强> TTURLConnection.m:

#import "TTURLConnection.h"

@implementation TTURLConnection

@synthesize tag;

- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:
    (BOOL)startImmediately tag:(NSInteger)tagParam {
    self = [super initWithRequest:request delegate:delegate 
        startImmediately:startImmediately];

    if(self) {
        self.tag = tagParam;
    }

    return self;
}

@end

答案 4 :(得分:1)

希望这会对你有所帮助。

- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{   
    NSString *urlString = [[[connection originalRequest] URL] absoluteString];
    if ([urlString caseInsensitiveCompare:@"http://www.apple.com"] == NSOrderedSame) {
        //Do Task#1
    }
    else if ([urlString caseInsensitiveCompare:@"http://www.google.com"] == NSOrderedSame)
    {
        //Do Task#2
    }
}