2015-09-17 3 views
0

Я знаю, что ABPersonView не является жалобой KVO. Моя проблема заключается в том, что, несмотря на то, что объявленное свойство ABPersonView сохраняется при каждом доступе к свойству, я получаю другой объект. Я делаю что-то неправильно или это правильно, что каждый раз, когда произошли изменения в ABPersonView, мне нужно обновить модель новым объектом ABPerson? Использование El Capitan GM.Как наблюдать изменения ABPersonView для ABPerson

ABPersonView:

@property (readwrite, retain) ABPerson *person; 
// An ABPerson record for display. 
// Raises if person originates from ABAddressBook's +sharedAddressBook. 
// Person must be exist in an ABAddressBook created and manipulated on the main thread only. 
// When person is nil, displays an empty selection state. 

Код:

#import "AppDelegate.h" 
@import AddressBook; 
static void * ABPersonVCContext = &ABPersonVCContext; 

@interface AppDelegate() 

@property (weak) IBOutlet NSWindow *window; 
@property (strong) ABPerson *person; 
@property (strong) ABPersonView *personView; 
@property (strong) ABAddressBook *book; 
@property (assign, getter=isEditing) BOOL editing; 
@property NSTimer *timer; 
@end 

@implementation AppDelegate 

- (instancetype)init { 
    self = [super init]; 
    if (self) { 
    _book = [[ABAddressBook alloc] init]; 
    NSString *vCardRepresentation = @"BEGIN:VCARD\r\nVERSION:3.0\r\nN:AA;BB;;;\r\nFN:\r\nEND:VCARD\r\n"; 
    NSData *vCardData = [vCardRepresentation dataUsingEncoding:NSUTF8StringEncoding]; 
    _person = [[ABPerson alloc] initWithVCardRepresentation:vCardData]; 
    [_book addRecord:_person]; 
    [self addObserver:self forKeyPath:@"editing" 
       options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew 
       context:ABPersonVCContext]; 
#ifdef DEBUG 
    NSLog(@"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__); 
    NSLog(@"%@",_person); 
#endif 
    } 
    return self; 
} 

- (void)awakeFromNib 
{ 
    self.personView = [[ABPersonView alloc] initWithFrame:self.window.contentView.frame]; 
    self.personView.person = self.person; 
    [self.window.contentView addSubview:self.personView]; 
    self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(reverseEditing) userInfo:NULL repeats:YES]; 
    [self.timer fire]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if (context == ABPersonVCContext) { 
    if ([keyPath isEqualTo:@"editing"]) { 
#ifdef DEBUG 
     NSLog(@"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__); 
     NSLog(@"%@",self.personView.person); 
#endif 
    } 
    } else { 
    @try { 
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
    } 
    @catch (NSException *exception) { 
     ; 
    } 
    @finally { 
     ; 
    } 
    } 
} 

- (void)reverseEditing 
{ 
    self.editing = !self.editing; 
} 

@end 

EDIT: Новый объект приходит из разных Addressbook Например:

(lldb) po [newPerson addressBook] 
<ABAddressBook: 0x6080000d50e0> 

(lldb) po self.book 
<ABAddressBook: 0x6080000c4130> 

(lldb) po [self.person addressBook] 
<ABAddressBook: 0x6080000c4130> 

EDIT2: Даже регистрация уведомлений не помогите, потому что другой объект будучи измененным.

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self selector:@selector(changeOccured:) name:kABDatabaseChangedNotification object:nil]; 
[nc addObserver:self selector:@selector(changeOccured:) name:kABDatabaseChangedExternallyNotification object:nil]; 
+0

Я только самостоятельно обнаружил то же самое. Я, честно говоря, не могу придумать способ создать нового человека И сохранить этого человека в сломанных пользовательских интерфейсах AddressBook в El Capitan и позже. Песочница снова ударяет! –

ответ

0

К сожалению, каждый вызов к человеку свойство personView вызывает ABPersonViewAPIAdapter, который преобразует CNContact в ABPerson. Поэтому, если вы не хотите использовать CNContact на El Capitan, он должен распространять отредактированный ABPerson обратно на объект модели.

Можно попробовать следующий код (надеюсь, это позволит сэкономить некоторое время, чтобы кто-то)

NSLog(@"%@",[self.personView performSelector:@selector(addressBook) withObject:nil]); 
    NSLog(@"%@",[self.personView performSelector:@selector(_APIAdapter) withObject:nil]); 
    NSLog(@"%@",[self.personView performSelector:@selector(_contact) withObject:nil]); 

 Смежные вопросы

  • Нет связанных вопросов^_^