Проблемы с производительностью SVProgressHUD

У меня есть раздел кода, который производит производительность и работает не так, как ожидалось. он использует SVProgressHUD из следующего репозитория github по адресу https://github.com/samvermette/SVProgressHUD. У меня есть область кода, где мне нужно использовать [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error], Я хочу, чтобы индикатор прогресса отображался до синхронного запроса, а затем отклонялся после его завершения. Вот код, о котором идет речь:

//Display the progress HUB
[SVProgressHUD showWithStatus:@"Signing Up..." maskType:SVProgressHUDMaskTypeClear];

NSError* error;
NSURLResponse *response = nil;
[self setUserCredentials];

// create json object for a users session
NSDictionary* session = [NSDictionary dictionaryWithObjectsAndKeys:
                         firstName, @"first_name",
                         lastName, @"last_name",
                         email, @"email",
                         password, @"password",
                         nil];

NSData *jsonSession = [NSJSONSerialization dataWithJSONObject:session options:NSJSONWritingPrettyPrinted error:&error];

NSString *url = [NSString stringWithFormat:@"%@api/v1/users.json", CoffeeURL];

NSURL *URL = [NSURL URLWithString:url];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:30.0];

[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:[NSString stringWithFormat:@"%d", [jsonSession length]] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:jsonSession];

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *JSONResponse = [NSJSONSerialization JSONObjectWithData:[dataString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];

NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSInteger statusCode = httpResponse.statusCode;

NSLog(@"Status: %d", statusCode);

if (JSONResponse != nil && statusCode == 200)
{
    //Dismiss progress HUB here
    [SVProgressHUD dismiss];
    return YES;
}
else
{
    [SVProgressHUD dismiss];
    return NO;
}  

По какой-то причине синхронный запрос блокирует отображение HUB. Он отображается сразу после того, как синхронный запрос происходит, к сожалению, это также, когда он отклонен. Поведение, отображаемое для пользователя, заключается в том, что приложение зависает, ожидает завершения синхронного запроса, быстро мигает концентратором, а затем снова становится отзывчивым. Как я могу исправить эту проблему? Я хочу SVProgressHUB чтобы отображаться в это время зависания, как я могу это сделать?

2 ответа

Решение

Вы можете попробовать выполнить такой запрос и обработать все остальное внутри блока. Код внутри блока будет только при запуске, когда запрос вернулся.

Так что это может быть что-то вроде этого:

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){

NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSDictionary *JSONResponse = [NSJSONSerialization JSONObjectWithData:[dataString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];

NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSInteger statusCode = httpResponse.statusCode;

NSLog(@"Status: %d", statusCode);

if (JSONResponse != nil && statusCode == 200)
{
    //Dismiss progress HUB here
    [SVProgressHUD dismiss];    
}
else
{
    [SVProgressHUD dismiss];
}  

}];

Да, и это имеет полный смысл, поскольку HUD отображается в основном потоке, все анимации пользовательского интерфейса. Затем вы запускаете запрос, блокирующий основной поток.

Вы должны либо выполнить запрос в фоновом режиме, который имеет смысл для всех сетевых запросов, либо отложить блокирующий вызов, чтобы дать пользовательскому интерфейсу время для обновления.

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

Другие вопросы по тегам