26

So I've been looking around and following all the steps to setup shared UserDefaults correctly but I should be missing something.

I have App Groups capability activated on both my app and my extension. Both use the same suite name ("group.TestSharedPreferences") and I write this way:

struct Preferences {
    static let shared = UserDefaults(suiteName: "group.TestSharedPreferences")!
}

On viewDidLoad:

Preferences.shared.set(1, forKey: "INT")

And to read:

Preferences.shared.integer(forKey: "INT") // Returns 1 in Container App
Preferences.shared.integer(forKey: "INT") // Returns 0 in Today Extension

Even using synchronize() just after setting "INT", the value retrieved in the extension is not the one saved in the container App. Any ideas on what might I be missing? Thank you!

matt
  • 515,959
  • 87
  • 875
  • 1,141
iDec
  • 707
  • 2
  • 8
  • 16
  • 1
    Does the entitlements file for both targets include that app group? – Léo Natan Oct 16 '16 at 00:41
  • I would expect `0` to be returned if the value for this key were `nil`. Thus this seems like a sign that either you are not defining `Preferences.shared` correctly in the today extension code or the today extension code is being called _before_ the app ever gets a chance to set the value. – matt Oct 16 '16 at 00:41
  • Possible duplicate of [Communicating and persisting data between apps with App Groups](http://stackoverflow.com/questions/24015506/communicating-and-persisting-data-between-apps-with-app-groups) – Maetschl Oct 16 '16 at 00:41
  • @LeoNatan Yes, both include the correct app group – iDec Oct 16 '16 at 00:42
  • @iDeC Perhaps try calling `synchronize()`. – Léo Natan Oct 16 '16 at 00:43
  • @matt I'm defining Preferences.shared the same way exactly in both the app and the extension, and I first run the app to be sure that the value is set and then the extension. – iDec Oct 16 '16 at 00:44
  • @LeoNatan already tried that but no luck :/ – iDec Oct 16 '16 at 00:45

2 Answers2

41

I would recommend to dig down step by step here.

First, make sure that both the main app and the widget extension have app group capability enabled and use the same and activated (the checkmark must be set) app group name:

Main App: Main App

Today Widget Extension:

Today Widget Extension

Then make a simple test with direct set/get access. In your main app's AppDelegate.didFinishLaunchingWithOptions method (change the app group name and the keys to your needs):

if let userDefaults = UserDefaults(suiteName: "group.de.zisoft.GPS-Track") {
    userDefaults.set("test 1" as AnyObject, forKey: "key1")
    userDefaults.set("test 2" as AnyObject, forKey: "key2")
    userDefaults.synchronize()
}

In your Today Widget Extension's ViewController:

if let userDefaults = UserDefaults(suiteName: "group.de.zisoft.GPS-Track") {
    let value1 = userDefaults.string(forKey: "key1")
    let value2 = userDefaults.string(forKey: "key2")
    ...
}

If this works, the problem must be related in your Preferences singleton.

zisoft
  • 22,770
  • 10
  • 62
  • 73
  • Okay this seemed to be working but I started getting this warning: Failed to read values in CFPrefsPlistSource<....>. So I ended up changing my group.XXXX defaults name and for some reason is correctly working now. Thank you anyways! – iDec Oct 16 '16 at 12:42
  • I had the same issue and just like @iDeC solved by creating a new sharedContainer. And then everything worked. – sambro Feb 17 '18 at 19:26
  • @zisoft Thanks for the clear description of App Group, Its helped me to communication between my app and service extension. – iDeveloper Sep 23 '18 at 09:09
  • it was enabling it for both app and extension for me. and checking both entitlements - one got added automatically and the other not. – Jonathan Plackett Feb 09 '19 at 22:32
  • same issue for me too. Unexpectedly found nil while unwrapping an Optional value Fatal error: when access as an object its returns nil. https://stackoverflow.com/questions/55820193/how-to-set-response-data-into-todayextenstion-widget – kiran Apr 29 '19 at 19:06
1

I had the same problem, and my mistake was that I accidentally added app groups only to release configuration. And, of course, while testing on debug configuration nothing worked, app extensions couldn't retrieve shared data from user defaults. So be sure you add it to both configurations.

enter image description here

  • 1
    Thank you. Silly mistake. My widget extension was not working in production because I added group only to debug mode – Praveena Aug 31 '23 at 09:36