cordova-plugin-mserviceinterface-2.0 1.0.21 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +28 -28
- package/plugin.xml +153 -153
- package/src/android/CallbackProgressDialog.java +53 -53
- package/src/android/FileProvider.java +7 -7
- package/src/android/backgroundNotification.java +120 -120
- package/src/android/doubleogradle.gradle +5 -5
- package/src/android/mInterface.java +2087 -2066
- package/src/android/mInterfaceReceiver.java +59 -59
- package/src/android/mInterfaceService.java +749 -749
- package/src/android/mInterfaceUtil.java +1686 -1688
- package/src/android/res/xml/network_security_config.xml +8 -8
- package/src/android/res/xml/opener_paths.xml +16 -16
- package/src/ios/InternetConnection.h +64 -64
- package/src/ios/InternetConnection.m +242 -242
- package/src/ios/SSZipArchive.h +146 -146
- package/src/ios/SSZipArchive.m +1180 -1180
- package/src/ios/SSZipCommon.h +66 -66
- package/src/ios/UICKeyChainStore.h +64 -64
- package/src/ios/UICKeyChainStore.m +434 -434
- package/src/ios/XMLConverter.h +61 -61
- package/src/ios/XMLConverter.m +243 -243
- package/src/ios/ZipArchive.h +19 -19
- package/src/ios/aes/aes.h +270 -270
- package/src/ios/aes/aes_ni.c +687 -687
- package/src/ios/aes/aes_ni.h +59 -59
- package/src/ios/aes/aescrypt.c +301 -301
- package/src/ios/aes/aeskey.c +554 -554
- package/src/ios/aes/aesopt.h +776 -776
- package/src/ios/aes/aestab.c +418 -418
- package/src/ios/aes/aestab.h +173 -173
- package/src/ios/aes/brg_endian.h +127 -127
- package/src/ios/aes/brg_types.h +191 -191
- package/src/ios/aes/fileenc.c +145 -145
- package/src/ios/aes/fileenc.h +121 -121
- package/src/ios/aes/hmac.c +209 -209
- package/src/ios/aes/hmac.h +119 -119
- package/src/ios/aes/prng.c +155 -155
- package/src/ios/aes/prng.h +82 -82
- package/src/ios/aes/pwd2key.c +181 -181
- package/src/ios/aes/pwd2key.h +45 -45
- package/src/ios/aes/sha1.c +283 -283
- package/src/ios/aes/sha1.h +72 -72
- package/src/ios/mInterface.h +2 -0
- package/src/ios/mInterface.m +18 -1
- package/src/ios/minizip/crypt.c +146 -146
- package/src/ios/minizip/crypt.h +66 -66
- package/src/ios/minizip/ioapi.c +353 -353
- package/src/ios/minizip/ioapi.h +154 -154
- package/src/ios/minizip/ioapi_buf.c +452 -452
- package/src/ios/minizip/ioapi_buf.h +52 -52
- package/src/ios/minizip/ioapi_mem.c +167 -167
- package/src/ios/minizip/ioapi_mem.h +52 -52
- package/src/ios/minizip/minishared.c +292 -292
- package/src/ios/minizip/minishared.h +50 -50
- package/src/ios/minizip/unzip.c +2007 -2007
- package/src/ios/minizip/unzip.h +254 -254
- package/src/ios/minizip/zip.c +2007 -2007
- package/src/ios/minizip/zip.h +215 -215
- package/www/mInterface.js +3 -3
|
@@ -1,434 +1,434 @@
|
|
|
1
|
-
//
|
|
2
|
-
// UICKeyChainStore.m
|
|
3
|
-
// UICKeyChainStore
|
|
4
|
-
//
|
|
5
|
-
// Created by Kishikawa Katsumi on 11/11/20.
|
|
6
|
-
// Copyright (c) 2011 Kishikawa Katsumi. All rights reserved.
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
#import "UICKeyChainStore.h"
|
|
10
|
-
|
|
11
|
-
static NSString *_defaultService;
|
|
12
|
-
|
|
13
|
-
@interface UICKeyChainStore () {
|
|
14
|
-
NSMutableDictionary *itemsToUpdate;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@end
|
|
18
|
-
|
|
19
|
-
@implementation UICKeyChainStore
|
|
20
|
-
|
|
21
|
-
+ (NSString *)defaultService
|
|
22
|
-
{
|
|
23
|
-
if (!_defaultService) {
|
|
24
|
-
_defaultService = [[NSBundle mainBundle] bundleIdentifier];
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return _defaultService;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
+ (void)setDefaultService:(NSString *)defaultService
|
|
31
|
-
{
|
|
32
|
-
_defaultService = defaultService;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
#pragma mark -
|
|
36
|
-
|
|
37
|
-
+ (UICKeyChainStore *)keyChainStore
|
|
38
|
-
{
|
|
39
|
-
return [[self alloc] initWithService:[self defaultService]];
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
+ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service
|
|
43
|
-
{
|
|
44
|
-
return [[self alloc] initWithService:service];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
+ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
48
|
-
{
|
|
49
|
-
return [[self alloc] initWithService:service accessGroup:accessGroup];
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
- (instancetype)init
|
|
53
|
-
{
|
|
54
|
-
return [self initWithService:[self.class defaultService] accessGroup:nil];
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
- (instancetype)initWithService:(NSString *)service
|
|
58
|
-
{
|
|
59
|
-
return [self initWithService:service accessGroup:nil];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
- (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
63
|
-
{
|
|
64
|
-
self = [super init];
|
|
65
|
-
if (self) {
|
|
66
|
-
if (!service) {
|
|
67
|
-
service = [self.class defaultService];
|
|
68
|
-
}
|
|
69
|
-
_service = [service copy];
|
|
70
|
-
_accessGroup = [accessGroup copy];
|
|
71
|
-
|
|
72
|
-
itemsToUpdate = [[NSMutableDictionary alloc] init];
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return self;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
#pragma mark -
|
|
79
|
-
|
|
80
|
-
+ (NSString *)stringForKey:(NSString *)key
|
|
81
|
-
{
|
|
82
|
-
return [self stringForKey:key service:[self defaultService] accessGroup:nil];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
+ (NSString *)stringForKey:(NSString *)key service:(NSString *)service
|
|
86
|
-
{
|
|
87
|
-
return [self stringForKey:key service:service accessGroup:nil];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
+ (NSString *)stringForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
91
|
-
{
|
|
92
|
-
NSData *data = [self dataForKey:key service:service accessGroup:accessGroup];
|
|
93
|
-
if (data) {
|
|
94
|
-
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return nil;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
+ (BOOL)setString:(NSString *)value forKey:(NSString *)key
|
|
101
|
-
{
|
|
102
|
-
return [self setString:value forKey:key service:[self defaultService] accessGroup:nil];
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
+ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service
|
|
106
|
-
{
|
|
107
|
-
return [self setString:value forKey:key service:service accessGroup:nil];
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
+ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
111
|
-
{
|
|
112
|
-
NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
|
|
113
|
-
return [self setData:data forKey:key service:service accessGroup:accessGroup];
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
#pragma mark -
|
|
117
|
-
|
|
118
|
-
+ (NSData *)dataForKey:(NSString *)key
|
|
119
|
-
{
|
|
120
|
-
return [self dataForKey:key service:[self defaultService] accessGroup:nil];
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
+ (NSData *)dataForKey:(NSString *)key service:(NSString *)service
|
|
124
|
-
{
|
|
125
|
-
return [self dataForKey:key service:service accessGroup:nil];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
+ (NSData *)dataForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
129
|
-
{
|
|
130
|
-
if (!key) {
|
|
131
|
-
return nil;
|
|
132
|
-
}
|
|
133
|
-
if (!service) {
|
|
134
|
-
service = [self defaultService];
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
|
|
138
|
-
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
139
|
-
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
|
|
140
|
-
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
|
|
141
|
-
[query setObject:service forKey:(__bridge id)kSecAttrService];
|
|
142
|
-
[query setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
143
|
-
[query setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
144
|
-
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
145
|
-
if (accessGroup) {
|
|
146
|
-
[query setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
147
|
-
}
|
|
148
|
-
#endif
|
|
149
|
-
|
|
150
|
-
CFTypeRef data = nil;
|
|
151
|
-
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &data);
|
|
152
|
-
if (status != errSecSuccess) {
|
|
153
|
-
return nil;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
NSData *ret = [NSData dataWithData:(__bridge NSData *)data];
|
|
157
|
-
if (data) {
|
|
158
|
-
CFRelease(data);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
return ret;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
+ (BOOL)setData:(NSData *)data forKey:(NSString *)key
|
|
165
|
-
{
|
|
166
|
-
return [self setData:data forKey:key service:[self defaultService] accessGroup:nil];
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
+ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service
|
|
170
|
-
{
|
|
171
|
-
return [self setData:data forKey:key service:service accessGroup:nil];
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
+ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
175
|
-
{
|
|
176
|
-
if (!key) {
|
|
177
|
-
return NO;
|
|
178
|
-
}
|
|
179
|
-
if (!service) {
|
|
180
|
-
service = [self defaultService];
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
|
|
184
|
-
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
185
|
-
[query setObject:service forKey:(__bridge id)kSecAttrService];
|
|
186
|
-
[query setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
187
|
-
[query setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
188
|
-
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
189
|
-
if (accessGroup) {
|
|
190
|
-
[query setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
191
|
-
}
|
|
192
|
-
#endif
|
|
193
|
-
|
|
194
|
-
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL);
|
|
195
|
-
if (status == errSecSuccess) {
|
|
196
|
-
if (data) {
|
|
197
|
-
NSMutableDictionary *attributesToUpdate = [[NSMutableDictionary alloc] init];
|
|
198
|
-
[attributesToUpdate setObject:data forKey:(__bridge id)kSecValueData];
|
|
199
|
-
|
|
200
|
-
status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributesToUpdate);
|
|
201
|
-
if (status != errSecSuccess) {
|
|
202
|
-
return NO;
|
|
203
|
-
}
|
|
204
|
-
} else {
|
|
205
|
-
[self removeItemForKey:key service:service accessGroup:accessGroup];
|
|
206
|
-
}
|
|
207
|
-
} else if (status == errSecItemNotFound) {
|
|
208
|
-
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
|
|
209
|
-
[attributes setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
210
|
-
[attributes setObject:service forKey:(__bridge id)kSecAttrService];
|
|
211
|
-
[attributes setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
212
|
-
[attributes setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
213
|
-
#if TARGET_OS_IPHONE || (defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)
|
|
214
|
-
[attributes setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(__bridge id)kSecAttrAccessible];
|
|
215
|
-
#endif
|
|
216
|
-
[attributes setObject:data forKey:(__bridge id)kSecValueData];
|
|
217
|
-
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
218
|
-
if (accessGroup) {
|
|
219
|
-
[attributes setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
220
|
-
}
|
|
221
|
-
#endif
|
|
222
|
-
|
|
223
|
-
status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
|
|
224
|
-
if (status != errSecSuccess) {
|
|
225
|
-
return NO;
|
|
226
|
-
}
|
|
227
|
-
} else {
|
|
228
|
-
return NO;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
return YES;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
#pragma mark -
|
|
235
|
-
|
|
236
|
-
- (void)setString:(NSString *)string forKey:(NSString *)key
|
|
237
|
-
{
|
|
238
|
-
[self setData:[string dataUsingEncoding:NSUTF8StringEncoding] forKey:key];
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
- (NSString *)stringForKey:(id)key
|
|
242
|
-
{
|
|
243
|
-
NSData *data = [self dataForKey:key];
|
|
244
|
-
if (data) {
|
|
245
|
-
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return nil;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
#pragma mark -
|
|
252
|
-
|
|
253
|
-
- (void)setData:(NSData *)data forKey:(NSString *)key
|
|
254
|
-
{
|
|
255
|
-
if (!key) {
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
if (!data) {
|
|
259
|
-
[self removeItemForKey:key];
|
|
260
|
-
} else {
|
|
261
|
-
[itemsToUpdate setObject:data forKey:key];
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
- (NSData *)dataForKey:(NSString *)key
|
|
266
|
-
{
|
|
267
|
-
NSData *data = [itemsToUpdate objectForKey:key];
|
|
268
|
-
if (!data) {
|
|
269
|
-
data = [[self class] dataForKey:key service:self.service accessGroup:self.accessGroup];
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return data;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
#pragma mark -
|
|
276
|
-
|
|
277
|
-
+ (BOOL)removeItemForKey:(NSString *)key
|
|
278
|
-
{
|
|
279
|
-
return [UICKeyChainStore removeItemForKey:key service:[self defaultService] accessGroup:nil];
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
+ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service
|
|
283
|
-
{
|
|
284
|
-
return [UICKeyChainStore removeItemForKey:key service:service accessGroup:nil];
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
+ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
288
|
-
{
|
|
289
|
-
if (!key) {
|
|
290
|
-
return NO;
|
|
291
|
-
}
|
|
292
|
-
if (!service) {
|
|
293
|
-
service = [self defaultService];
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
NSMutableDictionary *itemToDelete = [[NSMutableDictionary alloc] init];
|
|
297
|
-
[itemToDelete setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
298
|
-
[itemToDelete setObject:service forKey:(__bridge id)kSecAttrService];
|
|
299
|
-
[itemToDelete setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
300
|
-
[itemToDelete setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
301
|
-
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
302
|
-
if (accessGroup) {
|
|
303
|
-
[itemToDelete setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
304
|
-
}
|
|
305
|
-
#endif
|
|
306
|
-
|
|
307
|
-
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)itemToDelete);
|
|
308
|
-
if (status != errSecSuccess && status != errSecItemNotFound) {
|
|
309
|
-
return NO;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return YES;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
+ (NSArray *)itemsForService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
316
|
-
{
|
|
317
|
-
if (!service) {
|
|
318
|
-
service = [self defaultService];
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
|
|
322
|
-
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
323
|
-
[query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
|
|
324
|
-
[query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
|
|
325
|
-
[query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit];
|
|
326
|
-
[query setObject:service forKey:(__bridge id)kSecAttrService];
|
|
327
|
-
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
328
|
-
if (accessGroup) {
|
|
329
|
-
[query setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
330
|
-
}
|
|
331
|
-
#endif
|
|
332
|
-
|
|
333
|
-
CFArrayRef result = nil;
|
|
334
|
-
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
|
|
335
|
-
if (status == errSecSuccess || status == errSecItemNotFound) {
|
|
336
|
-
return CFBridgingRelease(result);
|
|
337
|
-
} else {
|
|
338
|
-
return nil;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
+ (BOOL)removeAllItems
|
|
343
|
-
{
|
|
344
|
-
return [self removeAllItemsForService:[self defaultService] accessGroup:nil];
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
+ (BOOL)removeAllItemsForService:(NSString *)service
|
|
348
|
-
{
|
|
349
|
-
return [self removeAllItemsForService:service accessGroup:nil];
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
+ (BOOL)removeAllItemsForService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
353
|
-
{
|
|
354
|
-
NSArray *items = [UICKeyChainStore itemsForService:service accessGroup:accessGroup];
|
|
355
|
-
for (NSDictionary *item in items) {
|
|
356
|
-
NSMutableDictionary *itemToDelete = [[NSMutableDictionary alloc] initWithDictionary:item];
|
|
357
|
-
[itemToDelete setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
358
|
-
|
|
359
|
-
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)itemToDelete);
|
|
360
|
-
if (status != errSecSuccess) {
|
|
361
|
-
return NO;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
return YES;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
#pragma mark -
|
|
369
|
-
|
|
370
|
-
- (void)removeItemForKey:(NSString *)key
|
|
371
|
-
{
|
|
372
|
-
if ([itemsToUpdate objectForKey:key]) {
|
|
373
|
-
[itemsToUpdate removeObjectForKey:key];
|
|
374
|
-
} else {
|
|
375
|
-
[[self class] removeItemForKey:key service:self.service accessGroup:self.accessGroup];
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
- (void)removeAllItems
|
|
380
|
-
{
|
|
381
|
-
[itemsToUpdate removeAllObjects];
|
|
382
|
-
[[self class] removeAllItemsForService:self.service accessGroup:self.accessGroup];
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
#pragma mark -
|
|
386
|
-
|
|
387
|
-
- (void)synchronize
|
|
388
|
-
{
|
|
389
|
-
for (NSString *key in itemsToUpdate) {
|
|
390
|
-
[[self class] setData:[itemsToUpdate objectForKey:key] forKey:key service:self.service accessGroup:self.accessGroup];
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
[itemsToUpdate removeAllObjects];
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
#pragma mark -
|
|
397
|
-
|
|
398
|
-
- (NSString *)description
|
|
399
|
-
{
|
|
400
|
-
NSArray *items = [UICKeyChainStore itemsForService:self.service accessGroup:self.accessGroup];
|
|
401
|
-
NSMutableArray *list = [[NSMutableArray alloc] initWithCapacity:items.count];
|
|
402
|
-
for (NSDictionary *attributes in items) {
|
|
403
|
-
NSMutableDictionary *attrs = [[NSMutableDictionary alloc] init];
|
|
404
|
-
[attrs setObject:[attributes objectForKey:(__bridge id)kSecAttrService] forKey:@"Service"];
|
|
405
|
-
[attrs setObject:[attributes objectForKey:(__bridge id)kSecAttrAccount] forKey:@"Account"];
|
|
406
|
-
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
407
|
-
[attrs setObject:[attributes objectForKey:(__bridge id)kSecAttrAccessGroup] forKey:@"AccessGroup"];
|
|
408
|
-
#endif
|
|
409
|
-
NSData *data = [attributes objectForKey:(__bridge id)kSecValueData];
|
|
410
|
-
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
411
|
-
if (string) {
|
|
412
|
-
[attrs setObject:string forKey:@"Value"];
|
|
413
|
-
} else {
|
|
414
|
-
[attrs setObject:data forKey:@"Value"];
|
|
415
|
-
}
|
|
416
|
-
[list addObject:attrs];
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return [list description];
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
#pragma mark - Object Subscripting
|
|
423
|
-
|
|
424
|
-
- (NSString *)objectForKeyedSubscript:(NSString <NSCopying> *)key
|
|
425
|
-
{
|
|
426
|
-
return [self stringForKey:key];
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
- (void)setObject:(NSString *)obj forKeyedSubscript:(NSString <NSCopying> *)key
|
|
430
|
-
{
|
|
431
|
-
[self setString:obj forKey:key];
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
@end
|
|
1
|
+
//
|
|
2
|
+
// UICKeyChainStore.m
|
|
3
|
+
// UICKeyChainStore
|
|
4
|
+
//
|
|
5
|
+
// Created by Kishikawa Katsumi on 11/11/20.
|
|
6
|
+
// Copyright (c) 2011 Kishikawa Katsumi. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "UICKeyChainStore.h"
|
|
10
|
+
|
|
11
|
+
static NSString *_defaultService;
|
|
12
|
+
|
|
13
|
+
@interface UICKeyChainStore () {
|
|
14
|
+
NSMutableDictionary *itemsToUpdate;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@implementation UICKeyChainStore
|
|
20
|
+
|
|
21
|
+
+ (NSString *)defaultService
|
|
22
|
+
{
|
|
23
|
+
if (!_defaultService) {
|
|
24
|
+
_defaultService = [[NSBundle mainBundle] bundleIdentifier];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return _defaultService;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
+ (void)setDefaultService:(NSString *)defaultService
|
|
31
|
+
{
|
|
32
|
+
_defaultService = defaultService;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#pragma mark -
|
|
36
|
+
|
|
37
|
+
+ (UICKeyChainStore *)keyChainStore
|
|
38
|
+
{
|
|
39
|
+
return [[self alloc] initWithService:[self defaultService]];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
+ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service
|
|
43
|
+
{
|
|
44
|
+
return [[self alloc] initWithService:service];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
+ (UICKeyChainStore *)keyChainStoreWithService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
48
|
+
{
|
|
49
|
+
return [[self alloc] initWithService:service accessGroup:accessGroup];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
- (instancetype)init
|
|
53
|
+
{
|
|
54
|
+
return [self initWithService:[self.class defaultService] accessGroup:nil];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
- (instancetype)initWithService:(NSString *)service
|
|
58
|
+
{
|
|
59
|
+
return [self initWithService:service accessGroup:nil];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
- (instancetype)initWithService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
63
|
+
{
|
|
64
|
+
self = [super init];
|
|
65
|
+
if (self) {
|
|
66
|
+
if (!service) {
|
|
67
|
+
service = [self.class defaultService];
|
|
68
|
+
}
|
|
69
|
+
_service = [service copy];
|
|
70
|
+
_accessGroup = [accessGroup copy];
|
|
71
|
+
|
|
72
|
+
itemsToUpdate = [[NSMutableDictionary alloc] init];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return self;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#pragma mark -
|
|
79
|
+
|
|
80
|
+
+ (NSString *)stringForKey:(NSString *)key
|
|
81
|
+
{
|
|
82
|
+
return [self stringForKey:key service:[self defaultService] accessGroup:nil];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
+ (NSString *)stringForKey:(NSString *)key service:(NSString *)service
|
|
86
|
+
{
|
|
87
|
+
return [self stringForKey:key service:service accessGroup:nil];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
+ (NSString *)stringForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
91
|
+
{
|
|
92
|
+
NSData *data = [self dataForKey:key service:service accessGroup:accessGroup];
|
|
93
|
+
if (data) {
|
|
94
|
+
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return nil;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
+ (BOOL)setString:(NSString *)value forKey:(NSString *)key
|
|
101
|
+
{
|
|
102
|
+
return [self setString:value forKey:key service:[self defaultService] accessGroup:nil];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
+ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service
|
|
106
|
+
{
|
|
107
|
+
return [self setString:value forKey:key service:service accessGroup:nil];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
+ (BOOL)setString:(NSString *)value forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
111
|
+
{
|
|
112
|
+
NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding];
|
|
113
|
+
return [self setData:data forKey:key service:service accessGroup:accessGroup];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#pragma mark -
|
|
117
|
+
|
|
118
|
+
+ (NSData *)dataForKey:(NSString *)key
|
|
119
|
+
{
|
|
120
|
+
return [self dataForKey:key service:[self defaultService] accessGroup:nil];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
+ (NSData *)dataForKey:(NSString *)key service:(NSString *)service
|
|
124
|
+
{
|
|
125
|
+
return [self dataForKey:key service:service accessGroup:nil];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
+ (NSData *)dataForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
129
|
+
{
|
|
130
|
+
if (!key) {
|
|
131
|
+
return nil;
|
|
132
|
+
}
|
|
133
|
+
if (!service) {
|
|
134
|
+
service = [self defaultService];
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
|
|
138
|
+
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
139
|
+
[query setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
|
|
140
|
+
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
|
|
141
|
+
[query setObject:service forKey:(__bridge id)kSecAttrService];
|
|
142
|
+
[query setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
143
|
+
[query setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
144
|
+
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
145
|
+
if (accessGroup) {
|
|
146
|
+
[query setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
147
|
+
}
|
|
148
|
+
#endif
|
|
149
|
+
|
|
150
|
+
CFTypeRef data = nil;
|
|
151
|
+
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &data);
|
|
152
|
+
if (status != errSecSuccess) {
|
|
153
|
+
return nil;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
NSData *ret = [NSData dataWithData:(__bridge NSData *)data];
|
|
157
|
+
if (data) {
|
|
158
|
+
CFRelease(data);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return ret;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
+ (BOOL)setData:(NSData *)data forKey:(NSString *)key
|
|
165
|
+
{
|
|
166
|
+
return [self setData:data forKey:key service:[self defaultService] accessGroup:nil];
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
+ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service
|
|
170
|
+
{
|
|
171
|
+
return [self setData:data forKey:key service:service accessGroup:nil];
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
+ (BOOL)setData:(NSData *)data forKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
175
|
+
{
|
|
176
|
+
if (!key) {
|
|
177
|
+
return NO;
|
|
178
|
+
}
|
|
179
|
+
if (!service) {
|
|
180
|
+
service = [self defaultService];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
|
|
184
|
+
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
185
|
+
[query setObject:service forKey:(__bridge id)kSecAttrService];
|
|
186
|
+
[query setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
187
|
+
[query setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
188
|
+
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
189
|
+
if (accessGroup) {
|
|
190
|
+
[query setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
191
|
+
}
|
|
192
|
+
#endif
|
|
193
|
+
|
|
194
|
+
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL);
|
|
195
|
+
if (status == errSecSuccess) {
|
|
196
|
+
if (data) {
|
|
197
|
+
NSMutableDictionary *attributesToUpdate = [[NSMutableDictionary alloc] init];
|
|
198
|
+
[attributesToUpdate setObject:data forKey:(__bridge id)kSecValueData];
|
|
199
|
+
|
|
200
|
+
status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributesToUpdate);
|
|
201
|
+
if (status != errSecSuccess) {
|
|
202
|
+
return NO;
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
[self removeItemForKey:key service:service accessGroup:accessGroup];
|
|
206
|
+
}
|
|
207
|
+
} else if (status == errSecItemNotFound) {
|
|
208
|
+
NSMutableDictionary *attributes = [[NSMutableDictionary alloc] init];
|
|
209
|
+
[attributes setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
210
|
+
[attributes setObject:service forKey:(__bridge id)kSecAttrService];
|
|
211
|
+
[attributes setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
212
|
+
[attributes setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
213
|
+
#if TARGET_OS_IPHONE || (defined(MAC_OS_X_VERSION_10_9) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9)
|
|
214
|
+
[attributes setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(__bridge id)kSecAttrAccessible];
|
|
215
|
+
#endif
|
|
216
|
+
[attributes setObject:data forKey:(__bridge id)kSecValueData];
|
|
217
|
+
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
218
|
+
if (accessGroup) {
|
|
219
|
+
[attributes setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
220
|
+
}
|
|
221
|
+
#endif
|
|
222
|
+
|
|
223
|
+
status = SecItemAdd((__bridge CFDictionaryRef)attributes, NULL);
|
|
224
|
+
if (status != errSecSuccess) {
|
|
225
|
+
return NO;
|
|
226
|
+
}
|
|
227
|
+
} else {
|
|
228
|
+
return NO;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return YES;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
#pragma mark -
|
|
235
|
+
|
|
236
|
+
- (void)setString:(NSString *)string forKey:(NSString *)key
|
|
237
|
+
{
|
|
238
|
+
[self setData:[string dataUsingEncoding:NSUTF8StringEncoding] forKey:key];
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
- (NSString *)stringForKey:(id)key
|
|
242
|
+
{
|
|
243
|
+
NSData *data = [self dataForKey:key];
|
|
244
|
+
if (data) {
|
|
245
|
+
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return nil;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
#pragma mark -
|
|
252
|
+
|
|
253
|
+
- (void)setData:(NSData *)data forKey:(NSString *)key
|
|
254
|
+
{
|
|
255
|
+
if (!key) {
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
if (!data) {
|
|
259
|
+
[self removeItemForKey:key];
|
|
260
|
+
} else {
|
|
261
|
+
[itemsToUpdate setObject:data forKey:key];
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
- (NSData *)dataForKey:(NSString *)key
|
|
266
|
+
{
|
|
267
|
+
NSData *data = [itemsToUpdate objectForKey:key];
|
|
268
|
+
if (!data) {
|
|
269
|
+
data = [[self class] dataForKey:key service:self.service accessGroup:self.accessGroup];
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return data;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
#pragma mark -
|
|
276
|
+
|
|
277
|
+
+ (BOOL)removeItemForKey:(NSString *)key
|
|
278
|
+
{
|
|
279
|
+
return [UICKeyChainStore removeItemForKey:key service:[self defaultService] accessGroup:nil];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
+ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service
|
|
283
|
+
{
|
|
284
|
+
return [UICKeyChainStore removeItemForKey:key service:service accessGroup:nil];
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
+ (BOOL)removeItemForKey:(NSString *)key service:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
288
|
+
{
|
|
289
|
+
if (!key) {
|
|
290
|
+
return NO;
|
|
291
|
+
}
|
|
292
|
+
if (!service) {
|
|
293
|
+
service = [self defaultService];
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
NSMutableDictionary *itemToDelete = [[NSMutableDictionary alloc] init];
|
|
297
|
+
[itemToDelete setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
298
|
+
[itemToDelete setObject:service forKey:(__bridge id)kSecAttrService];
|
|
299
|
+
[itemToDelete setObject:key forKey:(__bridge id)kSecAttrGeneric];
|
|
300
|
+
[itemToDelete setObject:key forKey:(__bridge id)kSecAttrAccount];
|
|
301
|
+
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
302
|
+
if (accessGroup) {
|
|
303
|
+
[itemToDelete setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
304
|
+
}
|
|
305
|
+
#endif
|
|
306
|
+
|
|
307
|
+
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)itemToDelete);
|
|
308
|
+
if (status != errSecSuccess && status != errSecItemNotFound) {
|
|
309
|
+
return NO;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return YES;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
+ (NSArray *)itemsForService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
316
|
+
{
|
|
317
|
+
if (!service) {
|
|
318
|
+
service = [self defaultService];
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
NSMutableDictionary *query = [[NSMutableDictionary alloc] init];
|
|
322
|
+
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
323
|
+
[query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
|
|
324
|
+
[query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
|
|
325
|
+
[query setObject:(__bridge id)kSecMatchLimitAll forKey:(__bridge id)kSecMatchLimit];
|
|
326
|
+
[query setObject:service forKey:(__bridge id)kSecAttrService];
|
|
327
|
+
#if !TARGET_IPHONE_SIMULATOR && defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
328
|
+
if (accessGroup) {
|
|
329
|
+
[query setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup];
|
|
330
|
+
}
|
|
331
|
+
#endif
|
|
332
|
+
|
|
333
|
+
CFArrayRef result = nil;
|
|
334
|
+
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
|
|
335
|
+
if (status == errSecSuccess || status == errSecItemNotFound) {
|
|
336
|
+
return CFBridgingRelease(result);
|
|
337
|
+
} else {
|
|
338
|
+
return nil;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
+ (BOOL)removeAllItems
|
|
343
|
+
{
|
|
344
|
+
return [self removeAllItemsForService:[self defaultService] accessGroup:nil];
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
+ (BOOL)removeAllItemsForService:(NSString *)service
|
|
348
|
+
{
|
|
349
|
+
return [self removeAllItemsForService:service accessGroup:nil];
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
+ (BOOL)removeAllItemsForService:(NSString *)service accessGroup:(NSString *)accessGroup
|
|
353
|
+
{
|
|
354
|
+
NSArray *items = [UICKeyChainStore itemsForService:service accessGroup:accessGroup];
|
|
355
|
+
for (NSDictionary *item in items) {
|
|
356
|
+
NSMutableDictionary *itemToDelete = [[NSMutableDictionary alloc] initWithDictionary:item];
|
|
357
|
+
[itemToDelete setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
|
|
358
|
+
|
|
359
|
+
OSStatus status = SecItemDelete((__bridge CFDictionaryRef)itemToDelete);
|
|
360
|
+
if (status != errSecSuccess) {
|
|
361
|
+
return NO;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return YES;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
#pragma mark -
|
|
369
|
+
|
|
370
|
+
- (void)removeItemForKey:(NSString *)key
|
|
371
|
+
{
|
|
372
|
+
if ([itemsToUpdate objectForKey:key]) {
|
|
373
|
+
[itemsToUpdate removeObjectForKey:key];
|
|
374
|
+
} else {
|
|
375
|
+
[[self class] removeItemForKey:key service:self.service accessGroup:self.accessGroup];
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
- (void)removeAllItems
|
|
380
|
+
{
|
|
381
|
+
[itemsToUpdate removeAllObjects];
|
|
382
|
+
[[self class] removeAllItemsForService:self.service accessGroup:self.accessGroup];
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
#pragma mark -
|
|
386
|
+
|
|
387
|
+
- (void)synchronize
|
|
388
|
+
{
|
|
389
|
+
for (NSString *key in itemsToUpdate) {
|
|
390
|
+
[[self class] setData:[itemsToUpdate objectForKey:key] forKey:key service:self.service accessGroup:self.accessGroup];
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
[itemsToUpdate removeAllObjects];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
#pragma mark -
|
|
397
|
+
|
|
398
|
+
- (NSString *)description
|
|
399
|
+
{
|
|
400
|
+
NSArray *items = [UICKeyChainStore itemsForService:self.service accessGroup:self.accessGroup];
|
|
401
|
+
NSMutableArray *list = [[NSMutableArray alloc] initWithCapacity:items.count];
|
|
402
|
+
for (NSDictionary *attributes in items) {
|
|
403
|
+
NSMutableDictionary *attrs = [[NSMutableDictionary alloc] init];
|
|
404
|
+
[attrs setObject:[attributes objectForKey:(__bridge id)kSecAttrService] forKey:@"Service"];
|
|
405
|
+
[attrs setObject:[attributes objectForKey:(__bridge id)kSecAttrAccount] forKey:@"Account"];
|
|
406
|
+
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED)
|
|
407
|
+
[attrs setObject:[attributes objectForKey:(__bridge id)kSecAttrAccessGroup] forKey:@"AccessGroup"];
|
|
408
|
+
#endif
|
|
409
|
+
NSData *data = [attributes objectForKey:(__bridge id)kSecValueData];
|
|
410
|
+
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
|
411
|
+
if (string) {
|
|
412
|
+
[attrs setObject:string forKey:@"Value"];
|
|
413
|
+
} else {
|
|
414
|
+
[attrs setObject:data forKey:@"Value"];
|
|
415
|
+
}
|
|
416
|
+
[list addObject:attrs];
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return [list description];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
#pragma mark - Object Subscripting
|
|
423
|
+
|
|
424
|
+
- (NSString *)objectForKeyedSubscript:(NSString <NSCopying> *)key
|
|
425
|
+
{
|
|
426
|
+
return [self stringForKey:key];
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
- (void)setObject:(NSString *)obj forKeyedSubscript:(NSString <NSCopying> *)key
|
|
430
|
+
{
|
|
431
|
+
[self setString:obj forKey:key];
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
@end
|