简体   繁体   中英

iOS Today Extension NSUserDefaults Sharing Data with Containing App using Callbacks

I've got the following problem:

I created a Today Extension, which contains an UISwitch . The IBAction of this switch in Today Extension should store the on-state using the NSUserDefaults with the initWithSuite like this:

- (IBAction)switchStateChanged:(id)sender {

     BOOL isOn = self.preferenceSwitch.isOn;

     NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.x.TodayExtensionSharingDefaults"];

    [sharedDefaults setBool: isOn forKey: @"SwitchState"];
    [sharedDefaults synchronize];
}

Now in my Containing App, I know that i can access the switch state using this:

NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.x.TodayExtensionSharingDefaults"];
BOOL value = [defaults boolForKey:@"SwitchState"];

I'm looking for a solution that gives me a callback in my main containing app, when the value of the switch is changed.

In this solution, i have to set a NSTimer that refresh the user-defaults every 200ms for example.

Is there any solution by adding an Observer to the sharedDefaults?

I think this will work for your use case:

When you leave your app and open up Notification Center,

- (void)applicationWillResignActive:(UIApplication *)application

is called in your AppDelegate. When you come back from the widget,

- (void)applicationDidBecomeActive:(UIApplication *)application

is called in your AppDelegate. So just check your value then and fire off a internal notification to your controller. You shouldn't have any need for a timer.

Observing the change in your app is not a good solution, even if you could make it work, because you can't be certain that your app is even running when the switch value changes. It's also not how today extensions are intended to work.

If your app needs to know the state of this switch the next time it runs (recognizing that it might not be running when the switch is tapped), you're already doing the right thing.

If you need to immediately notify your app that the switch value has changed (again, recognizing that your app might not be running and that doing this might launch your app), you should create a custom URL scheme for your app and then open the URL from the extension. This would be something like:

  • In the app, declare a custom URL scheme in the "URL types" section of the app's "Info" settings.
  • Also in the app, add code to the app delegate to receive requests to open URLs.
  • In the app extension, use [NSExtensionContext openURL:completionHandler:] to open the URL. This will launch your app and pass the provided URL.

If the URL scheme is something like mygreatapp , the app extension would open a URL like mygreatapp: . You can add detail to the URL if needed, or the app can just use user defaults to look up the saved value.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM