0

iPhoneで奇妙な動作をしています。カレンダーイベント(EventKit)を使用するアプリケーションを作成しています。使用するクラスは次のとおりです。

.hのもの

#import "GenericManager.h"
#import <EventKit/EventKit.h>

#define oneDay      60*60*24
#define oneHour     60*60

@protocol CalendarManagerDelegate;

@interface CalendarManager : GenericManager

/*  
 * metodo che aggiunge un evento ad un calendario di nome Name nel giorno onDate.
 * L'evento da aggiungere viene recuperato tramite il dataSource che è quindi
 * OBBLIGATORIO (!= nil).
 *
 * Restituisce YES solo se il delegate è conforme al protocollo CalendarManagerDataSource.
 * NO altrimenti
 */
+ (BOOL) addEventForCalendarWithName:(NSString *) name fromDate:(NSDate *)fromDate toDate: (NSDate *) toDate withDelegate:(id<CalendarManagerDelegate>) delegate;

/*
 * metodo che aggiunge un evento per giorno compreso tra fromDate e toDate ad un
 * calendario di nome Name. L'evento da aggiungere viene recuperato tramite il dataSource
 * che è quindi OBBLIGATORIO (!= nil).
 *
 * Restituisce YES solo se il delegate è conforme al protocollo CalendarManagerDataSource.
 * NO altrimenti
 */
+ (BOOL) addEventsForCalendarWithName:(NSString *) name fromDate:(NSDate *)fromDate toDate: (NSDate *) toDate withDelegate:(id<CalendarManagerDelegate>) delegate;

@end

@protocol CalendarManagerDelegate <NSObject>

// viene inviato quando il calendario necessita informazioni sull' evento da aggiungere
- (void) calendarManagerDidCreateEvent:(EKEvent *) event;

@end

.m 1

//
//  CalendarManager.m
//  AppCampeggioSingolo
//
//  Created by CreatiWeb Srl on 12/17/12.
//  Copyright (c) 2012 CreatiWeb Srl. All rights reserved.
//

#import "CalendarManager.h"
#import "Commons.h"
#import <objc/message.h>

@interface CalendarManager ()

@end

@implementation CalendarManager

+ (void)requestToEventStore:(EKEventStore *)eventStore delegate:(id)delegate fromDate:(NSDate *)fromDate toDate: (NSDate *) toDate name:(NSString *)name
{
    if([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)])
    {
        // ios >= 6.0
        [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
            if (granted)
            {
                [self addEventForCalendarWithName:name fromDate: fromDate toDate: toDate inEventStore:eventStore withDelegate:delegate];
            }
            else
            {

            }
        }];
    }
    else if (class_getClassMethod([EKCalendar class], @selector(calendarIdentifier)) != nil)
    {
        // ios >= 5.0 && ios < 6.0
        [self addEventForCalendarWithName:name fromDate:fromDate toDate:toDate inEventStore:eventStore withDelegate:delegate];
    }
    else
    {
        // ios < 5.0
        EKCalendar *myCalendar = [eventStore defaultCalendarForNewEvents];

        EKEvent *event = [self generateEventForCalendar:myCalendar fromDate: fromDate toDate: toDate inEventStore:eventStore withDelegate:delegate];
        [eventStore saveEvent:event span:EKSpanThisEvent error:nil];
    }
}

/*
 * metodo che recupera l'identificativo del calendario associato all'app o nil se non è mai stato creato.
 */
+ (NSString *) identifierForCalendarName: (NSString *) name
{
    NSString * confFileName = [self pathForFile:kCurrentCalendarFileName];

    NSDictionary *confCalendar = [NSDictionary dictionaryWithContentsOfFile:confFileName];
    NSString *currentIdentifier = [confCalendar objectForKey:name];
    return currentIdentifier;
}

/*
 * memorizza l'identifier del calendario
 */
+ (void) saveCalendarIdentifier:(NSString *) identifier andName: (NSString *) name
{
    if (identifier != nil)
    {
        NSString * confFileName = [self pathForFile:kCurrentCalendarFileName];
        NSMutableDictionary *confCalendar = [NSMutableDictionary dictionaryWithContentsOfFile:confFileName];
        if (confCalendar == nil)
        {
            confCalendar = [NSMutableDictionary dictionaryWithCapacity:1];
        }

        [confCalendar setObject:identifier forKey:name];
        [confCalendar writeToFile:confFileName atomically:YES];
    }
}

+ (EKCalendar *)getCalendarWithName:(NSString *)name inEventStore:(EKEventStore *)eventStore withLocalSource: (EKSource *)localSource forceCreation:(BOOL) force
{
    EKCalendar *myCalendar;
    NSString *identifier = [self identifierForCalendarName:name];

    if (force || identifier == nil)
    {
        NSLog(@"create new calendar");
        if (class_getClassMethod([EKCalendar class], @selector(calendarForEntityType:eventStore:)) != nil) {
            // da ios 6.0 in avanti
            myCalendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
        } else {
            myCalendar = [EKCalendar calendarWithEventStore:eventStore];
        }
        myCalendar.title = name;
        myCalendar.source = localSource;
        NSError *error = nil;
        BOOL result = [eventStore saveCalendar:myCalendar commit:YES error:&error];
        if (result) {
            NSLog(@"Saved calendar %@ to event store. %@",myCalendar,eventStore);
        } else {
            NSLog(@"Error saving calendar: %@.", error);
        }

        [self saveCalendarIdentifier:myCalendar.calendarIdentifier andName:name];
    }
    //   You can also configure properties like the calendar color etc. The important part is to store the identifier for later use. On the other hand if you already have the identifier, you can just fetch the calendar:

    else
    {
        myCalendar = [eventStore calendarWithIdentifier:identifier];
        NSLog(@"fetch an old-one = %@",myCalendar);
    }

    return myCalendar;
}

