Hello everyone!
Yesterday I started to port my old Address Book code to the new Contacts Framework and ran into the same BAD_ACCESS problem with birthdayContactIdentifer. Since my app is a calendar app I need to work with EKEvent objects and their birthdayContactIdentifer. There's no way around it.
I conducted some tests an wrote a simple app that just initializes the EKEventStore (and requests access) in order to then fetch all events of the following seven days. If any of the events are part of the birthday calendar it NSLogs the title and the birthdayContactIdentifier.
I implemeted the app both in Objective C and Swift 2 (using Xcode 7.0.1). Both apps NSLog the identifier (of the single birthday event inside my simulator) approximately 10% of the time. All other tries result in BAD_ACCESS. Dispatching the code inside the completion block to the main thread does not change the result.
The Zombie test yields the same result as posted by Sergey (at least for the Objective C version that is).
This is what an NSLog of the identifier looks like:
BirthdayTest[26543:91411653] Hans Tester’s Birthday
BirthdayTest[26543:91411653] ID: 20D681BC-6DBA-4D2B-AB64-5D375BD66CD1:ABPerson
At the moment I don't know what to do.
Frank
P.S.:
This is the code I used:
#import "ViewController.h"
@import EventKit;
@interface ViewController ()
@property (strong) EKEventStore *eventStore;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.eventStore = [[EKEventStore alloc] init];
[self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error){
if (granted) {
NSDate *startDate = [NSDate date];
NSDate *endDate = [startDate dateByAddingTimeInterval:7*86400];
NSArray *events = [self.eventStore eventsMatchingPredicate:[self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:nil]];
for (EKEvent *event in events) {
if (event.calendar.type == EKCalendarTypeBirthday) {
NSLog(@"%@",event.title);
NSLog(@"ID: %@",event.birthdayContactIdentifier); // 90% of the time --> BAD_ACCESS
}
}
}
}];
}
@end
import UIKit
import EventKit
class ViewController: UIViewController {
let eventStore : EKEventStore = EKEventStore()
override func viewDidLoad() {
super.viewDidLoad()
eventStore.requestAccessToEntityType(.Event) { (granted, error) in
if granted == true {
let startDate = NSDate()
let endDate = startDate.dateByAddingTimeInterval(7.0*86400.0)
let events = self.eventStore.eventsMatchingPredicate(self.eventStore.predicateForEventsWithStartDate(startDate, endDate: endDate, calendars: nil))
for event in events {
if event.calendar.type == .Birthday {
NSLog("\(event.title)")
NSLog("\(event.birthdayContactIdentifier)") // 90% of the time --> BAD_ACCESS
}
}
}
}
}
}