Share Datas Between Two Apps with iOS 8 App Groups (Using Nsuserdefaults)

Share datas between two apps with iOS 8 App Groups (using NSUserDefaults)

Check out this thread on the Apple Developer Forums:
https://devforums.apple.com/message/977151#977151

I believe that both instances need to use the group ID (initializing with initWithSuiteName:) or else they are reading/writing to different user defaults sets.

So your Swift code would change to:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults.setBool(true, forKey: "Bool")
userDefaults.synchronize()

Communicating and persisting data between apps with App Groups

Another benefit to App Groups is the ability to share a NSUserDefaults database. This also works for App Extensions (notification center widgets, custom keyboards, etc).

Initialize your NSUserDefaults object like this in all applications in the app group and they will share the database:

Objective-C:

[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];

Swift:

NSUserDefaults(suiteName: "<group identifier>")

Keep in mind everything from the [NSUserDefaults standardUserDefaults] database for each application will not carry over into this database.

The documentation gives a correct example as well (As of Beta 3).

And don't forget to synchronize the database:

[yourDefaults synchronize];

App Groups Data Sharing Between Applications iOS

You can store shared data using App Groups, but I've only tried to do this with built in types.

If you're trying to store your own classes you may need to look at something like NSKeyedArchiver and NSCoding (maybe look here).

If you can find a way to use the built in types you can use App Groups as follows:

Sharing NSUserDefaults data between multiple apps

In order to have shared defaults between an app and an extension or between 2 apps you have to add an App Group in your settings using the following steps:

  1. In the Project Navigator click on the *.xcodeproj file (should be at the top).
  2. To the right of the Project Navigator look for Project and Targets. Under targets click on your primary target (should be the first thing under Targets).
  3. Towards the top, click on the Capabilities tab.
  4. In the App Groups section click the switch to the right to turn App Groups ON.
  5. Click on the + button and add an App Group named group.com.company.myApp.
  6. Go to the same place in your other apps and this group should now be available to select. Turn this group on for each app that will be using this shared data.

Note: If you go to the Apple Developer Portal (the Apple website that shows all of your Certificates, Identifiers, Devices and Provisioning Profiles) and go to Identifiers > App Groups you should see this new App Group.

To store data:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults!.setObject("user12345", forKey: "userId")
userDefaults!.synchronize()

To retrieve data:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
print("User Id: \(testUserId)")
}

iOS 8 widget, sharing data between app groups forward and backward

The nil problem occurs because you try to access application's storyboard from widget. It's not straightforward, since the containing app and widget extension are being kept in a separate bundles. So the [NSBundle mainBundle] in step 2) is not the same bundle as the one in your app.

Possible solutions include:

  • including the app's Main.storyboard in extensions bundle either via adding it to Copy Bundle resources list at widget's target Build Phases tab or just adding widget target to Main.storyboard list of Target Membership

  • moving the code responsible for getting the messages from MainController startGetMessages: into a shared framework that will be accessible both from the app and the widget, preferably into a dedicated object.

The second one is way better. As a rule of thumb it's best to follow SOLID principles when doing the object-oriented programming, where S stands for single responsibility. It should not be a responsibility of view controller to provide the messages fetching system-wide. Creating a dedicated object that will have only one job - to get messages - and sharing it across the targets is a way to go.

Please consult the docs for the detailed explanation on how to create the shared framework: https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW1

Sharing UserDefaults between extensions

You cannot use UserDefaults.standard to share data between a host app and its app extension. You instead have to create a shared container with UserDefaults(suiteName:) to share data.

Even though an app extension bundle is nested within its containing
app’s bundle, the running app extension and containing app have no
direct access to each other’s containers.

To enable data sharing, use Xcode or the Developer portal to enable
app groups for the containing app and its contained app extensions.
Next, register the app group in the portal and specify the app group
to use in the containing app.

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 more, refer to: https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW1

How to use App Groups: https://github.com/pgpt10/Today-Widget

Standard or SuiteName?

Use standard one for data that is only for Host App. Use suiteName for data that you want to share between Extension and Host App. Just don't persist the same data in both of them. Avoid data redundancy. Use both of them according to the context.

Can I share files/data through App Groups but in different developer accounts applications?

The answer is no.

If you create a provisioning profile with an app group my.app.group and extract entitlements from it, you will see that the group is referenced as XXXXXXX.my.app.group where XXXXXXX is your developer ID, so on another account the group will be YYYYYYY.my.app.group and it will be perceived as a different group by any device.

More info: App ID, Application Groups



Related Topics



Leave a reply



Submit