Search code examples
iosobjective-cxcodewatchkitapple-watch

Apple Watch, WatchKit, and NSUserDefaults


I figured since the "Watch App" is a bundle in the same iOS application, I should be able to access NSUserDefaults within my Apple Watch App. Is this not so?

I can't seem to get NSUserDefaults values from my iOS (which I made sure has data as it loads fine in the iOS app).

When I run it in the Apple Watch app, it comes in as empty. Do I not have access to the same NSUserDefaults values as the iOS parent app?

I have a custom class which contains an NSMutalArray. This mutable array is what I want to display in a Table in the Watch App. This same class which contains the NSMutableArray also has functions to save/load data to/from NSUserDefaults. It works fine in my iOS app but just doesn't load data in the Apple Watch app.

What am I doing wrong here or what am I not aware of?

Here is the class:

Keep in mind that I use it as a singleton object too. It saves it's data into NSUserDefaults by first converting itself into NSData - which is why you see extra functions in this class that you can just ignore.

#import "Teacher.h"
#import "Course.h"

@implementation Teacher

static Teacher *sharedInstance = Nil;

+ (Teacher *)sharedInstance
{
    @synchronized(self)
    {
        if(!sharedInstance)
        {
            sharedInstance = [[self alloc] init];
        }
    }

    return sharedInstance;
}

- (id)init
{
    self = [super init];

    if (self)
    {
        _classes = [[NSMutableArray alloc] init];
    }

    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
    [coder encodeObject:_classes forKey:@"classes"];
}

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super init];

    if (self)
    {
        _classes = [coder decodeObjectForKey:@"classes"];
    }

    return self;
}

+ (void)saveData
{
    NSMutableArray *teacherClasses = [[Teacher sharedInstance] classes];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:teacherClasses];
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    [userDefaults setObject:data forKey:@"teacherClasses"];
}

+ (void)loadData
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *loadClasses= [NSKeyedUnarchiver unarchiveObjectWithData:[userDefaults objectForKey:@"teacherClasses"]];
    if(loadClasses == Nil)
    {
        loadClasses = [[NSMutableArray alloc] init];
    }

    [[Teacher sharedInstance] setClasses:loadClasses];
}

- (Teacher *) copyWithZone:(NSZone *)zone
{
    Teacher *teacher = [[Teacher alloc] init];
    [teacher setClasses:[self classes]];

    return teacher;
}

@end

Thanks.


Solution

  • You need to use a shared container if you wish to share data between your iOS app and your Apple Watch app.