Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 34 additions & 26 deletions NSUserDefaults+iCloud.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
NSString* const FTiCloudSyncChangedKeys = @"changedKeys";
NSString* const FTiCloudSyncRemovedKeys = @"removedKeys";
NSString* const iCloudBlacklistRegex = @"(^!|^Apple|^ATOutputLevel|Hockey|DateOfVersionInstallation|^MF|^NS|Quincy|^BIT|^TV|UsageTime|^Web|preferredLocaleIdentifier)";
NSString* const FTiCloudSyncControlKey = @"!FTiCloudSyncEnabled";

@implementation NSUserDefaults(Additions)

Expand All @@ -40,28 +41,31 @@ + (void)updateFromiCloud:(NSNotification*)notificationObject {
if ([[[notificationObject userInfo] objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] intValue] == NSUbiquitousKeyValueStoreQuotaViolationChange) {
NSLog(@"NSUbiquitousKeyValueStoreQuotaViolationChange");
}

NSMutableArray *changedKeys = [NSMutableArray array];
NSMutableArray *removedKeys = nil;
@synchronized(self) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *dict = [[NSUbiquitousKeyValueStore defaultStore] dictionaryRepresentation];

[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if (![key isMatchedByRegex:iCloudBlacklistRegex] && ![[defaults valueForKey:key] isEqual:obj]) {
[defaults my_setObject:obj forKey:key]; // call original implementation
[changedKeys addObject:key];
}
}];

removedKeys = [NSMutableArray arrayWithArray:[defaults dictionaryRepresentation].allKeys];
[removedKeys removeObjectsInArray:dict.allKeys];
[removedKeys enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) {
if (![key isMatchedByRegex:iCloudBlacklistRegex]) {
[defaults my_removeObjectForKey:key]; // non-swizzled/original implementation
}
}];

[defaults my_synchronize]; // call original implementation (don't sync with iCloud again)

if ([defaults shouldSynchronise]) {
[dict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
if (![key isMatchedByRegex:iCloudBlacklistRegex] && ![[defaults valueForKey:key] isEqual:obj]) {
[defaults my_setObject:obj forKey:key]; // call original implementation
[changedKeys addObject:key];
}
}];

removedKeys = [NSMutableArray arrayWithArray:[defaults dictionaryRepresentation].allKeys];
[removedKeys removeObjectsInArray:dict.allKeys];
[removedKeys enumerateObjectsUsingBlock:^(id key, NSUInteger idx, BOOL *stop) {
if (![key isMatchedByRegex:iCloudBlacklistRegex]) {
[defaults my_removeObjectForKey:key]; // non-swizzled/original implementation
}
}];

[defaults my_synchronize]; // call original implementation (don't sync with iCloud again)
}
}
[[NSNotificationCenter defaultCenter] postNotificationName:FTiCloudSyncDidUpdateNotification
object:self
Expand All @@ -71,7 +75,7 @@ + (void)updateFromiCloud:(NSNotification*)notificationObject {
- (void)my_setObject:(id)object forKey:(NSString *)key {
BOOL equal = [[self objectForKey:key] isEqual:object];
[self my_setObject:object forKey:key];
if (!equal && ![key isMatchedByRegex:iCloudBlacklistRegex] && [NSUbiquitousKeyValueStore defaultStore]) {
if (!equal && [self shouldSynchronise] && ![key isMatchedByRegex:iCloudBlacklistRegex] && [NSUbiquitousKeyValueStore defaultStore]) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[[NSUbiquitousKeyValueStore defaultStore] setObject:object forKey:key];
});
Expand All @@ -82,7 +86,7 @@ - (void)my_removeObjectForKey:(NSString *)key {
BOOL exists = !![self objectForKey:key];
[self my_removeObjectForKey:key]; // call original implementation

if (exists && ![key isMatchedByRegex:iCloudBlacklistRegex] && [NSUbiquitousKeyValueStore defaultStore]) {
if (exists && [self shouldSynchronise] && ![key isMatchedByRegex:iCloudBlacklistRegex] && [NSUbiquitousKeyValueStore defaultStore]) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
[[NSUbiquitousKeyValueStore defaultStore] removeObjectForKey:key];
});
Expand All @@ -91,13 +95,17 @@ - (void)my_removeObjectForKey:(NSString *)key {

- (void)my_synchronize {
[self my_synchronize]; // call original implementation
if ([NSUbiquitousKeyValueStore defaultStore]) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
if(![[NSUbiquitousKeyValueStore defaultStore] synchronize]) {
NSLog(@"iCloud sync failed");
}
});
}

if ([self shouldSynchronise] && [NSUbiquitousKeyValueStore defaultStore]) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
if(![[NSUbiquitousKeyValueStore defaultStore] synchronize]) {
NSLog(@"iCloud sync failed");
}
});
}
}

- (bool) shouldSynchronise {
return [[self objectForKey:FTiCloudSyncControlKey] boolValue];
}
@end
3 changes: 3 additions & 0 deletions RegexKitLite.m
Original file line number Diff line number Diff line change
Expand Up @@ -1196,7 +1196,10 @@ static void rkl_handleDelayedAssert(id self, SEL _cmd, id exception) {
else {
id functionString = [exception objectForKey:@"function"], fileString = [exception objectForKey:@"file"], descriptionString = [exception objectForKey:@"description"], lineNumber = [exception objectForKey:@"line"];
RKLCHardAbortAssert((functionString != NULL) && (fileString != NULL) && (descriptionString != NULL) && (lineNumber != NULL));
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
[[NSAssertionHandler currentHandler] handleFailureInFunction:functionString file:fileString lineNumber:(NSInteger)[lineNumber longValue] description:descriptionString];
#pragma clang diagnostic pop
}
}
}
Expand Down