You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
515 lines
18 KiB
515 lines
18 KiB
// |
|
// CLTimezoneData.m |
|
// Clocker |
|
// |
|
// Created by Abhishek Banthia on 12/22/15. |
|
// |
|
// |
|
|
|
#import "CLAPI.h" |
|
#import "CLTimezoneData.h" |
|
#import "CommonStrings.h" |
|
#import "DateTools.h" |
|
#import "PanelController.h" |
|
#include <CoreFoundation/CoreFoundation.h> |
|
#include <IOKit/IOKitLib.h> |
|
#include "EDSunriseSet.h" |
|
|
|
@implementation CLTimezoneData |
|
|
|
-(instancetype)initWithDictionary:(NSDictionary *)dictionary |
|
{ |
|
self = [super init]; |
|
|
|
if (self) |
|
{ |
|
self.customLabel = dictionary[CLCustomLabel]; |
|
self.timezoneID = dictionary[CLTimezoneID]; |
|
self.latitude = dictionary[@"latitude"]; |
|
self.longitude = dictionary[@"longitude"]; |
|
self.place_id = dictionary[CLPlaceIdentifier]; |
|
self.formattedAddress = dictionary[CLTimezoneName]; |
|
self.isFavourite = [NSNumber numberWithInt:NSOffState]; |
|
self.selectionType = CLCitySelection; |
|
} |
|
|
|
return self; |
|
} |
|
|
|
+ (void)setInitialTimezoneData |
|
{ |
|
CLTimezoneData *newData = [self new]; |
|
newData.timezoneID = [[NSTimeZone systemTimeZone] name]; |
|
newData.formattedAddress = newData.timezoneID; |
|
|
|
[newData saveObjectToPreferences]; |
|
} |
|
|
|
- (BOOL)saveObjectToPreferences |
|
{ |
|
|
|
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:self]; |
|
NSMutableArray *array = [NSMutableArray new]; |
|
[array addObject:encodedObject]; |
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:array forKey:CLDefaultPreferenceKey]; |
|
|
|
return YES; |
|
} |
|
|
|
+ (instancetype)getCustomObject:(NSData *)encodedData |
|
{ |
|
|
|
if (encodedData) |
|
{ |
|
if ([encodedData isKindOfClass:[NSDictionary class]]) |
|
{ |
|
CLTimezoneData *newObject = [[self alloc] initWithDictionary:(NSDictionary *)encodedData]; |
|
return newObject; |
|
} |
|
CLTimezoneData *object = [NSKeyedUnarchiver unarchiveObjectWithData:encodedData]; |
|
return object; |
|
|
|
} |
|
|
|
return nil; |
|
|
|
} |
|
|
|
- (void)encodeWithCoder:(NSCoder *)coder |
|
{ |
|
[coder encodeObject:self.place_id forKey:@"place_id"]; |
|
[coder encodeObject:self.formattedAddress forKey:@"formattedAddress"]; |
|
[coder encodeObject:self.customLabel forKey:@"customLabel"]; |
|
[coder encodeObject:self.timezoneID forKey:@"timezoneID"]; |
|
[coder encodeObject:self.nextUpdate forKey:@"nextUpdate"]; |
|
[coder encodeObject:self.latitude forKey:@"latitude"]; |
|
[coder encodeObject:self.longitude forKey:@"longitude"]; |
|
[coder encodeObject:self.isFavourite forKey:@"isFavourite"]; |
|
[coder encodeObject:self.sunriseTime forKey:@"sunriseTime"]; |
|
[coder encodeObject:self.sunsetTime forKey:@"sunsetTime"]; |
|
[coder encodeInteger:self.selectionType forKey:@"selectionType"]; |
|
} |
|
|
|
- (instancetype)initWithCoder:(NSCoder *)coder |
|
{ |
|
self = [super init]; |
|
|
|
if (self) |
|
{ |
|
self.place_id = [coder decodeObjectForKey:@"place_id"]; |
|
self.formattedAddress = [coder decodeObjectForKey:@"formattedAddress"]; |
|
self.customLabel = [coder decodeObjectForKey:@"customLabel"]; |
|
self.timezoneID = [coder decodeObjectForKey:@"timezoneID"]; |
|
self.nextUpdate = [coder decodeObjectForKey:@"nextUpdate"]; |
|
self.latitude = [coder decodeObjectForKey:@"latitude"]; |
|
self.longitude = [coder decodeObjectForKey:@"longitude"]; |
|
self.isFavourite = [coder decodeObjectForKey:@"isFavourite"]; |
|
self.sunriseTime = [coder decodeObjectForKey:@"sunriseTime"]; |
|
self.sunsetTime = [coder decodeObjectForKey:@"sunsetTime"]; |
|
self.selectionType = [coder decodeIntegerForKey:@"selectionType"]; |
|
} |
|
|
|
return self; |
|
} |
|
|
|
-(NSString *)description |
|
{ |
|
return [NSString stringWithFormat:@"TimezoneID: %@\nFormatted Address: %@\nCustom Label: %@\nLatitude: %@\nLongitude:%@\nPlaceID: %@\nisFavourite: %@\nSunrise Time: %@\nSunset Time: %@\nSelection Type: %zd", self.timezoneID, |
|
self.formattedAddress, |
|
self.customLabel, |
|
self.latitude, |
|
self.longitude, |
|
self.place_id, |
|
self.isFavourite, |
|
self.sunriseTime, |
|
self.sunsetTime, |
|
self.selectionType]; |
|
} |
|
|
|
- (NSString *)formatStringShouldContainCity:(BOOL)value |
|
{ |
|
if (self.customLabel.length > 0) |
|
{ |
|
return self.customLabel; |
|
} |
|
|
|
if ([self.formattedAddress length] > 0) |
|
{ |
|
return self.formattedAddress; |
|
} |
|
else if (self.timezoneID) |
|
{ |
|
NSString *timezoneID = self.timezoneID; |
|
|
|
NSRange range = [timezoneID rangeOfString:@"/"]; |
|
if (range.location != NSNotFound) |
|
{ |
|
timezoneID = [timezoneID substringWithRange:NSMakeRange(range.location+1, timezoneID.length-1 - range.location)]; |
|
} |
|
return timezoneID; |
|
} |
|
else |
|
{ |
|
return @"Error"; |
|
} |
|
|
|
} |
|
|
|
- (NSString *)getTimeForTimeZoneWithFutureSliderValue:(NSInteger)futureSliderValue |
|
{ |
|
NSCalendar *currentCalendar = [NSCalendar autoupdatingCurrentCalendar]; |
|
NSDate *newDate = [currentCalendar dateByAddingUnit:NSCalendarUnitMinute |
|
value:futureSliderValue |
|
toDate:[NSDate date] |
|
options:kNilOptions]; |
|
NSDateFormatter *dateFormatter = [NSDateFormatter new]; |
|
dateFormatter.dateStyle = kCFDateFormatterNoStyle; |
|
|
|
NSNumber *is24HourFormatSelected = [[NSUserDefaults standardUserDefaults] objectForKey:CL24hourFormatSelectedKey]; |
|
|
|
is24HourFormatSelected.boolValue ? [dateFormatter setDateFormat:@"HH:mm"] : [dateFormatter setDateFormat:@"hh:mm a"]; |
|
|
|
dateFormatter.timeZone = [NSTimeZone timeZoneWithName:self.timezoneID]; |
|
//In the format 22:10 |
|
|
|
return [dateFormatter stringFromDate:newDate]; |
|
} |
|
|
|
- (void)retrieveLatitudeAndLongitudeWithSearchString:(NSString *)formattedString |
|
{ |
|
NSString *preferredLanguage = [NSLocale preferredLanguages][0]; |
|
|
|
if (![CLAPI isUserConnectedToInternet]) |
|
{ |
|
/*Show some kind of information label*/ |
|
return; |
|
} |
|
|
|
NSArray* words = [formattedString componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceAndNewlineCharacterSet]]; |
|
|
|
formattedString = [words componentsJoinedByString:CLEmptyString]; |
|
|
|
NSString *urlString = [NSString stringWithFormat:CLLocationSearchURL, formattedString, preferredLanguage]; |
|
|
|
[CLAPI dataTaskWithServicePath:urlString |
|
bySender:self |
|
withCompletionBlock:^(NSError *error, NSDictionary *json) { |
|
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{ |
|
|
|
if (error || [json[@"status"] isEqualToString:@"ZERO_RESULTS"]) |
|
{ |
|
return; |
|
} |
|
|
|
|
|
[json[@"results"] enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull dictionary, NSUInteger idx, BOOL * _Nonnull stop) |
|
{ |
|
|
|
if ([dictionary[CLPlaceIdentifier] isEqualToString:self.place_id]) |
|
{ |
|
//We have a match |
|
|
|
NSDictionary *latLang = [[dictionary objectForKey:@"geometry"] objectForKey:@"location"]; |
|
self.latitude = [NSString stringWithFormat:@"%@", latLang[@"lat"]]; |
|
self.longitude = [NSString stringWithFormat:@"%@", latLang[@"lng"]]; |
|
} |
|
|
|
}]; |
|
|
|
}); |
|
|
|
}]; |
|
|
|
} |
|
|
|
- (NSString *)getLocalCurrentDate |
|
{ |
|
NSDateFormatter *dateFormatter = [NSDateFormatter new]; |
|
dateFormatter.dateStyle = kCFDateFormatterShortStyle; |
|
dateFormatter.timeStyle = kCFDateFormatterNoStyle; |
|
dateFormatter.timeZone = [NSTimeZone systemTimeZone]; |
|
|
|
return [NSDateFormatter localizedStringFromDate:[NSDate date] |
|
dateStyle:NSDateFormatterShortStyle |
|
timeStyle:NSDateFormatterNoStyle]; |
|
|
|
} |
|
|
|
- (NSString *)compareSystemDate:(NSString *)systemDate toTimezoneDate:(NSString *)date |
|
{ |
|
NSDateFormatter *formatter = [NSDateFormatter new]; |
|
formatter.dateFormat = [NSDateFormatter dateFormatFromTemplate:@"MM/dd/yyyy" |
|
options:0 |
|
locale:[NSLocale currentLocale]]; |
|
|
|
NSDate *localDate = [formatter dateFromString:systemDate]; |
|
NSDate *timezoneDate = [formatter dateFromString:date]; |
|
|
|
// Specify which units we would like to use |
|
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar]; |
|
NSInteger weekday = [calendar component:NSCalendarUnitWeekday fromDate:localDate]; |
|
|
|
if ([self.nextUpdate isKindOfClass:[NSString class]]) |
|
{ |
|
|
|
NSUInteger units = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay; |
|
NSDateComponents *comps = [[NSCalendar currentCalendar] components:units fromDate:timezoneDate]; |
|
comps.day = comps.day + 1; |
|
NSDate *tomorrowMidnight = [[NSCalendar currentCalendar] dateFromComponents:comps]; |
|
|
|
CLTimezoneData *newDataObject = [CLTimezoneData new]; |
|
newDataObject.timezoneID = self.timezoneID; |
|
newDataObject.formattedAddress = self.formattedAddress; |
|
newDataObject.latitude = self.latitude; |
|
newDataObject.longitude = self.longitude; |
|
newDataObject.customLabel = self.customLabel; |
|
newDataObject.place_id = self.place_id; |
|
newDataObject.nextUpdate = tomorrowMidnight; |
|
newDataObject.isFavourite = [NSNumber numberWithInt:NSOffState]; |
|
|
|
__block PanelController *panelController; |
|
|
|
[[NSApplication sharedApplication].windows enumerateObjectsUsingBlock:^(NSWindow * _Nonnull window, NSUInteger idx, BOOL * _Nonnull stop) { |
|
if ([window.windowController isMemberOfClass:[PanelController class]]) |
|
{ |
|
panelController = window.windowController; |
|
} |
|
}]; |
|
|
|
[panelController.defaultPreferences replaceObjectAtIndex:[panelController.defaultPreferences indexOfObject:self] withObject:newDataObject]; |
|
[[NSUserDefaults standardUserDefaults] setObject:panelController.defaultPreferences forKey:CLDefaultPreferenceKey]; |
|
} |
|
|
|
NSInteger daysApart = [timezoneDate daysFrom:localDate]; |
|
|
|
if (daysApart == 0) { |
|
return @"Today"; |
|
} |
|
else if (daysApart == -1) |
|
{ |
|
return @"Yesterday"; |
|
} |
|
else if (daysApart == 1) |
|
{ |
|
return @"Tomorrow"; |
|
} |
|
else |
|
{ |
|
return [self getWeekdayFromInteger:weekday+2]; |
|
} |
|
} |
|
|
|
- (NSString *)getDateForTimeZoneWithFutureSliderValue:(NSInteger)futureSliderValue |
|
andDisplayType:(CLDateDisplayType)type |
|
{ |
|
NSCalendar *currentCalendar = [NSCalendar autoupdatingCurrentCalendar]; |
|
NSDate *newDate = [currentCalendar dateByAddingUnit:NSCalendarUnitMinute |
|
value:futureSliderValue |
|
toDate:[NSDate date] |
|
options:kNilOptions]; |
|
NSDateFormatter *dateFormatter = [NSDateFormatter new]; |
|
dateFormatter.dateStyle = kCFDateFormatterShortStyle; |
|
dateFormatter.timeStyle = kCFDateFormatterNoStyle; |
|
|
|
dateFormatter.timeZone = [NSTimeZone timeZoneWithName:self.timezoneID]; |
|
|
|
NSNumber *relativeDayPreference = [[NSUserDefaults standardUserDefaults] objectForKey:CLRelativeDateKey]; |
|
if (relativeDayPreference.integerValue == 0 && type == CLPanelDisplay) { |
|
return [self compareSystemDate:[self getLocalCurrentDate] |
|
toTimezoneDate:[dateFormatter stringFromDate:newDate]]; |
|
} |
|
else |
|
{ |
|
NSDateFormatter *formatter = [NSDateFormatter new]; |
|
formatter.dateFormat = [NSDateFormatter dateFormatFromTemplate:@"MM/dd/yyyy" options:0 locale:[NSLocale currentLocale]]; |
|
|
|
NSDate *convertedDate = [formatter dateFromString:[dateFormatter stringFromDate:newDate]]; |
|
|
|
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar]; |
|
NSInteger weekday = [calendar component:NSCalendarUnitWeekday fromDate:convertedDate]; |
|
return [self getWeekdayFromInteger:weekday]; |
|
} |
|
} |
|
|
|
- (NSString *)getWeekdayFromInteger:(NSInteger)weekdayInteger |
|
{ |
|
|
|
if (weekdayInteger > 7) { |
|
weekdayInteger = weekdayInteger - 7; |
|
} |
|
|
|
switch (weekdayInteger) { |
|
case 1: |
|
return @"Sunday"; |
|
break; |
|
|
|
case 2: |
|
return @"Monday"; |
|
break; |
|
|
|
case 3: |
|
return @"Tuesday"; |
|
break; |
|
|
|
case 4: |
|
return @"Wednesday"; |
|
break; |
|
|
|
case 5: |
|
return @"Thursday"; |
|
break; |
|
|
|
case 6: |
|
return @"Friday"; |
|
break; |
|
|
|
case 7: |
|
return @"Saturday"; |
|
break; |
|
|
|
default: |
|
return @"Error"; |
|
break; |
|
} |
|
} |
|
|
|
- (NSString *)getMenuTitle |
|
{ |
|
NSMutableString *menuTitle = [NSMutableString new]; |
|
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; |
|
NSNumber *shouldCityBeShown = [userDefaults objectForKey:CLShowPlaceInMenu]; |
|
NSNumber *shouldDayBeShown = [userDefaults objectForKey:CLShowDayInMenu]; |
|
NSNumber *shouldDateBeShown = [userDefaults objectForKey:CLShowDateInMenu]; |
|
|
|
if (shouldCityBeShown.boolValue == 0) |
|
{ |
|
|
|
self.customLabel.length > 0 ? |
|
[menuTitle appendString:self.customLabel] : |
|
[menuTitle appendString:self.formattedAddress]; |
|
|
|
} |
|
|
|
if (shouldDayBeShown.boolValue == 0) |
|
{ |
|
NSString *substring = [self getDateForTimeZoneWithFutureSliderValue:0 andDisplayType:CLMenuDisplay]; |
|
|
|
substring = [substring substringToIndex:3]; |
|
|
|
if (menuTitle.length > 0) |
|
{ |
|
[menuTitle appendFormat:@" %@",substring.capitalizedString]; |
|
} |
|
else |
|
{ |
|
[menuTitle appendString:substring.capitalizedString]; |
|
} |
|
} |
|
|
|
if (shouldDateBeShown.boolValue == 0) |
|
{ |
|
NSString *date = [[NSDate date] formattedDateWithFormat:@"MMM dd" timeZone:[NSTimeZone timeZoneWithName:self.timezoneID] locale:[NSLocale currentLocale]]; |
|
|
|
if (menuTitle.length > 0) |
|
{ |
|
[menuTitle appendFormat:@" %@",date]; |
|
} |
|
else |
|
{ |
|
[menuTitle appendString:date]; |
|
} |
|
} |
|
|
|
menuTitle.length > 0 ? |
|
[menuTitle appendFormat:@" %@",[self getTimeForTimeZoneWithFutureSliderValue:0]] : |
|
[menuTitle appendString:[self getTimeForTimeZoneWithFutureSliderValue:0]]; |
|
|
|
return menuTitle; |
|
} |
|
|
|
-(void)initializeSunriseSunsetWithSliderValue:(NSInteger)sliderValue |
|
{ |
|
|
|
if (!self.latitude || !self.longitude) |
|
{ |
|
//Retrieve the values using Google Places API |
|
|
|
if (self.selectionType == CLTimezoneSelection) |
|
{ |
|
/* A timezone has been selected*/ |
|
|
|
NSLog(@"%@", self); |
|
|
|
return; |
|
} |
|
|
|
[self retrieveLatitudeAndLongitudeWithSearchString:self.formattedAddress]; |
|
|
|
} |
|
|
|
EDSunriseSet *sunriseSetObject = [EDSunriseSet sunrisesetWithDate:[[NSCalendar autoupdatingCurrentCalendar] |
|
dateByAddingUnit:NSCalendarUnitMinute |
|
value:sliderValue |
|
toDate:[NSDate date] |
|
options:kNilOptions] |
|
timezone:[NSTimeZone timeZoneWithName:self.timezoneID] |
|
latitude:self.latitude.doubleValue |
|
longitude:self.longitude.doubleValue]; |
|
self.sunriseTime = sunriseSetObject.sunrise; |
|
self.sunsetTime = sunriseSetObject.sunset; |
|
} |
|
|
|
|
|
-(NSString *)getFormattedSunriseOrSunsetTimeAndSliderValue:(NSInteger)sliderValue |
|
{ |
|
/* We have to call this everytime so that we get an updated value everytime! */ |
|
|
|
[self initializeSunriseSunsetWithSliderValue:sliderValue]; |
|
|
|
if (!self.sunriseTime && !self.sunsetTime) |
|
{ |
|
return CLEmptyString; |
|
} |
|
|
|
self.sunriseOrSunset = [self.sunriseTime isLaterThanOrEqualTo:[NSDate date]]; |
|
|
|
NSDate *newDate = self.sunriseOrSunset ? self.sunriseTime : self.sunsetTime; |
|
|
|
NSDateFormatter *dateFormatter = [NSDateFormatter new]; |
|
|
|
dateFormatter.dateStyle = kCFDateFormatterNoStyle; |
|
|
|
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:self.timezoneID]]; |
|
|
|
NSNumber *is24HourFormatSelected = [[NSUserDefaults standardUserDefaults] objectForKey:CL24hourFormatSelectedKey]; |
|
|
|
is24HourFormatSelected.boolValue ? [dateFormatter setDateFormat:@"HH:mm"] : [dateFormatter setDateFormat:@"hh:mm a"]; |
|
|
|
//In the format 22:10 |
|
|
|
return [dateFormatter stringFromDate:newDate]; |
|
|
|
} |
|
|
|
- (NSString *)getFullFledgedDateForTimeWithDate:(NSDate *)date |
|
{ |
|
NSCalendar *currentCalendar = [NSCalendar autoupdatingCurrentCalendar]; |
|
|
|
NSDate *newDate = [currentCalendar dateByAddingUnit:NSCalendarUnitMinute |
|
value:0 |
|
toDate:date |
|
options:kNilOptions]; |
|
|
|
NSDateFormatter *dateFormatter = [NSDateFormatter new]; |
|
|
|
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm a"]; |
|
|
|
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:self.timezoneID]]; |
|
|
|
return [dateFormatter stringFromDate:newDate]; |
|
} |
|
|
|
@end
|
|
|