Ожидание ответа для HTTP-запроса с использованием NSURLSession - Цель C - PullRequest
0 голосов
/ 13 октября 2019

Сейчас я занимаюсь разработкой небольшого класса, в котором есть метод для отправки запроса POST. Этот метод предназначен для возврата ResponseModel (который в основном имеет два ivars: code, message), эта модель будет отображаться из ответа. Я использую dataTaskWithRequest:urlRequest completionHandler: метод. Вот так:

+ (void)sendPOSTRequest1:(id)data withResponse:(void (^) (ResponseModel * data) )taskResponse {
    NSError *error = nil;

    NSMutableURLRequest * urlRequest = [self getRequestObject];

    [urlRequest setHTTPMethod:@"POST"];

    NSData * requestData = [self encodeAndEncrypt:data];

    [urlRequest setHTTPBody:requestData];


    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session
                                      dataTaskWithRequest:urlRequest
                                      completionHandler:
                                      ^(NSData *data, NSURLResponse *response, NSError *error) {

        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;

        ResponseModel * responseModel = [NSKeyedUnarchiver
                                         unarchivedObjectOfClass:[ResponseModel class]
                                         fromData:data
                                         error:&error];

        taskResponse(responseModel);


    }];

    [dataTask resume];
}

И вызовите метод следующим образом:

DummyModel * dummy = [[DummyModel alloc] init];

__block ResponseModel * result = [[ResponseModel alloc] init];

[HTTPRequest sendPOSTRequest1:dummy withResponse:^(ResponseModel *data) {
    result =  data;
    NSLog(@"data %@",data);
}];

// It`s not sure that the asyncronous request has already finished by this point
NSLog(@"POST result : %@",result);

Моя проблема в том, что я не хочу выполнять код в блоке обратного вызовапотому что мне нужно дождаться ответа, чтобы вернуть ResponseModel, и тот, кто его реализует, может получить модель и сделать другие вещи. Я исследовал возможность использования NSURLConnection, потому что у него есть метод для выполнения синхронного запроса, но теперь он устарел, поэтому мне было интересно: можно ли ждать ответа, используя то, что есть в коде?

1 Ответ

0 голосов
/ 13 октября 2019

Вы можете использовать GCD для реализации синхронного запроса следующим образом:

быстрый код

public static func requestSynchronousData(request: URLRequest) -> Data? {
    var data: Data? = nil
    let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0)
    let task = URLSession.shared.dataTask(with: request, completionHandler: {
        taskData, _, error -> () in
        data = taskData
        if data == nil, let error = error {print(error)}
        semaphore.signal()
    })
    task.resume()
    _ = semaphore.wait(timeout: .distantFuture)
    return data
}

Код Objective-C

+ (NSData *)requestSynchronousData:(NSURLRequest *)request {
    __block NSData * data = nil;
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable taskData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            NSLog(@"%@", error);
        }
        data = taskData;
        dispatch_semaphore_signal(semaphore);
    }];
    [task resume];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    return data;
}

Вы можете использовать dispatch_async для обработкиИнтерфейс взаимодействия внутри блока

DummyModel * dummy = [[DummyModel alloc] init];

__block ResponseModel * result = [[ResponseModel alloc] init];

[HTTPRequest sendPOSTRequest1:dummy withResponse:^(ResponseModel *data) {
    result =  data;
    dispatch_async(dispatch_get_main_queue(), ^{
       // handle some ui interaction
    });
    NSLog(@"data %@",data);
}];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...