Медленное расширение iOS Share

Я работаю над расширением обмена, чтобы просто взять ссылку, выбрать несколько имен, чтобы поделиться ею, и поделиться. Уровень данных еще не добавлен, только пользовательский интерфейс для отображения некоторых имен в табличном представлении (с использованием пользовательской ячейки), и я извлекаю общий URL-адрес из контекста расширения. Весь код в ВК ниже. Все представления настраиваются в раскадровке. Два UIButtons, два UILabels, один TableView и UIView для всего этого, так что я могу легко скруглять углы.

введите здесь описание изображения

Проблема, с которой я сталкиваюсь, заключается в том, что _linkLabel, который я использую для отображения URL-адреса, визуально не обновляется в течение почти 10 секунд! Что в мире. Что я здесь делаю, что вызывает это?

Я вывожу URL-адрес в обратном вызове из hasItemConformingToTypeIdentifier, и это происходит, как только расширение появляется, но не обновляет метку??!! Помогает. Пожалуйста.

#import "ShareViewController.h"
#import "UserCell.h"

@interface ShareViewController ()

@end

@implementation ShareViewController

- (void)viewDidLoad{
    self.view.alpha = 0;
    _friends = [@[@"Ronnie",@"Bobby",@"Ricky",@"Mike"] mutableCopy];
    _containerView.layer.cornerRadius = 6.f;
    _selectedIndexPaths = [[NSMutableArray alloc] init];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [UIView animateWithDuration:0.5 animations:^{
        self.view.alpha = 1;
    }];
}

- (void)viewDidAppear:(BOOL)animated{
    //pull the URL out
    NSExtensionItem *item = self.extensionContext.inputItems[0];
    NSItemProvider *provider = item.attachments[0];
    if ([provider hasItemConformingToTypeIdentifier:@"public.url"]) {
        [provider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
            NSURL *url = (NSURL*)item;
            _linkLabel.text = url.absoluteString;
            NSLog(@"Link: %@", url.absoluteString);
        }];
    }
    else{
        NSLog(@"No Link");
    }
}

#pragma mark - UITableView Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    UserCell *cell = (UserCell*)[tableView cellForRowAtIndexPath:indexPath];
    if([_selectedIndexPaths containsObject:indexPath]){
        [_selectedIndexPaths removeObject:indexPath];
        cell.selected = NO;
    }
    else{
        cell.selected = YES;
        [_selectedIndexPaths addObject:indexPath];
    }
    NSLog(@"Share to %i friends", (int)[_selectedIndexPaths count]);
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    //Later, calc height based on text in comment
    return  44;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return [_friends count];
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *CellIdentifier = @"UserCell";
    UserCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil){
        cell = [[UserCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    cell.selected = ([_selectedIndexPaths containsObject:indexPath]) ? YES : NO;
    cell.nameLabel.text = [_friends objectAtIndex:indexPath.row];
    return cell;
}

- (IBAction)dismiss {
    [UIView animateWithDuration:0.34 animations:^{
        self.view.alpha = 0;
    } completion:^(BOOL finished) {
        [self.extensionContext completeRequestReturningItems:nil completionHandler:nil];
    }];
}

@end

person d2burke    schedule 12.11.2014    source источник


Ответы (1)


Задержки в обновлении элементов пользовательского интерфейса — классический признак попытки обновления пользовательского интерфейса вне основной очереди. Что здесь и происходит. У вас есть это:

[provider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
    NSURL *url = (NSURL*)item;
    _linkLabel.text = url.absoluteString;
    NSLog(@"Link: %@", url.absoluteString);
}];

За исключением того, что NSItemProvider не гарантирует, что обработчик завершения будет вызван в той же очереди, с которой вы начали. Вы почти гарантированно окажетесь здесь в другой очереди, так что вы получаете эту странную задержку. Вам нужно отправить обратно в основную очередь, чтобы выполнить обновление:

[provider loadItemForTypeIdentifier:@"public.url" options:nil completionHandler:^(id<NSSecureCoding> item, NSError *error) {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSURL *url = (NSURL*)item;
        _linkLabel.text = url.absoluteString;
        NSLog(@"Link: %@", url.absoluteString);
    });
}];
person Tom Harrington    schedule 12.11.2014
comment
Это сделало это :) Отличный ответ, Том - person d2burke; 13.11.2014