NSURLConnection委托

修订…

应用程序的关键是与数据库服务器通信。 从服务器到应用程序的响应都是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.在文本框中input新的电子邮件地址,然后单击保存button。 该button然后调用一个单一类的方法,它将新的电子邮件地址发送到服务器和(通过URL),并接收一个确认更改的XML响应。

这里是我的问题:1.我做的单身类方法调用之前,从视图控制器启动微调 – 但不知道什么时候应用程序发送/接收服务器已完成,我怎么让微调停在正确的时间? 我不能从单身人士的课程,我试过。 据我所知,它必须来自VC内部,还是有办法改变我单身class的VC输出?

  1. 单身类NSURLConnection正在处理我的所有通信。 从简单的一切,电子邮件改变一切到更新交易表。 这对我来说似乎是错误的,并且使得跟踪谁在呼叫什么是非常困难的。 再次,我正在通过我对MVC的解释。 我认为为每个VC创build一个NSURLConnection会更容易,并在这些类中进行一些处理。 但是,这不会是MVC(ISH)。

  2. 我有接近100个variables,数组等…在我单身人士课堂,我用它分配值给我所有的VC。 这对我来说似乎也是错误的,但我想不出任何其他的方式。

我怎么能区分NSURLConnection委托(connectionDidFinishLoading)哪个URL调用正在做?

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

下载完成后,如何才能告诉“connectionDidFinishLoading”?

该方法告诉你连接何时完成。 您需要将这些信息存储在对您的应用有用的地方。

更新:根据您添加的内容,您的“处理”类是您的应用程序的模型。 应用程序的其余部分不应该在乎每个事务都涉及到服务器的消息 – 这就是模型的业务。 此外,没有理由模型必须是一个单一的对象(更不用说一个单身) – 它可以是一组对象一起工作。

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

很难说你的应用程序最好的计划是什么,不知道你计划采取的计划,但通常的准则是:

  • 把你的问题分解成更容易解决的部分

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

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

把你的模型分成几个类将会使testing变得更容易。 你可以想象为Transaction类编写一组unit testing是多么容易。 处理器也是如此 – 如果服务器事务处于不同的类中,则更容易testing处理器是否正确。

如果对同一个委托有多个NSURLConnections,请考虑使用NSMutableDictionary实例的全局(好吧,我们假设是一个实例variables),根据哪个NSURLConnection被调用来存储数据。 例如,您可以使用转换为NSString的连接的内存地址(类似于

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

应该做的伎俩)。

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

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

如果你使用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提供队列function。 看看这里 。

希望这会帮助你。

 - (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 } } 

我会build议inheritanceNSURLConnection。 只需添加两个属性:NSInteger, tag和BOOL, isFinished 。 这样,您可以为每个不同的请求定义标签,然后通过委托方法中的标签来标识它们。 在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