应用程序在日历事件中测试参与者记录时崩溃

时间:2017-09-18 10:06:30

标签: ios objective-c calendar eventkit abrecord

我的应用访问用户的日历,查找最近的会议事件并拉出参与者。它适用于我的测试iPad,但在生产中(自iOS 9起),许多用户都遇到了崩溃问题。来自Crashlytics的崩溃报告显示了在使用nil获取参与者记录(ABRecordRef)后测试if (record)记录时的崩溃点。我在App启动时阅读日历,然后每隔30秒阅读一次。

以下是Crashlytics报道的内容

Crashed: com.apple.main-thread
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x000000000000007e
0 libobjc.A.dylib         objc_msgSend + 5
1 Simple Meeting Minutes  MMeventManager.m line 258
                          -[MMeventManager checkCalendarEvents]
2 Simple Meeting Minutes  MMMasterViewController.m line 315
                          -[MMMasterViewController checkCalendarEvents]
3 Foundation              __NSFireDelayedPerform + 458

11 UIKit                  UIApplicationMain + 150
12 Simple Meeting Minutes main.m line 16
                          main
13 libdyld.dylib          start + 2

这是来自Crashlytics的文本日志

Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x1c1d0dc6 objc_msgSend + 5
1  Simple Meeting Minutes         0xae457 -[MMeventManager checkCalendarEvents] (MMeventManager.m:258)
2  Simple Meeting Minutes         0xba9cf -[MMMasterViewController checkCalendarEvents] (MMMasterViewController.m:315)
3  Foundation                     0x1d86e06f __NSFireDelayedPerform + 458
4  CoreFoundation                 0x1cef8637 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 14
5  CoreFoundation                 0x1cef8339 __CFRunLoopDoTimer + 832
6  CoreFoundation                 0x1cef7d37 __CFRunLoopDoTimers + 188
7  CoreFoundation                 0x1cef5dd5 __CFRunLoopRun + 780
8  CoreFoundation                 0x1ce491af CFRunLoopRunSpecific + 470
9  CoreFoundation                 0x1ce48fd1 CFRunLoopRunInMode + 104
10 GraphicsServices               0x1e5f3b41 GSEventRunModal + 80
11 UIKit                          0x221cba53 UIApplicationMain + 150
12 Simple Meeting Minutes         0xaed2b main (main.m:16)
13 libdyld.dylib                  0x1c6364eb start + 2

我的代码如下:

