Цель C: есть ли способ вызвать блок завершения для метода в другом методе? - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть несколько GET методов запроса API, которые после завершения вызывают блок завершения.Вот пример одного.

- (void)getUserInfo
    onSuccess:(void (^)(id))successBlock
    onFailure:(void (^)(NSError *))failureBlock {

    NSString *urlStr = [NSString stringWithFormat:@"%@/user/", baseUrl];

    [manager GET:urlStr parameters:nil progress:nil
          success:^(NSURLSessionTask *task, id responseObject) {
              successBlock(responseObject);
          }
          failure:^(NSURLSessionTask *operation, NSError *error) {
              failureBlock(error);
          }];
}

Однако я заметил, что я повторяю код запроса менеджера GET в других методах.Я хочу создать другой метод, который обрабатывает все запросы и удаляет повторяющийся код.URL, кажется, единственное, что меняется.Однако есть один недостаток.Мне нужно вызвать successBlock, чтобы сообщить методу, что запрос завершен.

Может быть, мне нужно вообще пойти другим путем и сделать что-то другое.

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Блоки - если они имеют одинаковую подпись - их можно передавать по цепочке методов.Ваши блоки GET содержат ненужный первый параметр.NSURLSessionTask *, если он вообще должен быть возвращен, должен возвращаться синхронно.Удаление этого из подписи блока позволит вам стандартизировать блоки.

Проще сказать в коде ...

// changed this method name so it would compile

- (void)getUserInfoOnSuccess:(void (^)(id))successBlock
                   onFailure:(void (^)(NSError *))failureBlock {

    NSString *urlStr = [NSString stringWithFormat:@"%@/user/", baseUrl];

   // two things: get the task as a return value (if you need it)
   // pass the blocks directly, without nesting them in new blocks
    NSURLSessionTask *task = [manager GET: urlStr
                               parameters: nil
                                 progress: nil
                                  success: successBlock
                                  failure: failureBlock];
    // do something with the task
}

Чтобы это работало, измените тип возврата метода GETи заблокировать подписи ...

- (NSURLSessionTask *)GET:(NSString *)url parameters:(id)params progress:(id)progress success:(void (^)(id))successBlock failure:(void (^)(NSError *))failureBlock {
    // return the session task created here
    return task
}
0 голосов
/ 27 ноября 2018

Вы можете передавать блоки завершения и затем вызывать их из вашего финального метода, который обрабатывает все запросы get.Я обычно делаю блоки завершения, которые для краткости собираются повторно использовать typedefs.Вот пример того, что я имею в виду (я добавил второй пример метода, который также проходит через метод center getRequestWithURLString:onSuccess:onFailure:):

LLFakeManager.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef void (^_Nullable SuccessCompletionBlock)(id responseObject);
typedef void (^_Nullable FailureCompletionBlock)(NSError *error);

@interface LLFakeManager : NSObject
- (void)getUserInfoOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock;
- (void)getBooksCheckedOutOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock;
@end

NS_ASSUME_NONNULL_END

LLFakeManager.m

#import "LLFakeManager.h"

@interface LLFakeManager()
- (void)getRequestWithURLString:(NSString *)urlString
                      onSuccess:(SuccessCompletionBlock)successBlock
                      onFailure:(FailureCompletionBlock)failureBlock;
@end

@implementation LLFakeManager

- (void)getUserInfoOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock {
    NSString *urlStr = @"FakeUserUrlPath";
    [self getRequestWithURLString:urlStr onSuccess:successBlock onFailure:failureBlock];
}

- (void)getBooksCheckedOutOnSuccess:(SuccessCompletionBlock)successBlock onFailure:(FailureCompletionBlock)failureBlock {
    NSString *urlString = @"FakeBooksUrlPath";
    [self getRequestWithURLString:urlString onSuccess:successBlock onFailure:failureBlock];
}

// central method that will handle all the get requests
- (void)getRequestWithURLString:(NSString *)urlString
                      onSuccess:(SuccessCompletionBlock)successBlock
                      onFailure:(FailureCompletionBlock)failureBlock {
    // some fake implementation here to do your request, then use the completion block passed in from whatever other method
    if (successBlock) {
        successBlock(@"responseObjectPassedBackHere");
    }
}

@end

И пример его вызова:

LLFakeManager *manager = [[LLFakeManager alloc] init];
[manager getUserInfoOnSuccess:^(id  _Nonnull responseObject) {
    NSLog(@"Here's my response object = %@", responseObject);
} onFailure:^(NSError * _Nonnull error) {
    // no implementation but same idea
}];

Будет производить этот журнал:

Here's my response object = responseObjectPassedBackHere

Этот сайт: http://goshdarnblocksyntax.com это удобный списоксинтаксиса блока, который также может быть полезен для вас.

...