Как отобразить CNContact с помощью CNContactViewController в OSX

Я пытаюсь отобразить CNContact на новом CNContactViewController. У меня не выбрана карта. Я попробовал это с несохраненным контактом (не идет). Также пробовал с сохраненным + извлеченным из CNContactStore, тоже не работает. Пробовал с контактом "я", но тот же результат. Согласно отладчику, выбранный контакт загружается с правильными значениями и не является нулевым/пустым. Приложение находится в песочнице и правильно запрашивает разрешение контактов.

Вот образец:

#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
#import "AppDelegate.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (strong)  CNContact *contact;
@property (strong)  CNContactViewController *controller;
@end

@implementation AppDelegate

- (instancetype)init {
  self = [super init];
  if (self) {
    _controller = [[CNContactViewController alloc] init];

  }
  return self;
}

- (void)awakeFromNib
{
  CNContactStore *store = [[CNContactStore alloc] init];
  CNMutableContact *mutContact = [[CNMutableContact alloc] init];
  NSString *identifier = [mutContact identifier];
  mutContact.givenName = @"GivenName";
  mutContact.familyName = @"FamilyName";
  CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
  [saveRequest addContact:mutContact toContainerWithIdentifier:[store defaultContainerIdentifier]];
  [store executeSaveRequest:saveRequest error:nil];

  id keysToFetch = @[[CNContactViewController descriptorForRequiredKeys]];
  _contact = [store unifiedContactWithIdentifier:identifier keysToFetch:keysToFetch error:nil];

  dispatch_async(dispatch_get_main_queue(), ^{
    self.controller.contact = self.contact;
    self.window.contentViewController = self.controller;
    self.window.contentView = self.controller.view;
  });
}
@end

Карта не выбрана

РЕДАКТИРОВАТЬ: 6 октября 2015 г.

Apple TSI подтвердила, что они не могут заставить его работать на OS X 10.11.0.


person Marek H    schedule 10.09.2015    source источник


Ответы (1)


Решение состоит в том, чтобы установить контакт после загрузки представления.

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

#import <Contacts/Contacts.h>
#import <ContactsUI/ContactsUI.h>
#import "ViewController.h"

@interface ViewController()
@property (strong) CNContactStore *store;
@property (strong)  CNContactViewController *controller;
@property(nonatomic, copy) NSString *contactIdentifier;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.store = [[CNContactStore alloc] init];
    [self saveContact];
}


-(void)saveContact
{
    CNMutableContact *mutContact = [[CNMutableContact alloc] init];


    mutContact.givenName = @"GivenName";
    mutContact.familyName = @"FamilyName";
    CNSaveRequest *saveRequest = [[CNSaveRequest alloc] init];
    [saveRequest addContact:mutContact toContainerWithIdentifier:[self.store defaultContainerIdentifier]];
    [self.store executeSaveRequest:saveRequest error:nil];
     self.contactIdentifier = [mutContact identifier];
}


- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];

    // Update the view, if already loaded.
}


- (IBAction)displayContact:(id)sender {

    id keysToFetch = @[[CNContactViewController descriptorForRequiredKeys]];
     CNContact *contact = [self.store unifiedContactWithIdentifier:self.contactIdentifier keysToFetch:keysToFetch error:nil];

    self.controller = [[CNContactViewController alloc] init];

    [self.controller.view setFrameSize:NSMakeSize(500, 500)];

    [self presentViewController:self.controller asPopoverRelativeToRect:self.view.bounds ofView: self.view preferredEdge: NSMaxXEdge behavior:NSPopoverBehaviorTransient];

    self.controller.contact = contact;
}
person Marek H    schedule 09.10.2015