일정 관련 앱을 만들면서 정말 다양한 시간, 날짜 포맷에 대해 학습을 하게 되었다.
아이폰/안드로이드 모두 서비스를 하는 경우 날짜 포맷의 통일을 위해 UNIX의 Timestemp값을 사용하게 되는데 때문에 서버 API는 long형으로 내려 주게 되어 있었다.
CoreData를 사용하면서 테이블에 해당하는 Attribute를 설계할 때 일정의 시작일자와 종료일자를 Double형으로 잡아두었다.
애초에는 달력을 그리고 이것 저것 하느라 별 고민이 없다가 실제 구현이 들어가면서 산적한 문제들에 봉착하였다.
예전 웹개발을 할 때는 MS-SQL을 주로 사용했는데 조금만 생각하면 풀 수 있는 문제들도 미처 그 생각까지 접근을 못해 아까운 시간만 낭비하고 밤새 낑낑 거리면서 코딩을 했던 기억이 난다.
일정을 등록할 때 1일 ~ 3일까지 등록을 하거나 하루종일로 등록을 할 때 해당 기간 내에 등록된 모든 일정을 검색해서 가져와야 하는데 NSPredicate로 한다고 하니 갑자기 먹통이 된 것 같았다. 다행히 검색을 하니 관련 자료들이 있어 도움을 받아 문제를 해결 했다.
CoreData Schedule Attribute 사진을 캡처했다.
사용자가 특정 일을 선택하게 되면 해당 일자에 등록된 일정을 조회해서 보여주는 코드를 작성했다.
우선 Double형을 NSDate형으로 바꾸고 시작일자 시간을 00:00 00으로 설정한 뒤 끝나는 일자 시각을 23:59 59로 설정한 후
조건 검색을 수행하였다.
NSDateComponents *dateComp = [[NSCalendar currentCalendar]
components :(NSCalendarUnitYear + NSCalendarUnitMonth +
NSCalendarUnitDay + NSCalendarUnitSecond +
NSCalendarUnitMinute + NSCalendarUnitHour)
fromDate :_selectedDate];
dateComp.hour = 0;
dateComp.minute = 0;
dateComp.second = 0;
NSDate *sDate = [[NSCalendar currentCalendar] dateFromComponents:dateComp];
double startTimeStamp = [sDate timeIntervalSince1970] * 1000.0;
dateComp.hour = 23;
dateComp.minute = 59;
dateComp.second = 59;
NSDate *eDate = [[NSCalendar currentCalendar] dateFromComponents:dateComp];
double endTimeStamp = [eDate timeIntervalSince1970] * 1000.0;
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Schedule"];
if (_currentGroup) {
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"group_id == %ld AND sked_end >= sked_begin",
[_currentGroup.group_id integerValue]];
} else {
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"sked_end >= sked_begin"];
}
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"sked_begin" ascending:NO];
NSSortDescriptor *sort_reg = [NSSortDescriptor sortDescriptorWithKey:@"reg_date" ascending:NO];
fetchRequest.sortDescriptors = @[sort, sort_reg];
/*
#define APP_DELEGATE ((AppDelegate *)[[UIApplication sharedApplication] delegate])
#define APP_DELEGATE_MOC APP_DELEGATE.managedObjectContext
*/
NSError *fetchError = nil;
NSArray *dataArray = [APP_DELEGATE_MOC executeFetchRequest:fetchRequest error:&fetchError];
NSDateComponents를 이용해서 원하는 시간으로 초기화를 할 수 있다.
원하는 날짜로 설정을 해서 각각 시작 시간과 종료시간을 설정하는 코드와 함께 NSFetchRequest를 통해 Attribute객체를 구하고 NSPredicate를 통해 검색을 한다.
NSArray로 전달 받은 일정 리스트는 해당 일자에 표시해주면 된다.
double endTimeStamp = [eDate timeIntervalSince1970] * 1000.0;
1000.0을 곱해주는 것은 날짜값을 안드로이드와 맞추기 위해서 해주었다.
아이폰의 데이터 타입과 안드로이드가 달라 곱해주지 않어나 Double형보다 적은 데이터형일 경우는 정확한 날짜로의 변환이 안되었다.
이후 일정 상세보기나 모아보기 , 미확인 일정 등을 조회할 때 유용하게 사용했었다.
좀 바보스러운건 굳이 Double형을 사용하지 않고 NSDate형을 사용했더라면 좀 더 수월하지 않았을까?
여러 일을 병행하다 보니 미처 생각하지 못하고 테이블을 설계 했기 때문에 번거로움을 감해야 만 했다.
지금은 서비스가 종료된 SKT Cake앱의 일정 화면이다.
좋은 경험이 되었던 프로젝트라 애착이 많이 간다.
'프로그래밍 > Xcode-iOS' 카테고리의 다른 글
iOS 랜덤숫자와 객체 비교 예제 (arc4random(), indexOfObject) (0) | 2017.07.05 |
---|---|
[Xcode] Archive upload completed with warrings (0) | 2017.04.30 |
[iOS] Event Kit 이용하여 일정 등록 하는 방법 (0) | 2017.04.26 |
[iOS] 음력 변환(LunarSun Convert) 클래스 (0) | 2017.04.25 |
[iOS] Hex String to NSData (0) | 2017.04.24 |