-(NSArray *)checkCalendarEvents{

// When app becomes active, check calendar for meeting events

NSMutableArray *calendarEvents = [[NSMutableArray alloc]init];

if (self.eventsAccessGranted && allowCalendarEvents) {

    self.arrEvents = self.getEventsOfSelectedCalendar;

    if (self.arrEvents.count > 0) {

        // get previousEvents
        NSArray *previousEvents = [self.meetingModel getPreviousEvents];

        NSUInteger eventCounter = 0;

        // loop through the calendar event until we get a valid event, then jump out of the loop.
        // We just want the first event, other events we will capture on the next alert

        for (EKEvent *thisEvent in self.arrEvents)
        {
            // check if we have had this event before or not
            NSString *eventID = thisEvent.eventIdentifier;

            MMevent *calendarEvent = [[MMevent alloc]init];

            NSMutableArray *calendarAttendees = [[NSMutableArray alloc]init];

            if (![previousEvents containsObject:eventID]) {

                //not had this event before so proceed
                eventCounter++;
                NSString *minutesBy;
                NSString *lastName;
                NSString *firstName;
                NSString *fullName;

                MMattendee *calendarAttendee = [[MMattendee alloc] init];

                // get the organiser details as being the Minutes taker
                EKParticipant *organizer = thisEvent.organizer;

                // get the meeting organiser details if there is one
                if (organizer.name) {
                    fullName = organizer.name;

                    // set the minutes by to be the organiser
                    minutesBy = fullName;

                    // get name components from fullname
                    firstName = [[fullName componentsSeparatedByString:@" "] objectAtIndex:0];
                    if (fullName.length > firstName.length) {
                        lastName = [fullName substringFromIndex:[fullName rangeOfString:firstName].length + 1];
                    }else{
                        // use the first part of the firstName (as it maybe an email address only)
                        if ([firstName rangeOfString:@"@"].location > 0 ) {
                            NSString *emailFrontPart = [[firstName componentsSeparatedByString:@"@"] objectAtIndex:0];

                            // now look for a dot sepatator in email string
                            // NSLog(@"%d", [emailFrontPart rangeOfString:@"."].location);
                            if ([emailFrontPart rangeOfString:@"."].location == NSNotFound) {
                                // no dot separator
                                firstName = emailFrontPart;
                                lastName = @" ";
                            }
                            else{
                                // get firstname as a firstpart
                                firstName = [[emailFrontPart componentsSeparatedByString:@"."] objectAtIndex:0];

                                // get lastname as the second part
                                if (lastName.length == 0) {
                                    lastName = [[emailFrontPart componentsSeparatedByString:@"."] objectAtIndex:1];
                                }
                            }
                        }
                    }
                    calendarAttendee.firstName = firstName;
                    calendarAttendee.lastName = lastName;

                    //get organiser email address
                    ABAddressBookRef book = ABAddressBookCreateWithOptions(nil, nil);
                    ABRecordRef record = [organizer ABRecordWithAddressBook:book];
                    if (record) {
                        ABMultiValueRef value = ABRecordCopyValue(record, kABPersonEmailProperty);
                        if(ABMultiValueGetCount(value)) {
                            if (value
                                && ABMultiValueGetCount(value) > 0) {
                                NSString *emailAddress = (__bridge id)ABMultiValueCopyValueAtIndex(value, 0);
                                calendarAttendee.emailAddress = emailAddress;
                            }
                        }
                    }

                    // add organizer to the attendees
                    if (firstName.length > 0) {
                        [calendarAttendees addObject:calendarAttendee];
                        calendarAttendee = NULL;
                    }

                }

                // now check for other meeting participants
                if (thisEvent.attendees == nil) {
                    // if there isn't any meeting participants, then ignore the meeting

                }else{

                    // go through the participants and collect there details
                    for (EKParticipant *participant in thisEvent.attendees){

                        fullName = @"";
                        firstName = @"";
                        lastName = @"";

                        if (participant.participantType == 1) {
                            // we have at least one "person" participant.

                            MMattendee *calendarAttendee = [[MMattendee alloc] init];
                            // get name
                            if (participant.name) {
                                fullName = participant.name;
                                firstName = [[fullName componentsSeparatedByString:@" "] objectAtIndex:0];

                                if (fullName.length > firstName.length) {
                                    lastName = [fullName substringFromIndex:[fullName rangeOfString:firstName].length + 1];
                                }else{
                                    // use the first part of the firstName (as it maybe an email address only)
                                    if ([firstName rangeOfString:@"@"].location > 0 ) {
                                        NSString *emailFrontPart = [[firstName componentsSeparatedByString:@"@"] objectAtIndex:0];

                                        // now look for a dot sepatator in email string
                                        // NSLog(@"%d", [emailFrontPart rangeOfString:@"."].location);
                                        if ([emailFrontPart rangeOfString:@"."].location == NSNotFound) {
                                            // no dot separator
                                            firstName = emailFrontPart;
                                            lastName = @" ";
                                        }
                                        else{
                                            // get firstname as a firstpart
                                            firstName = [[emailFrontPart componentsSeparatedByString:@"."] objectAtIndex:0];

                                            // get lastname as the second part
                                            if (lastName.length == 0) {
                                                lastName = [[emailFrontPart componentsSeparatedByString:@"."] objectAtIndex:1];
                                            }
                                        }
                                    }
                                }
                                calendarAttendee.firstName = firstName;
                                calendarAttendee.lastName = lastName;

                            }

                            //get participant's email address
                            ABAddressBookRef book = ABAddressBookCreateWithOptions(nil, nil);
                            ABRecordRef record = [participant ABRecordWithAddressBook:book];
                            if (record) {
                                ABMultiValueRef value = ABRecordCopyValue(record, kABPersonEmailProperty);
                                if(ABMultiValueGetCount(value)) {
                                    if (value
                                        && ABMultiValueGetCount(value) > 0) {
                                        NSString *emailAddress = (__bridge id)ABMultiValueCopyValueAtIndex(value, 0);
                                        calendarAttendee.emailAddress = emailAddress;
                                    }
                                }
                            }

                            // add to the attendees
                            if (firstName.length > 0) {
                                // NSLog(@"name = %@",calendarAttendee.firstName);
                                [calendarAttendees addObject:calendarAttendee];
                                calendarAttendee = NULL;
                            }
                        }
                    }
                } // end of going through the participants

                if (calendarAttendees.count > 1) {
                    // More than just the organiser, so we have a meeting
                    // get event details and put them into a meeting object

                    calendarEvent.eventID = thisEvent.eventIdentifier;
                    calendarEvent.eventTitle = thisEvent.title;
                    calendarEvent.dateTimeStart = [self.zoneDateFormat stringFromDate:thisEvent.startDate];
                    calendarEvent.dateTimeStop = [self.zoneDateFormat stringFromDate:thisEvent.endDate];
                    calendarEvent.location = thisEvent.location;
                    calendarEvent.attendees = calendarAttendees;
                    calendarEvent.organiser = minutesBy;

                    //save the event identifier so that we ignore in future
                    if (saveEventID) {
                        [self.meetingModel savePreviousEvent:eventID];
                    }

                    // add event to the NSArray
                    [calendarEvents addObject:calendarEvent];
                }
            }
        } //end of loop for examining the events
    }
}
return calendarEvents;
}

0 个答案:

没有答案