iOS Objective-C NSURLSession не обновляет интерфейс / свойство - PullRequest
0 голосов
/ 02 июня 2018

У меня проблемы с обновлением пользовательского интерфейса в приложении Objective-C для iOS.

Я вызываю свою функцию fetchData в разделе viewDidLoad моего ViewController.

NSURLSession успешно извлекает данные, однако мне не удается обновить свойство titleText в моем пользовательском интерфейсе, даже если оно находится в главной очереди.

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

Однако я безуспешно пробовал несколько способов, поэтому любая помощь будет высоко оценена.

- (void) fetchData
{    
    NSString *strURl = @"www.url.com";
    NSLog(@"%@",strURl);

    NSURLSession *session = [NSURLSession sharedSession];
    [[session dataTaskWithURL:[NSURL URLWithString:strURl]
            completionHandler:^(NSData *data,
                                NSURLResponse *response,
                                NSError *error) {

                if (data == nil) {
                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"error", nil)message:NO_CONNECTION_TEXT preferredStyle:UIAlertControllerStyleAlert];

                    UIAlertAction* ok = [UIAlertAction actionWithTitle:NSLocalizedString(@"ok", nil) style:UIAlertActionStyleDefault handler:nil];
                    [alertController addAction:ok];
                    [self presentViewController:alertController animated:YES completion:nil];

                    return ;
                }
                else
                {
                    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

                        if (!parsedDetails){
                            parsedDetails = [[NSMutableArray alloc]init];
                        }

                        parsedDetails = [provider parseJSON:data into:parsedDetails withResponse:response];
                        NSLog(@"%@",parsedDetails);

                        dispatch_async(dispatch_get_main_queue(), ^{
                            NSLog(@"%@",parsedDetails);
                            NSLog(@"%@",[parsedDetails valueForKey:@"title"]);
                            self.titleText = [parsedDetails valueForKey:@"title"];
                        });
                    });
                }

            }] resume];
}

1 Ответ

0 голосов
/ 02 июня 2018

Часть 1: определение заголовка

parsedDetails - это NSMutableArray в вашем коде.

Затем вы используете KVC (Key-Value Coding) метод valueForKey в этом массиве.

Но это возвращает новый массив.Что происходит там: значение свойства title для каждого элемента в исходном массиве (parsedDetails) вставляется как новый элемент в новый массив, который в итоге возвращается как массив.

Из-за вашегокомментарий выше:

NSLog(@"%@",[parsedDetails valueForKey:@"title"]);

дает возвращаемое значение (массив с одной строкой):

("About") 

Но что вам на самом деле нужно, так это элемент title первой записи, так что скореекак это:

Detail *detail = parsedDetails.firstObject;
if (detail) {
    title = [detail title];
} else {
    title = @"default empty title";
}

Или, если вы предпочитаете вариант KVC:

id detail = parsedDetails.firstObject;
if (detail) {
    title = [detail valueForKey:@"title"];
} else {
    title = @"default empty title";
}

Часть 2: Обновление метки

НасколькоЯ понимаю ваши комментарии, у вас есть свойство NSString с именем titleText?Предположительно определяется так:

@property (nonatomic, strong) IBOutlet NSString *titleText;

А у вас также есть где-нибудь UILabel розетка?

@property (weak, nonatomic) IBOutlet UILabel *label;

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

Это будет выглядеть так:

self.label.text = self.titleText;
...