'아이폰 앱 개발'에 해당되는 글 1건

  1. 2014.05.08 (Objective-C) EventKit을 사용한 캘린더 등록 및 표시하는 방법

iPhone 캘린더에 등록된 내용을 보여주거나 표시해주기 위해서는 EventKit을 이용하면 된다. 캘린더 이외에 리마인더도 제어 할 수 있으나 여기선 캘린더 등록 위주로 간단히 설명할 생각이다.



사실 애플도큐먼트만 봐도 굳이 설며이 필요없는 간단한 내용이지만 중요한 포인트는 

EventKit을 사용할 클래스는 싱글톤 클래스로 만들어 사용할 것이라는 내용.

(도큐먼트에 보면 로드하는데 시간이 걸리므로 로드 후 사용하는것이 좋다고 소개되어 있다.)

그러므로 일단 여기서도 싱글톤으로된 매니져클래스를 샘플로 만들어 보았다.


자세한 사용법은 아래의 링크를 참고하면 된다.(일본어임)

https://developer.apple.com/jp/devcenter/ios/library/documentation/EventKitProgGuide.pdf



본론으로 들어가서,

물론, EventKit, EventKitUI 두개의 프레임워크를 먼저 추가해 주어야 한다.

(이름만 봐서도 알겠지만 EventKitUI는 이벤트 편집을 위한 UI프레임워크이다.)






먼저 EventManager.h

필요한 이벤트킷을 임포트 해준 다음 싱글톤 인스턴스 메소드(sharedInstance)와 이벤트 검색을 위한 메소드(fetchEvent...) 그리고 이벤트 추가, 수정을 위한 화면표시용 메소드(eventEditController...)를 선언해 준다.



#import <EventKit/EventKit.h>

#import <EventKitUI/EventKitUI.h>


@interface EventManager : NSObject


+ (EventManager *)sharedInstance;


- (NSArray *)fetchEvent;

- (NSArray *)fetchEventStartDate:(NSDate *)startDate EndDate:(NSDate *)endDate;

- (void)eventEditController:(id)owner event:(EKEvent *)event;


@end




그다음 EventManager.m

싱글톤 클래스를 구현해 주기 위한 메소드들을 추가해 준 다음 헤더파일에 선언된 메소드를 정의해 준다.

그리고 이벤트정보에 접근하기 위한 이벤트스토어를 프로퍼티(EKEventStore)로 선언.

마지막으로 이벤트 추가, 수정을 위한 EventKitUI를 사용하기 위한 프로토콜을 명시해 준다.



@interface EventManager() <EKEventEditViewDelegate>


@property (nonatomicstrongEKEventStore *store;


@end



@implementation EventManager 


static EventManager *_sharedInstance;


#pragma mark - singleton

+ (EventManager *)sharedInstance

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _sharedInstance = [[self alloc] init];

    });

    

    return _sharedInstance;

    

}


+ (id)allocWithZone:(NSZone *)zone {

    

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        _sharedInstance = [super allocWithZone:zone];

    });

    

    return _sharedInstance;

    

}


- (id)init {

    self = [super init];

    if (self) {

        _store = [[EKEventStore alloc] init];

        

        if([EKEventStore authorizationStatusForEntityType:EKEntityTypeReminder] == EKAuthorizationStatusAuthorized) {

            //접근거부

        } else {

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

            [eventStore requestAccessToEntityType:EKEntityTypeReminder

                                       completion:^(BOOL granted, NSError *error) {

                                           if(granted) {

                                               // 처음 접근시 대화장자가 표시되는 경우 OK버튼을 누르면 여기로 들어옴

                                           } else {

                                               dispatch_async(dispatch_get_main_queue(), ^{

                                                   //접근권한 없음

                                                   UIAlertView *alert = [[UIAlertView alloc]

                                                                         initWithTitle:NSLocalizedString(@"This app does not have access to you reminders.", nil)

                                                                         message:NSLocalizedString(@"To display your reminder, enable [YOUR APP] in the \"Privacy\" → \"Reminders\" in the Settings.app.", nil)

                                                                         delegate:nil

                                                                         cancelButtonTitle:NSLocalizedString(@"OK", nil)

                                                                         otherButtonTitles:nil];

                                                   [alert show];

                                               });

                                           }

                                       }

             ];

        }

    }

    

    return self;

}


- (id)copyWithZone:(NSZone *)zone

{

    return self;

}


- (void)dealloc {

    

}


#pragma mark - Event fetch

- (NSArray *)fetchEvent {

    

    //기본값은 일주일로 잡아준다.

    

    NSCalendar *calendar = [NSCalendar currentCalendar];


    // 시작시간 작성

    NSDateComponents *oneWeekAgoComponents = [[NSDateComponents alloc] init]; oneWeekAgoComponents.day = -7;

    NSDate *oneDayAgo = [calendar dateByAddingComponents:oneWeekAgoComponents

                                                  toDate:[NSDate date]

                                                 options:0];

    // 종료시간 작성

    NSDateComponents *oneYearFromNowComponents = [[NSDateComponents alloc] init]; oneYearFromNowComponents.year = 1;

    NSDate *oneYearFromNow = [calendar dateByAddingComponents:oneYearFromNowComponents

                                                       toDate:[NSDate date]

                                                      options:0];

    

    return [self fetchEventStartDate:oneDayAgo EndDate:oneYearFromNow];

    

}


- (NSArray *)fetchEventStartDate:(NSDate *)startDate EndDate:(NSDate *)endDate {

    

    // 조건생성

    NSPredicate *predicate = [_store predicateForEventsWithStartDate:startDate

                                                            endDate:startDate

                                                          calendars:nil];

    // 조건에 따른 패치 실행.

    return [_store eventsMatchingPredicate:predicate];

    

}


#pragma mark - Event editing controller

- (void)eventEditController:(id)owner event:(EKEvent *)event {


    //event가 nil 일 경우에는 신규이벤트 등록이 된다.

    

    EKEventEditViewController *eventEditViewController = [EKEventEditViewController new];

    eventEditViewController.editViewDelegate = self;

    eventEditViewController.event = event;

    eventEditViewController.eventStore = _store;

    

    [owner presentViewController:eventEditViewController animated:YES completion:nil];

}


#pragma mark - EKEventEditViewDelegate

- (void)eventEditViewController:(EKEventEditViewController *)controller didCompleteWithAction:(EKEventEditViewAction)action

{

//UI에서 이벤트를 받을경우 처리할 딜리게이트 메소드.


NSError *error = nil;

switch (action) {

case EKEventEditViewActionCanceled:

break;

case EKEventEditViewActionSaved:

[controller.eventStore saveEvent:controller.event span:EKSpanThisEvent error:&error];

break;

case EKEventEditViewActionDeleted:

[controller.eventStore removeEvent:controller.event span:EKSpanThisEvent error:&error];

break;

default:

break;

}

    

[controller dismissViewControllerAnimated:YES completion:nil];

}


@end



기술한 샘플코드는 전혀 테스트를 하지 않았기 때문에 동작안할 수도 있으므로 참고만 하시길...






Posted by 악당잰 트랙백 0 : 댓글 0

댓글을 달아 주세요