KNPersistentState.m
1 /* 2 * Copyright (c) 2013-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25 #import "KNPersistentState.h" 26 #import <utilities/debugging.h> 27 28 @implementation KNPersistentState 29 30 -(NSURL*)urlForStorage 31 { 32 return [NSURL URLWithString:@"Preferences/com.apple.security.KCN.plist" relativeToURL:[[NSFileManager defaultManager] URLForDirectory:NSLibraryDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:nil]]; 33 } 34 35 +(instancetype)loadFromStorage 36 { 37 KNPersistentState *state = [KNPersistentState new]; 38 if (!state) { 39 return state; 40 } 41 42 id plist = @{@"lastWritten": [NSDate distantPast]}; 43 44 NSError *error = nil; 45 NSData *stateData = [NSData dataWithContentsOfURL:[state urlForStorage] options:0 error:&error]; 46 if (!stateData) { 47 secdebug("kcn", "Can't read state data (p=%@, err=%@)", [state urlForStorage], error); 48 } else { 49 NSPropertyListFormat format; 50 plist = [NSPropertyListSerialization propertyListWithData:stateData options: NSPropertyListMutableContainersAndLeaves format:&format error:&error]; 51 52 if (plist == nil) { 53 secdebug("kcn", "Can't deserialize %@, e=%@", stateData, error); 54 } 55 } 56 57 state.lastCircleStatus = plist[@"lastCircleStatus"] ? [plist[@"lastCircleStatus"] intValue] : kSOSCCCircleAbsent; 58 state.lastWritten = plist[@"lastWritten"]; 59 state.pendingApplicationReminder = plist[@"pendingApplicationReminder"] ?: [NSDate distantFuture]; 60 state.applicationDate = plist[@"applicationDate"] ?: [NSDate distantPast]; 61 state.debugLeftReason = plist[@"debugLeftReason"]; 62 state.pendingApplicationReminderInterval = plist[@"pendingApplicationReminderInterval"]; 63 state.absentCircleWithNoReason = plist[@"absentCircleWithNoReason"] ? [plist[@"absentCircleWithNoReason"] intValue] : NO; 64 65 if (!state.pendingApplicationReminderInterval || [state.pendingApplicationReminderInterval doubleValue] <= 0) { 66 state.pendingApplicationReminderInterval = [NSNumber numberWithUnsignedInt: 24*60*60]; 67 } 68 69 return state; 70 } 71 72 -(void)writeToStorage 73 { 74 NSMutableDictionary *plist = [@{@"lastCircleStatus" : [NSNumber numberWithInt:self.lastCircleStatus], 75 @"lastWritten" : [NSDate date], 76 @"applicationDate" : self.applicationDate, 77 @"pendingApplicationReminder" : self.pendingApplicationReminder, 78 @"pendingApplicationReminderInterval": self.pendingApplicationReminderInterval, 79 @"absentCircleWithNoReason" : [NSNumber numberWithBool:self.absentCircleWithNoReason], 80 } mutableCopy]; 81 if (self.debugLeftReason) 82 plist[@"debugLeftReason"] = self.debugLeftReason; 83 secdebug("kcn", "writeToStorage plist=%@", plist); 84 85 NSError *error = nil; 86 NSData *stateData = [NSPropertyListSerialization dataWithPropertyList:plist format:NSPropertyListXMLFormat_v1_0 options:kCFPropertyListImmutable error:&error]; 87 if (!stateData) { 88 secdebug("kcn", "Can't serialize %@: %@", plist, error); 89 return; 90 } 91 if (![stateData writeToURL:[self urlForStorage] options:NSDataWritingAtomic error:&error]) { 92 secdebug("kcn", "Can't write to %@, error=%@", [self urlForStorage], error); 93 } 94 } 95 96 97 @end