+ (EKCalendar *)addEventForCalendarWithName: (NSString *) name fromDate:(NSDate *)fromDate toDate: (NSDate *) toDate inEventStore:(EKEventStore *)eventStore withDelegate: (id<CalendarManagerDelegate>) delegate
{
    // da ios 5.0 in avanti
    EKCalendar *myCalendar;
    EKSource *localSource = nil;
    for (EKSource *source in eventStore.sources)
    {
        if (source.sourceType == EKSourceTypeLocal)
        {
            localSource = source;
            break;
        }
    }

    @synchronized(self)
    {
        myCalendar = [self getCalendarWithName:name inEventStore:eventStore withLocalSource:localSource forceCreation:NO];
        if (myCalendar == nil)
            myCalendar = [self getCalendarWithName:name inEventStore:eventStore withLocalSource:localSource forceCreation:YES];

        NSLog(@"End synchronized block %@",myCalendar);
    }

    EKEvent *event = [self generateEventForCalendar:myCalendar fromDate:fromDate toDate:toDate inEventStore:eventStore withDelegate:delegate];
    [eventStore saveEvent:event span:EKSpanThisEvent error:nil];

    return myCalendar;
}

+ (EKEvent *) generateEventForCalendar: (EKCalendar *) calendar fromDate:(NSDate *)fromDate toDate: (NSDate *) toDate inEventStore:(EKEventStore *) eventStore withDelegate:(id<CalendarManagerDelegate>) delegate
{
    EKEvent *event = [EKEvent eventWithEventStore:eventStore];
    event.startDate=fromDate;
    event.endDate=toDate;
    [delegate calendarManagerDidCreateEvent:event];
    [event setCalendar:calendar];

    // ricerca dell'evento nel calendario, se ne trovo uno uguale non lo inserisco
    NSPredicate *predicate = [eventStore predicateForEventsWithStartDate:fromDate endDate:toDate calendars:[NSArray arrayWithObject:calendar]];
    NSArray *matchEvents = [eventStore eventsMatchingPredicate:predicate];

    if ([matchEvents count] > 0) {
        // ne ho trovati di gia' presenti, vediamo se uno e' quello che vogliamo inserire

        BOOL found = NO;

        for (EKEvent *fetchEvent in matchEvents) {
            if ([fetchEvent.title isEqualToString:event.title] &&
                [fetchEvent.notes isEqualToString:event.notes])
            {
                found = YES;
                break;
            }
        }
        if (found)
        {
            // esiste già e quindi non lo inserisco
            NSLog(@"OH NOOOOOO!!");
            event = nil;
        }
    }

    return event;
}

#pragma mark - Public Methods

+ (BOOL) addEventForCalendarWithName:(NSString *) name fromDate:(NSDate *)fromDate toDate: (NSDate *) toDate withDelegate:(id<CalendarManagerDelegate>) delegate
{
    BOOL retVal = YES;

    EKEventStore *eventStore=[[EKEventStore alloc] init];

    if ([delegate conformsToProtocol:@protocol(CalendarManagerDelegate)])
    {

        [self requestToEventStore:eventStore delegate:delegate fromDate:fromDate toDate: toDate  name:name];
    }
    else
    {
        retVal = NO;
    }

    return retVal;
}

+ (BOOL) addEventsForCalendarWithName:(NSString *) name fromDate:(NSDate *)fromDate toDate: (NSDate *) toDate withDelegate:(id<CalendarManagerDelegate>) delegate
{
    BOOL retVal = YES;

    NSDate *dateCursor = fromDate;

    EKEventStore *eventStore=[[EKEventStore alloc] init];


    if ([delegate conformsToProtocol:@protocol(CalendarManagerDelegate)])
    {

        while (retVal && ([dateCursor compare:toDate] == NSOrderedAscending)) {
            NSDate *finish = [dateCursor dateByAddingTimeInterval:oneDay];
            [self requestToEventStore:eventStore delegate:delegate fromDate: dateCursor toDate: finish  name:name];

            dateCursor = [dateCursor dateByAddingTimeInterval:oneDay];
        }


    }
    else
    {
        retVal = NO;
    }

    return retVal;
}

@end

実際には、私の iPhone でログを取得します。

fetch an old-one = (null) 19/12/2012 11:33:09.520 AppCampeggioSingolo [730:8 b1b] create new calendar 19/12/2012 11:33:09.558 AppCampeggioSingolo [730:8 b1b] 保存されたカレンダー EKCalendar

イベントを追加するたびに、彼が追加したiCalカレンダーイベントでそれを見つけることができません。しかし、私の友人の iPhone では、すべてが正しく機能しています。問題がコードに起因しているとは思えませんが、それが何であるかを理解していません。

昨日一日中、今日の一部を Google で検索しましたが、まだ何も見つかりませんでした。

どんな助けでも大歓迎です

編集:電話を忘れました

[CalendarManager addEventForCalendarWithName: @"myCalendar" fromDate:fromDate toDate: toDate withDelegate:self];

デリゲートメソッドでは、このようにイベントのタイトルとメモを設定するだけです

- (void) calendarManagerDidCreateEvent:(EKEvent *) event
{
    event.title = @"the title";
    event.notes = @"some notes";
}
4

1 に答える 1

0

解決しました!!! 今日、iPhone は黒い画面で動かなくなり、電源を切るオプションがありませんでした。だから「私はそれを復元することにしました...魔法!カレンダーは現在正常に機能しています... :)

情報の奇妙な方法 :p

于 2012-12-21T11:10:12.313 に答える