... 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输出?
单例类NSURLConnection正在处理我的所有通信。从简单的电子邮件一直到更新事务表的所有内容。这对我来说似乎不对,并且很难跟踪谁在调用什么。再次,我将通过我对MVC的解释。我认为为每个VC创建一个NSURLConnection并在这些类中进行一些处理要容易得多。然而,那不是MVC(ish)。
我接近100个变量,数组等...在我的单例类中,我用它来为我的所有VC赋值。这对我来说似乎也是错的,但我想不出任何其他方式。
答案 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
}
}