![](/img/trans.png)
[英]Navigate iOS Storyboard ViewControllers from AppDelegate
[英]appDelegate and ViewControllers
我是Objective-C的新手,我想知道我的方法是否有意义。
我的应用程序是基于Tabs-View的。 每个选项卡都调用对服务器的请求。
appDelegate
我创建了到服务器的异步套接字连接的实例。 TableViewController
在其中需要创建内部请求消息并将其发送到服务器。 我的问题是我无法访问TableViewController
的套接字,因此我可以通过appDelegate sharedApplication
访问套接字,然后将请求消息发送到服务器。
由于我使用异步套接字模型,因此接收服务器响应的委托是appDelegate
本身,现在我需要以某种方式将响应传播回“获取状态” TableViewController
。
我的问题是该怎么做?
也许我的方法从一开始就不好,我需要使用同步套接字模型。 或者也许我需要将套接字连接作为上下文传递给我打开的每个视图控制器。
我想念什么? 如何从发送它的视图中轻松访问对服务器的响应? 任何帮助,将不胜感激!!
谢谢!
我建议使用其他设计。 发出请求的东西应该是任何VC都可以实例化并用于发出请求的类,可能是NSURLRequest的子类。
因为它是一个单例,所以很容易使应用程序委派全局数据和行为的所有者,但这不是工作。
如果您需要为服务器请求做很多自定义工作,请子类NSURLRequest。 使用NSURLConnection的sendAsynchronousRequest:方法运行它。 它使调用者可以传递一个块以在请求完成时执行该请求结果。
例如MyRequest.h
@interface MyRequest : NSMutableURLRequest
- (id)initWithParams:(NSDictionary *)params;
- (void)runWithCompletion:(void (^)(id result, NSError *error))completion;
@end
例如MyRequest.m
@implementation MyRequest
- (id)initWithParams:(NSDictionary *)params {
self = [self init];
if (self) {
// do custom init here, e.g.
self.URL = @"http://www.myservice.com/myrequest.json"
[self setValue:@"bar" forHTTPHeaderField:@"foo"]; // more realistically, using key value pairs in the params dictionary
// and so on
}
return self;
}
- (void)runWithCompletion:(void (^)(id result, NSError *error))completion {
[NSURLConnection sendAsynchronousRequest:self
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (data) {
// do something custom with the received data here,
// like convert to a string and parse as json, etc.
completion(data, nil);
} else {
completion(nil, error);
}
}];
}
@end
现在,任何VC或与此相关的任何其他类都可以创建其中之一并使用它:
// in MyVC.m
MyRequest *myRequest = [[MyRequest alloc] initWithParams:[NSDictionary dictionary]];
[myRequest runWithCompletion:^(id result, NSError *error) {
// do main thread ui stuff with the result in hand, e.g.
[self.tableView reloadData];
}];
您可以让您的代表在通知中心发布通知。 然后,您的表视图控制器注册到该通知,并且它可以接收信息。
就像是
在您的AppDelegate中 ,当收到套接字响应时
NSDictionary * userInfo = @{@"socketResponse" : response}; // assuming that response is the object to pass around
[[NSNotificationCenter defaultCenter] postNotificationName:@"kDidReceiveSocketResponse"
object:self
userInfo:userInfo
在你的UITableViewController中
- (void)viewDidLoad {
[super viewDidLoad];
//...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(socketResponseReceived:)
name:@"kDidReceiveSocketResponse"
object:nil];
//...
}
- (void)socketResponseReceived:(NSDictionary *)userInfo {
id response = userInfo[@"socketResponse"];
// do whatever you like
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
我同意Talha对此的评论,不建议使用Notification Center。 最好创建一个继承自NSObject的新类来处理套接字事件,但是如果需要,您也可以仅使用应用程序委托使其工作。 为了方便您...
创建一个从套接字类到视图控制器的链接
在两个文件都可以看到的地方定义TableViewSocketEventsDelegate。 您可以创建一个公共的Constants.h之类的东西。
@protocol TableViewSocketEventsDelegate <NSObject>
@required
- (void) someSocketEvent:(int)statusCode;
//TODO: Add callbacks that make sense here
@end
给套接字类(在您的情况下为应用程序委托.h文件)对最终将处理该操作的内容(在您的情况下,表视图控制器)的引用
@property (nonatomic, assign) id<TableViewSocketEventsDelegate> socketDelegate;
在.m中,请确保合成socketDelegate并将其分配给适当的视图控制器。
接下来,告诉视图控制器它可以处理这些委托回调。
在.h中:
ViewController : UITableViewController<TableViewSocketEventsDelegate>
在.m中:
#pragma mark - TableViewSocketEventsDelegate
- (void) someSocketEvent:(int)statusCode
{
NSLog(@"Some socket event happened %I", statusCode);
}
现在您要做的就是更改应用委托中处理套接字的现有方法,以调用新方法
if (self.socketDelegate) {
[self.socketDelegate someSocketEvent:2];
}
这对你有意义吗? 如果所有的选项卡视图控制器都需要处理相同的委托,我也建议为它们创建一个基类。
祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.