1// 2// PersistantState.m 3// Security 4// 5// Created by J Osborne on 7/11/13. 6// 7// 8 9#import "PersistantState.h" 10#import <Foundation/Foundation.h> 11 12@interface PersistantState() 13-(NSURL*)urlForStorage; 14@end 15 16@implementation PersistantState 17 18-(NSURL*)urlForStorage 19{ 20 return [NSURL fileURLWithPath:@"/var/mobile/Library/Preferences/com.apple.security.CircleJoinRequested.plist" isDirectory:NO]; 21} 22 23-(unsigned int)defaultPendingApplicationReminderAlertInterval 24{ 25 return 60 * 60 * 24 * 2; 26} 27 28+(instancetype)loadFromStorage 29{ 30 PersistantState *state = [[PersistantState alloc] init]; 31 if (!state) { 32 return state; 33 } 34 35 NSError *error = nil; 36 id plist = @{@"lastWritten": [NSDate distantPast]}; 37 38 NSData *stateData = [NSData dataWithContentsOfURL:[state urlForStorage] options:0 error:&error]; 39 if (!stateData) { 40 NSLog(@"Can't read state data (p=%@, err=%@)", [state urlForStorage], error); 41 } else { 42 NSPropertyListFormat format; 43 id plistTmp = [NSPropertyListSerialization propertyListWithData:stateData options: NSPropertyListMutableContainersAndLeaves format:&format error:&error]; 44 45 if (plistTmp == nil) { 46 NSLog(@"Can't deserialize %@, e=%@", stateData, error); 47 } else { 48 plist = plistTmp; 49 } 50 } 51 52 state.lastCircleStatus = plist[@"lastCircleStatus"] ? [plist[@"lastCircleStatus"] intValue] : kSOSCCCircleAbsent; 53 state.lastWritten = plist[@"lastWritten"]; 54 state.pendingApplicationReminder = plist[@"pendingApplicationReminder"] ? plist[@"pendingApplicationReminder"] : [NSDate distantFuture]; 55 state.applcationDate = plist[@"applcationDate"] ? plist[@"applcationDate"] : [NSDate distantPast]; 56 state.debugShowLeftReason = plist[@"debugShowLeftReason"]; 57 state.pendingApplicationReminderAlertInterval = plist[@"pendingApplicationReminderAlertInterval"] ? [plist[@"pendingApplicationReminderAlertInterval"] unsignedIntValue] : [state defaultPendingApplicationReminderAlertInterval]; 58 state.absentCircleWithNoReason = plist[@"absentCircleWithNoReason"] ? [plist[@"absentCircleWithNoReason"] intValue] : NO; 59 60 return state; 61} 62 63-(void)writeToStorage 64{ 65 NSDictionary *plist = @{@"lastCircleStatus": [NSNumber numberWithInt:self.lastCircleStatus], 66 @"lastWritten": [NSDate date], 67 @"pendingApplicationReminder": self.pendingApplicationReminder ? self.pendingApplicationReminder : [NSDate distantFuture], 68 @"applcationDate": self.applcationDate ? self.applcationDate : [NSDate distantPast], 69 @"pendingApplicationReminderAlertInterval": [NSNumber numberWithUnsignedInt:self.pendingApplicationReminderAlertInterval], 70 @"absentCircleWithNoReason": [NSNumber numberWithBool:self.absentCircleWithNoReason] 71 }; 72 if (self.debugShowLeftReason) { 73 NSMutableDictionary *tmp = [plist mutableCopy]; 74 tmp[@"debugShowLeftReason"] = self.debugShowLeftReason; 75 plist =[tmp copy]; 76 } 77 NSLog(@"writeToStorage plist=%@", plist); 78 79 NSError *error = nil; 80 NSData *stateData = [NSPropertyListSerialization dataWithPropertyList:plist format:NSPropertyListXMLFormat_v1_0 options:kCFPropertyListImmutable error:&error]; 81 if (!stateData) { 82 NSLog(@"Can't serialize %@: %@", plist, error); 83 return; 84 } 85 if (![stateData writeToURL:[self urlForStorage] options:NSDataWritingAtomic error:&error]) { 86 NSLog(@"Can't write to %@, error=%@", [self urlForStorage], error); 87 } 88} 89 90@end 91