Can UserDefaults.standard.addSuite(...) be used by extensions?

I have a widget extension that needs to use some UserDefaults written from my host app. I didn't want to use UserDefaults(suiteName:) since it's an optional, so I used the following property from [this article]:(https://www.swiftbysundell.com/articles/the-power-of-userdefaults-in-swift/)

extension UserDefaults {
    static var shared: UserDefaults {
        let combined = UserDefaults.standard
        combined.addSuite(named: appGroupName)
        return combined
    }
}

But when I call it in the extension, the values are not present. Is this expected behavior?

For the record, I am 100% sure I have the right app groups. I also made a new project only to test this and it's behaving identically.

And I'm not calling .synchronize() for UserDefaults anywhere, but I don't think that's needed.

Accepted Reply

Thanks for the question.

I think something that the article didn't make clear is what happens when you set a value to UserDefaults that used addSuite.

The following code snippet I think demonstrates what's actually going on:

UserDefaults.shared.set("Hello World", forKey: "test2")
                
print(UserDefaults.standard.string(forKey: "test2")) // Prints: "Hello World"
print(UserDefaults(suiteName: appGroupName)?.string(forKey: "test2")) // Prints: nil

When setting a value, the way your UserDefaults.shared is declared, sets it on .standard first and never modifies the appGroupName suite.

If you want to set a value from your app that modifies the actual appGroupName suite, you have to use the UserDefaults(suiteName:) initializer from within the host app.

  • Got it, thank you!

Add a Comment

Replies

Thanks for the question.

I think something that the article didn't make clear is what happens when you set a value to UserDefaults that used addSuite.

The following code snippet I think demonstrates what's actually going on:

UserDefaults.shared.set("Hello World", forKey: "test2")
                
print(UserDefaults.standard.string(forKey: "test2")) // Prints: "Hello World"
print(UserDefaults(suiteName: appGroupName)?.string(forKey: "test2")) // Prints: nil

When setting a value, the way your UserDefaults.shared is declared, sets it on .standard first and never modifies the appGroupName suite.

If you want to set a value from your app that modifies the actual appGroupName suite, you have to use the UserDefaults(suiteName:) initializer from within the host app.

  • Got it, thank you!

Add a Comment