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 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
235 changes: 233 additions & 2 deletions SDCloudUserDefaults.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "23BB07911BCA5EA2004DD41D"
BuildableName = "SDCloudUserDefaults OSX.framework"
BuildableName = "SDCloudUserDefaults.framework"
BlueprintName = "SDCloudUserDefaults OSX"
ReferencedContainer = "container:SDCloudUserDefaults.xcodeproj">
</BuildableReference>
Expand All @@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand All @@ -46,13 +44,11 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "23BB07911BCA5EA2004DD41D"
BuildableName = "SDCloudUserDefaults OSX.framework"
BuildableName = "SDCloudUserDefaults.framework"
BlueprintName = "SDCloudUserDefaults OSX"
ReferencedContainer = "container:SDCloudUserDefaults.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand All @@ -64,7 +60,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "23BB07911BCA5EA2004DD41D"
BuildableName = "SDCloudUserDefaults OSX.framework"
BuildableName = "SDCloudUserDefaults.framework"
BlueprintName = "SDCloudUserDefaults OSX"
ReferencedContainer = "container:SDCloudUserDefaults.xcodeproj">
</BuildableReference>
Expand Down
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
139 changes: 100 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,47 @@ +(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) {
id obj = [cloud objectForKey:key];

[defaults setObject:obj forKey:key];

if (obj != nil) {
[[NSNotificationCenter defaultCenter] postNotificationName:SDCloudValueUpdatedNotification
object:self
userInfo:@{key:[cloud objectForKey:key]}];
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:SDCloudValueUpdatedNotification
object:self
userInfo:nil];
}
}


}
}];
}

}
Expand Down
42 changes: 42 additions & 0 deletions SDCloudUserDefaults_Swift/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// AppDelegate.swift
// SDCloudUserDefaults_Swift
//
// Created by Peter Easdown on 10/10/20.
// Copyright © 2020 Wandle Software Limited. All rights reserved.
//

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {



func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.

SDCloudUserDefaults.shared.registerForNotifications()

application.registerForRemoteNotifications()

return true
}

// MARK: UISceneSession Lifecycle

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}


}

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading