Skip to content
This repository has been archived by the owner on Mar 14, 2023. It is now read-only.

Added functionality to simplify the initialisation of the wrapper. #11

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 14 additions & 0 deletions SDCloudUserDefaults/SDCloudUserDefaults.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@
*/
+(void)removeNotifications;

#define ICLOUD_DATA_ENABLED_KEY @"iCloudDataEnabled"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer constants to be defined using the extern NSString* const syntax, so the actual value can be hidden in the .m file. (See here for an example.)


/**
* Enables or disables the storage of player information and other settings in iCloud. For Shared iPad usage
* this needs to be enabled so that the users data is preserved in iCloud when the iPad is swapped to another
* user.
*/
+ (void) setiCloudEnabled:(BOOL)iCloudEnabled;

/**
* Returns YES if iCloud is enabled.
*/
+ (BOOL) isiCloudEnabled;

/**
* Notification with the following name will be fired for every updated value that came from iCloud
*/
Expand Down
131 changes: 92 additions & 39 deletions SDCloudUserDefaults/SDCloudUserDefaults.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,37 @@ @implementation SDCloudUserDefaults
static NSString *suiteName;
static NSUserDefaults *userDefaults;

+ (void) setiCloudEnabled:(BOOL)iCloudEnabled {
[[NSUserDefaults standardUserDefaults] setBool:iCloudEnabled forKey:ICLOUD_DATA_ENABLED_KEY];
[[NSUserDefaults standardUserDefaults] synchronize];

if (iCloudEnabled == YES) {
[SDCloudUserDefaults registerForNotifications];
} else {
[SDCloudUserDefaults removeNotifications];
}
}

+ (BOOL) isiCloudEnabled {
return [[NSUserDefaults standardUserDefaults] boolForKey:ICLOUD_DATA_ENABLED_KEY];
}

+ (void) initialize {
[super initialize];
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way that this can be implemented that doesn't require changing the the API for existing users?


id keyValue = [SDCloudUserDefaults objectForKey:ICLOUD_DATA_ENABLED_KEY];

if (keyValue != nil) {
BOOL iCloudEnabled = [SDCloudUserDefaults boolForKey:ICLOUD_DATA_ENABLED_KEY];

if (iCloudEnabled == YES) {
[SDCloudUserDefaults registerForNotifications];
} else {
[SDCloudUserDefaults removeNotifications];
}
}
}

+(NSUserDefaults *) _standardUserDefaults {
if (userDefaults == nil) {
userDefaults = [NSUserDefaults standardUserDefaults];
Expand Down Expand Up @@ -62,13 +93,19 @@ +(BOOL)boolForKey:(NSString*)aKey {
}

+(id)objectForKey:(NSString*)aKey {
NSUbiquitousKeyValueStore* cloud = [NSUbiquitousKeyValueStore defaultStore];
id retv = [cloud objectForKey:aKey];
if (!retv) {
retv = [[self _standardUserDefaults] objectForKey:aKey];
[cloud setObject:retv forKey:aKey];
if ([SDCloudUserDefaults isiCloudEnabled] == YES) {
NSUbiquitousKeyValueStore* cloud = [NSUbiquitousKeyValueStore defaultStore];
id retv = [cloud objectForKey:aKey];

if (!retv) {
retv = [[self _standardUserDefaults] objectForKey:aKey];
[cloud setObject:retv forKey:aKey];
}

return retv;
} else {
return [[self _standardUserDefaults] objectForKey:aKey];
}
return retv;
}

+(NSInteger)integerForKey:(NSString*)aKey {
Expand All @@ -88,8 +125,13 @@ +(void)setBool:(BOOL)aBool forKey:(NSString*)aKey {
}

+(void)setObject:(id)anObject forKey:(NSString*)aKey {
[[NSUbiquitousKeyValueStore defaultStore] setObject:anObject forKey:aKey];
if ([SDCloudUserDefaults isiCloudEnabled] == YES) {
[[NSUbiquitousKeyValueStore defaultStore] setObject:anObject forKey:aKey];
}

[[self _standardUserDefaults] setObject:anObject forKey:aKey];

[SDCloudUserDefaults synchronize];
}

+(void)setInteger:(NSInteger)anInteger forKey:(NSString*)aKey {
Expand All @@ -103,12 +145,20 @@ +(void)setFloat:(float)aFloat forKey:(NSString *)aKey {
}

+(void)removeObjectForKey:(NSString*)aKey {
[[NSUbiquitousKeyValueStore defaultStore] removeObjectForKey:aKey];
if ([SDCloudUserDefaults isiCloudEnabled] == YES) {
[[NSUbiquitousKeyValueStore defaultStore] removeObjectForKey:aKey];
}

[[self _standardUserDefaults] removeObjectForKey:aKey];

[SDCloudUserDefaults synchronize];
}

+(void)synchronize {
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
if ([SDCloudUserDefaults isiCloudEnabled] == YES) {
[[NSUbiquitousKeyValueStore defaultStore] synchronize];
}

[[self _standardUserDefaults] synchronize];
}

Expand All @@ -118,36 +168,39 @@ +(void)registerForNotifications {
return;
}

notificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"NSUbiquitousKeyValueStoreDidChangeExternallyNotification"
object:[NSUbiquitousKeyValueStore defaultStore]
queue:nil
usingBlock:^(NSNotification* notification) {

NSDictionary* userInfo = [notification userInfo];
NSNumber* reasonForChange = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey];

// If a reason could not be determined, do not update anything.
if (!reasonForChange)
return;

// Update only for changes from the server.
NSInteger reason = [reasonForChange integerValue];
if ((reason == NSUbiquitousKeyValueStoreServerChange) ||
(reason == NSUbiquitousKeyValueStoreInitialSyncChange)) {
NSUserDefaults* defaults = [self _standardUserDefaults];
NSUbiquitousKeyValueStore* cloud = [NSUbiquitousKeyValueStore defaultStore];
NSArray* changedKeys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
for (NSString* key in changedKeys) {
[defaults setObject:[cloud objectForKey:key] forKey:key];

[[NSNotificationCenter defaultCenter] postNotificationName:SDCloudValueUpdatedNotification
object:self
userInfo:@{key:[cloud objectForKey:key]}];
}


}
}];
notificationObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
object:[NSUbiquitousKeyValueStore defaultStore]
queue:nil
usingBlock:^(NSNotification* notification) {

NSDictionary* userInfo = [notification userInfo];
NSNumber* reasonForChange = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey];

// If a reason could not be determined, do not update anything.
if (!reasonForChange)
return;

// Update only for changes from the server.
NSInteger reason = [reasonForChange integerValue];
if ((reason == NSUbiquitousKeyValueStoreServerChange) ||
(reason == NSUbiquitousKeyValueStoreInitialSyncChange)) {

NSUserDefaults* defaults = [self _standardUserDefaults];
NSUbiquitousKeyValueStore* cloud = [NSUbiquitousKeyValueStore defaultStore];
NSArray* changedKeys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];

for (NSString* key in changedKeys) {
[defaults setObject:[cloud objectForKey:key] forKey:key];

[[NSNotificationCenter defaultCenter] postNotificationName:SDCloudValueUpdatedNotification
object:self
userInfo:@{key:[cloud objectForKey:key]}];
}


}
}];
}

}
Expand Down