EKEventStore with iOS Widget error: [EventKit] Client tried to open too many connections to calaccessd. Refusing to open another

EKEventStore with iOS Widget error: [EventKit] Client tried to open too many connections to calaccessd. Refusing to open another

我有一个 iOS 小部件,它使用 EKEventStore 来处理提醒。该小部件仅初始化 EKEventStore 一次,然后使用该实例。小部件通常在今天 viewController 中被查看时创建,并在用户退出通知中心时被销毁。这导致每次用户查看小部件时初始化 EKEventStore。连续 10 次查看小部件后,出现以下错误:

[EventKit] Client tried to open too many connections to calaccessd. Refusing to open another

我诊断了这个问题,发现它发生在小部件的 10 次浏览之后。要重现此问题,您需要打开另一个应用程序,然后每次都返回到小部件,以便在您查看时重新加载小部件。

我正确初始化 EKEventStore 如下:

self.eventStore = [[EKEventStore alloc] init];
[self.eventStore requestAccessToEntityType:EKEntityTypeReminder
                                                   completion:^(BOOL granted, NSError *error) {

}];

我知道在小部件的同一会话中多次初始化 EKEventStore 可能会出现问题。但是当用户离开小部件时,我希望初始化 EKEventStore 的次数有限,以便在小部件从头重新加载时重置。

实施共享单例 class 来管理 EKEventStore 如下,在应用程序和扩展程序(小部件)中使用单例:

+(EventStoreManager *)sharedInstance {
    static dispatch_once_t onceToken;
    static EventStoreManager *  eventStoreSharedInstance;

    dispatch_once(&onceToken, ^{
        eventStoreSharedInstance = [[EventStoreManager alloc] init];
    });
    return eventStoreSharedInstance;
}

这解决了上述问题。即使扩展或小部件被销毁,这个单例也会被维护。 感谢 Apple 支持提供此修复。