Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't NSUserDefaults work between my app & share extension?

I have an iOS app with a share extension. I am trying to share data between them using NSUserDefaults and App Groups but, while I can write into the NSUD object, read it, and synchronize() without error, reading in the extension always results in nil.

I have an app group, the literal string "group.net.foo.bar" for which both the app & extension have configured under Capabilities -> App Groups. This string is in a constants struct in my app:

struct Forum {
    static let APP_GROUP = "group.net.foo.bar"
    static let AUTH_KEY = "AUTH_KEY"
}

In the main app I create a UserDefaults object and write to it:

fileprivate lazy var userDefaults: UserDefaults = {
    let defaults = UserDefaults()
    defaults.addSuite(named: Forum.APP_GROUP)
    return defaults
}()

// later
userDefaults.set(apiKey, forKey: Forum.AUTH_KEY)
userDefaults.synchronize()

Creating a new NSUD object after that synchronize() and retrieving the AUTH_KEY works. In the extension, I create an NSUD and try to retrieve the value, to no avail:

private lazy var userDefaults: UserDefaults = {
    let defaults = UserDefaults()
    defaults.addSuite(named: Forum.APP_GROUP)
    return defaults
}()

// later
private func getApiKey() -> String? {
    return userDefaults.string(forKey: Forum.AUTH_KEY)
}
// returns nil

In all of my reading of the Apple docs and depressingly-similar questions here on Stack Overflow I can't divine what I've done incorrectly.

Xcode Version 8.0 (8A218a), also tested with Xcode 8.1 Beta 2. Same behavior on simulator andy my iPhone 6s running iOS 10.

like image 750
Drew Stephens Avatar asked Oct 11 '16 16:10

Drew Stephens


People also ask

How much data can you store in NSUserDefaults?

It appears the limit is the maximum file size for iOS (logically), which is currently 4GB: https://discussions.apple.com/thread/1763096?tstart=0. The precise size of the data is circumscribed by the compiler types (NSData, NSString, etc.) or the files in your asset bundle.

Is NSUserDefaults thread safe?

Thread SafetyThe UserDefaults class is thread-safe.

How do you check if NSUserDefaults is empty in Objective C?

There isn't a way to check whether an object within NSUserDefaults is empty or not. However, you can check whether a value for particular key is nil or not.

How do you save NSUserDefaults in Objective C?

Saving to NSUserDefaults : Basically, all you have to do is load NSUserDefaults, and then tell it to save a value to a specific key. Here is a simple example of writing an integer to NSUserDefaults: NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];


1 Answers

Not sure if defaults.addSuite(named: ...) does the same as UserDefaults(suiteName: ...). In my app I use appGroups this way and it works as expected:

// write
if let userDefaults = UserDefaults(suiteName: appGroupName) {
    userDefaults.set("---" as AnyObject, forKey: "distance")
    userDefaults.set("---" as AnyObject, forKey: "altitude")
    ...
    userDefaults.synchronize()
}

// read
if let userDefaults = UserDefaults(suiteName: appGroupName) {
    self.distanceLabel.text = userDefaults.string(forKey: "distance")
    self.altitudeLabel.text = userDefaults.string(forKey: "altitude")
}
like image 164
zisoft Avatar answered Sep 20 '22 18:09

zisoft