WatchKit SDK not retrieving data from NSUserDefaults

13,347

Solution 1

+standardUserDefaults returns an NSUserDefaults object that only saves information for the current process.

If you want to create an NSUserDefaults object that shares data between your iOS app and one of its extensions, then you'll need to set up an app group container and use that as the basis for sharing information.

From the linked documentation:

After you enable app groups, an app extension and its containing app can both use the NSUserDefaults API to share access to user preferences. To enable this sharing, use the initWithSuiteName: method to instantiate a new NSUserDefaults object, passing in the identifier of the shared group. For example, a Share extension might update the user’s most recently used sharing account, using code like this:

// Create and share access to an NSUserDefaults object.
NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.example.domain.MyShareExtension"];

// Use the shared user defaults object to update the user's account.
[mySharedDefaults setObject:theAccountName forKey:@"lastAccountName"];

NOTE: With watch OS2 you can no longer use shared group containers.

Solution 2

IMPORTANT

With watch OS2 you can no longer use shared group containers. You need to use this stack overflow answer.

"For OS2 - you will need to use the WatchConnectivity frameworks and implement the WCSessionDelegate."

Share:
13,347

Related videos on Youtube

Ravin Sardal
Author by

Ravin Sardal

SOreadytohelp Freshman studying Software Engineering. Class of 2018

Updated on June 04, 2022

Comments

  • Ravin Sardal
    Ravin Sardal almost 2 years

    I wanted to make a test app for the Apple watch in which you can set some String on your phone, and then it will be displayed on the Apple Watch. I decided to use NSUserDefaults class to store this data.

    In my view controller for the iPhone I have a method which takes the input and stores into local storage:

    - (IBAction)saveInfo:(id)sender {
    
        NSString *userInput = [myTextField text];
    
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
        [defaults setObject:userInput forKey:@"savedUserInput"];
    
        [defaults synchronize];
    
        self.myLabel.text = [defaults stringForKey:@"savedUserInput"];
    }
    

    And in my watch interface controller I have a method that retrieves the data and displays it:

    - (IBAction)showText2 {
    
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    
        [defaults synchronize];
    
        self.myLabel2.text = [defaults stringForKey:@"savedUserInput"];
    }
    

    Except for some reason the data I am trying to retrieve is shown as null, and the label is not being updated.

    • johndpope
      johndpope almost 9 years
    • William T.
      William T. over 8 years
      Please note, shared NSUserDefaults will NOT work on WatchOS2. This is a feature specific to WatchOS1,
  • Ravin Sardal
    Ravin Sardal over 9 years
    I set up the group container in DevPortal and have put the appropriate group name, but the data is still not being shared between the phone and the watch. Does it take a while to update within apple?
  • Dave DeLong
    Dave DeLong over 9 years
    @RavinSardal I believe the suite name you'll want to use is @"group.{whatever your group name is}"
  • Srivathsalachary Vangeepuram
    Srivathsalachary Vangeepuram over 9 years
    Dave, a WatchKit target does not have a "capabilities" tab in Xcode. Do WatchKit apps automatically inherit app group settings? I've used app groups for extensions but I don't see where to add one for WatchKit.
  • Dave DeLong
    Dave DeLong over 9 years
    @TomHarrington A Watch App does not have Capabilities, but the WatchKit Extension does; since it's the extension that contains the executable code, it's the extension that needs the app group capability.
  • Srivathsalachary Vangeepuram
    Srivathsalachary Vangeepuram over 9 years
    @DaveDeLong got it, I was looking at the wrong target. Thanks.
  • Naloiko Eugene
    Naloiko Eugene about 9 years
    @DaveDeLong Exactly. Thanks! Though in docs apple says: NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"com.example.domain.MyShareExtension"]; But the groupId can start only with "group." prefix. So the correct code is: NSUserDefaults *mySharedDefaults = [[NSUserDefaults alloc] initWithSuiteName: @"group.myGroupId"];
  • CarmeloS
    CarmeloS about 9 years
    @DaveDeLong Your comment for watch kit extension and its capability saved my day. Would please stress that one need to set the capability in watch extension in your answer so that others who missed the comment will see it?
  • Kudit
    Kudit about 9 years
    Didn't seem to work for me. Using my group in both the app and the extension. App seems to work fine, but the extension/watch doesn't seem to be able to pull that data (getting null).
  • Kenny Wyland
    Kenny Wyland almost 9 years
    +1 for the Capability on the Extension. Once I went to the Extension target and enabled that Capability, then his worked perfect. @DaveDeLong, I recommend adding that to your answer if you are allowed to edit it still.
  • Mrug
    Mrug about 8 years
    Is it working in WatchOS2. I am struggling to access shared NSUserDefaults but not able to access, always getting (null)
  • dredful
    dredful about 8 years
    IMPORTANT - This no longer works in WatchOS2 - stackoverflow.com/questions/30851729/…