-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathBSManagedDocument+SSYAuxiliaryData.m
147 lines (127 loc) · 5.11 KB
/
BSManagedDocument+SSYAuxiliaryData.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#import "BSManagedDocument+SSYAuxiliaryData.h"
#import "NSObject+DoNil.h"
NSString* auxiliaryDataFilename = @"auxiliaryData.plist";
@implementation BSManagedDocument (SSYAuxiliaryData)
+ (NSURL*)auxiliaryDataFileUrlForDocumentUrl:(NSURL*)url {
url = [url URLByAppendingPathComponent:auxiliaryDataFilename];
return url;
}
+ (NSString*)auxiliaryDataFilePathForDocumentPath:(NSString*)path {
path = [path stringByAppendingPathComponent:auxiliaryDataFilename];
return path;
}
+ (NSString *)documentPathForAuxiliaryDataFilePath:(NSString*)path
documentExtension:(NSString*)extension {
NSString* answer = nil;
if ([path.lastPathComponent isEqualToString:auxiliaryDataFilename]) {
path = [path stringByDeletingLastPathComponent];
if ([path.pathExtension isEqualToString:extension]) {
answer = path;
}
}
return answer;
}
- (NSURL*)auxiliaryDataFileUrl {
return [[self class] auxiliaryDataFileUrlForDocumentUrl:[self fileURL]];
}
+ (NSDictionary*)auxiliaryDataDictionaryFromDiskForDocumentUrl:(NSURL*)documentUrl {
NSDictionary* dic = nil;
NSData* data = [NSData dataWithContentsOfURL:[self auxiliaryDataFileUrlForDocumentUrl:documentUrl]];
if (data) {
dic = [NSPropertyListSerialization propertyListWithData:data
options:0
format:NULL
error:NULL];
}
if (!dic) {
dic = [NSDictionary dictionary];
}
return dic;
}
- (NSDictionary*)auxiliaryDataDictionaryFromDisk {
return [[self class] auxiliaryDataDictionaryFromDiskForDocumentUrl:[self fileURL]];
}
- (BOOL)writeToDiskAuxiliaryDataDictionary:(NSDictionary*)dic {
NSURL* url = [self auxiliaryDataFileUrl];
if (url) {
NSData* data = [NSPropertyListSerialization dataWithPropertyList:dic
format:NSPropertyListBinaryFormat_v1_0
options:0
error:NULL];
return [data writeToURL:url
atomically:YES];
} else {
/* This branch is expected if receiver is opted into asynchronous
saving, during the first attempt with a new document, because our
fileURL is nil. The subclass must have a mechanism to call this
method again after fileURL has been set. For example, in the
BkmkMgrs project, our BkmxDoc subclass has such a mechanism based
on -[BkmxDoc observeValueForKeyPath::::]. */
return NO;
}
}
- (id)auxiliaryObjectForKey:(NSString*)key {
return [[self auxiliaryDataDictionaryFromDisk] objectForKey:key];
}
- (BSManagedDocumentAuxiliaryDataWriteResult)setAuxiliaryObject:(id)newObject
forKey:(NSString*)key {
NSObject* existingObject = [self auxiliaryObjectForKey:key];
BSManagedDocumentAuxiliaryDataWriteResult result;
if (![NSObject isEqualHandlesNilObject1:existingObject
object2:newObject]) {
NSMutableDictionary* dic = [[self auxiliaryDataDictionaryFromDisk] mutableCopy];
if (newObject) {
[dic setObject:newObject
forKey:key];
} else {
[dic removeObjectForKey:key];
}
BOOL ok = [self writeToDiskAuxiliaryDataDictionary:dic];
if (ok) {
result = BSManagedDocumentAuxiliaryDataWriteResultDid;
} else {
result = BSManagedDocumentAuxiliaryDataWriteResultFailed;
}
#if !__has_feature(objc_arc)
[dic release];
#endif
} else {
/* Nothing to do */
result = BSManagedDocumentAuxiliaryDataWriteResultUnnecessary;
}
return result;
}
- (void)addAuxiliaryKeyValues:(NSDictionary*)keyValues {
NSDictionary* existingDic = [self auxiliaryDataDictionaryFromDisk];
NSMutableSet* staleKeys = [NSMutableSet new];
for (NSString* key in keyValues) {
NSObject* newValue = [keyValues objectForKey:key];
NSObject* oldValue = [existingDic objectForKey:key];
if (!oldValue) {
[staleKeys addObject:key];
}
else if (![newValue isEqual:oldValue]) {
[staleKeys addObject:key];
}
}
if (staleKeys.count > 0) {
NSMutableDictionary* newDic = [existingDic mutableCopy];
for (NSString* key in staleKeys) {
[newDic setObject:[keyValues objectForKey:key]
forKey:key];
}
[self writeToDiskAuxiliaryDataDictionary:newDic];
#if !__has_feature(objc_arc)
[newDic release];
#endif
}
#if !__has_feature(objc_arc)
[staleKeys release];
#endif
}
+ (id)auxiliaryObjectForKey:(NSString*)key
documentPackagePath:(NSString*)documentPath {
NSURL* documentUrl = [NSURL fileURLWithPath:documentPath];
return [[self auxiliaryDataDictionaryFromDiskForDocumentUrl:documentUrl] objectForKey:key];
}
@end