Reputation: 1439
I've defined NSUbiquitousKeyValueStore as 'CloudStore' in one ViewController (PointsViewController.m), and created a CloudStore singleton in order to be able to use it in another ViewController (PayViewController.m).
However, when I call the Singleton in PayViewController.m, it then throws an error on every NSString reference under it. The error reads: "No known class method forStringForKey" and "No known method for setString:forKey". Am I missing something here? Have I implemented the singleton incorrectly? See ViewController & Singleton code below.
PointsViewController.m
NSUbiquitousKeyValueStore *CloudStore = [NSUbiquitousKeyValueStore defaultStore];
NSString *pointsStr = [CloudStore stringForKey:@"UserWantsToBuyPoints"];
[CloudStore setString:pointsStr forKey:@"UserWantsToBuyPoints"];
[CloudStore synchronize];
NSString *TotalUserPoints = [CloudStore stringForKey:@"TotalUserPoints"];
int pointsInt = [pointsStr intValue];
int TotalUserPointsInt = [TotalUserPoints intValue];
TotalUserPointsInt = TotalUserPointsInt + pointsInt;
NSString *totalStr = [NSString stringWithFormat:@"%d", TotalUserPointsInt];
[CloudStore setObject:totalStr forKey:@"TotalUserPoints"];
[CloudStore synchronize];
PayViewController.m
[CloudStore singleton];
NSString *pointsStr = [CloudStore stringForKey:@"UserWantsToBuyPoints"];
[CloudStore setString:pointsStr forKey:@"UserWantsToBuyPoints"];
[cloudStore synchronize];
NSString *TotalUserPoints = [CloudStore stringForKey:@"TotalUserPoints"];
int pointsInt = [pointsStr intValue];
int TotalUserPointsInt = [TotalUserPoints intValue];
TotalUserPointsInt = TotalUserPointsInt + pointsInt;
NSString *totalStr = [NSString stringWithFormat:@"%d", TotalUserPointsInt];
[CloudStore setObject:totalStr forKey:@"TotalUserPoints"];
[CloudStore synchronize];
NSString *pointsStr = [CloudStore stringForKey:@"UserWantsToBuyPoints"];
[CloudStore setString:pointsStr forKey:@"UserWantsToBuyPoints"];
[CloudStore synchronize];
NSString *TotalUserPoints = [CloudStore stringForKey:@"TotalUserPoints"];
int pointsInt = [pointsStr intValue];
int TotalUserPointsInt = [TotalUserPoints intValue];
TotalUserPointsInt = TotalUserPointsInt + pointsInt;
NSString *totalStr = [NSString stringWithFormat:@"%d", TotalUserPointsInt];
[CloudStore setObject:totalStr forKey:@"TotalUserPoints"];
[CloudStore synchronize];
CloudStore.h (singleton)
#import <Foundation/Foundation.h>
@interface CloudStore : NSObject
+(CloudStore *)singleton;
@end
CloudStore.m (singleton)
#import "CloudStore.h"
@implementation CloudStore
+(CloudStore *)singleton {
static dispatch_once_t pred;
static CloudStore *shared = nil;
dispatch_once(&pred, ^{
shared = [[CloudStore alloc] init];
});
return shared;
}
@end
Upvotes: 0
Views: 46
Reputation: 107131
You are actually messing up the singleton and iCloud storage objects in your code. You need to declare and initialise the iCloud object in your singleton and use it:
CloudStore.h
#import <Foundation/Foundation.h>
@interface CloudStore : NSObject
// Storage property
@property (nonatomic, strong) NSUbiquitousKeyValueStore *cloud;
+ (CloudStore *)sharedStorage;
@end
CloudStore.m
#import "CloudStore.h"
@implementation CloudStore
+ (CloudStore *)sharedStorage
{
static dispatch_once_t pred;
static CloudStore *shared = nil;
dispatch_once(&pred, ^{
shared = [[CloudStore alloc] init];
[shared initStorage];
});
return shared;
}
- (void)initStorage
{
cloud = [NSUbiquitousKeyValueStore defaultStore];
}
@end
And wherever you want to use the CloudStore variable use it like:
Setting data:
[[[CloudStore sharedStorage] cloud] setObject:totalStr forKey:@"TotalUserPoints"];
Getting data:
NSString *pointsStr = [[[CloudStore sharedStorage] cloud] stringForKey:@"UserWantsToBuyPoints"];
Synchronising:
[[[CloudStore sharedStorage] cloud] synchronize];
You should read this nice tutorial : iOS Design Patterns, it'll help you to understand the usage of singleton much better.
Upvotes: 1