1

私は Objective-C を初めて使用するので、私のアプローチが理にかなっているかどうかを知りたいです。

私のアプリケーションは Tabs-View ベースです。すべてのタブがサーバーへのリクエストを呼び出します。

  1. appDelegateのサーバーへの非同期ソケット接続のインスタンスを作成します。
  2. TableViewController内部要求メッセージを作成してサーバーに送信する必要があるをロードする [Get status] タブをクリックします。
  3. 私の問題は、のソケットにアクセスできないことです。そのTableViewControllerため、ソケットにアクセスしてからappDelegate sharedApplication、リクエストメッセージをサーバーに送信します。

  4. 私は非同期ソケットモデルを使用しているため、サーバーの応答を受け取るデリゲートはappDelegateそれ自体であり、応答を "Get status" に伝達する必要がありますTableViewController

私の質問はそれを行う方法ですか??

多分私のアプローチは最初は良くなく、同期ソケットモデルを使用する必要があります。または、開いているすべてのView Controllerにソケット接続をコンテキストとして渡す必要があるかもしれません。

私は何が欠けていますか?? サーバーへの応答を、送信元のビューから簡単にアクセスできるようにするにはどうすればよいですか?? どんな助けでも大歓迎です!!

ありがとう!

4

3 に答える 3

1

別のデザインを提案します。リクエストを行うものは、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];
}];
于 2012-12-31T15:59:44.843 に答える
0

代理人に通知センターに通知を投稿させることができます。次に、Table View Controller がその通知に登録され、情報を受け取ることができます。

何かのようなもの

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];
}
于 2012-12-31T14:35:44.123 に答える
0

これに関する Talha のコメントに同意し、通知センターの使用はお勧めしません。ソケット イベントを処理するために NSObject から継承する新しいクラスを作成するのが最善ですが、必要に応じてアプリ デリゲートのみを使用して動作させることもできます。使いやすいように...

ソケット クラスからビュー コントローラーへのリンクを作成する

両方のファイルから見える場所に TableViewSocketEventsDelegate を定義します。public 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];
    }

それはあなたにとって理にかなっていますか?また、すべてのタブ ビュー コントローラーが同じデリゲートを処理する必要がある場合は、すべてのタブ ビュー コントローラーの基本クラスを作成することをお勧めします。

幸運を!

于 2012-12-31T15:53:52.930 に答える