

MVVMでの実装方法について質問です。

ModelでAFNetWorkingを使用し、JSONを取得しています。  
AFNetWorkingの非同期通信が終了したタイミングでViewのテーブルをreloadDataしたいのですが、MVVMの場合ModelからViewを操作することは無いと認識しています。  
この場合のViewを更新する方法を教えていただきたいです。

[code]

    // Model
    [manager POST:testAPI
       parameters:parameters
          success:^(NSURLSessionDataTask *task, id responseObject)
     {
    
         // レスポンスをDBに登録
    
         // TODO: DB登録後、Viewの更新処理を実行したい
    
    
     } failure:^(NSURLSessionDataTask *task, NSError *error)
     {
     }];
    
[/code]

＜追記＞  
【delegate】  
~~Viewでmodel.delegate = self としてもAFNetWorkingのブロックスが実行されるときにはnilとなってしまいます…~~  
Modelのインスタンス作成でミスしているだけでした。

【blocks】  
View→ViewModel→Modelの流れなので......

[code]

    // View
        [_viewModel sampleMethod1:^{
            [self refresh];
        }];
    
    // ViewModel 
    - (void) sampleMethod1:(void (^) (void)) refreshView {
        [_model sampleMethod2:^{
        refreshView();
    }];
    
    // Model 
    - (void) sampleMethod2:(void (^) (void)) refreshView {
        ..........
    
        [manager POST:testAPI
           parameters:parameters
              success:^(NSURLSessionDataTask *task, id responseObject)
         {
    
             // レスポンスをDBに登録する処理を実行
             .......
    
             // TODO: 上記DB登録処理後、Viewの更新処理を実行したい
             refreshView();
    
         } failure:^(NSURLSessionDataTask *task, NSError *error)
         {
         }];
    
[/code]

}  
となり、VからVMに渡した処理をさらにMに渡して処理する事になり冗長な気がしました。  
もっと綺麗な書き方があると思うのですが、分かりません…。

＜追記２＞  
Blocksの場合の綺麗な書き方は分かりませんが、delegateで実装できそうでした。


CC BY-SA 3.0
2016-01-20T06:50:01.870
21113
2016-01-21T09:32:26.833
2016-01-21T09:32:26.833
question
ios objective-c mvvm
非同期通信の終了タイミングでテーブルをreloadDataしたい


Model内のメソッドの処理が完了したことを知らせる方法は2つほどあります。  
(非同期処理が含まれている場合を書きます)

  * delegateを自作して、処理完了後にdelegateのメソッドを呼び出す
  * Block構文をメソッドの引数に持たせる

各特徴ですが、

【delegateの特徴】

  * ソースのネストが少なくなる
  * optional指定することで、処理を譲渡される側で受け取り処理を書かなくても済み、複数箇所で利用する際にソースが荒れない
  * ソースを見たときに、処理を直列的に追えない

【Block構文の特徴】

  * ソースの処理を直列的に追いやすい(&直列的に処理を書ける)
  * Model内のメソッドが減る(delegateではメソッドを必要分 追加する)
  * そのModelを呼び出す側で定義するオブジェクトの数が減る
  * ソースのネストが深くなる

といったところです。  
初めはどちらかの利用に統一されても良いとか思います。

私の場合は両方使いますが、  
使い分けとしては、

  * 連続した非同期処理ではない→delegate
  * 連続した非同期処理がある→Block構文

としている場合が多いかもしれません。

書き方としては、  
【delegateの書き方】

Model.hを下記として

[code]

    // デリゲートを定義
    @protocol WebClientDelegate <NSObject>
    
    - (void)didSuccess:(NSDictionary *response);
    - (void)didFailure:(NSError *error);
    
    @end
    
    @interface Model : NSObject
    
    /// デリゲート先で参照するためのプロパティ
    @property (assign, nonatomic) id<ModelDelegate> delegate;
    ....
    
    @end
    
[/code]

Model.mを下記内のメソッドで

[code]

    - (void)sampleMethod
     {
            [manager POST:testAPI
               parameters:parameters
                  success:^(NSURLSessionDataTask *task, id responseObject)
            {
    
                // レスポンスをDBに登録
    
                // TODO: DB登録後、Viewの更新処理を実行したい
                NSDictionary *result = "何らかの結果"
                if([self.delegate respondsToSelector:@selector(didSuccess:)]) {
                    [self.delegate didSuccess:result];
                }
            } failure:^(NSURLSessionDataTask *task, NSError *error) {
                if([self.delegate respondsToSelector:@selector(didFailure:)]) {
                    [self.delegate didFailure:error];
                }
            }];
    }
    
[/code]

【Block構文の書き方】

[code]

    - (void)sampleMethod:(void (^)(NSDictionary *response))success 
                 failure:(void (^)(NSError *error))failure
     {
            [manager POST:testAPI
               parameters:parameters
                  success:^(NSURLSessionDataTask *task, id responseObject)
            {
    
                // レスポンスをDBに登録
    
                // TODO: DB登録後、Viewの更新処理を実行したい
                NSDictionary *result = "何らかの結果"
                success(result);
            } failure:^(NSURLSessionDataTask *task, NSError *error) {
                failure(error);
            }];
    }
    
[/code]

となります。

以上、少しでも参考になれば幸いです。


CC BY-SA 3.0
2016-01-21T00:29:38.020
21139
2016-01-21T04:39:40.147
2016-01-21T04:39:40.147
8968
8968
21113
answer