Giter Site home page Giter Site logo

Comments (11)

sandstrom avatar sandstrom commented on April 29, 2024 3

Support for this is needed for many app extension scenarios, for example share extension, today extension and many of the other extensions.

We've ran into this when trying to create a share extension, and it seems like others have too (just one example from your forums):
https://forum.ionicframework.com/t/capacitor-plugin-for-share-extension-from-ios-android/187970

from capacitor-plugins.

jgirdner avatar jgirdner commented on April 29, 2024 2

Let's go fellas! iOS 14 is here. No time to delay.

from capacitor-plugins.

jcesarmobile avatar jcesarmobile commented on April 29, 2024

Issues tagged with feature request are closed but tracked for reactions to gauge interest.

Or if you are really interested and have the knowledge to implement this, you can send a PR.

from capacitor-plugins.

ryanflores79 avatar ryanflores79 commented on April 29, 2024

I just started looking into created an iOS widget to show some data on the home screen from within my ioinic capacitor app. I'm going to need a way of defining a suiteName so that when I store some data in the app, the widget extension can read the data and display it. Is there any plan to work on this now that iOS 14 beta is out?

from capacitor-plugins.

hocococaspar avatar hocococaspar commented on April 29, 2024

Pretty please implement this! :)

from capacitor-plugins.

hieuhoangtrung avatar hieuhoangtrung commented on April 29, 2024

@sandstrom @ThomasKientz There is a workaround for this.
@capacitor/storage is using UserDefaults.standard for storing data which is not able to share with app extension. What you need to do is migrating UserDefaults to App Groups. You can find the example code here
This migration will be run when iOS app is loaded in AppDelegate.swift. I'd recommend put it in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool
You don't needs to migrate all the keys/values though, just pick the important keys to share with your App Extension.

from capacitor-plugins.

taylorhlabs avatar taylorhlabs commented on April 29, 2024

I just posted about this yesterday in the forums before finding this post today. Does the Capacitor Storage plugin still only support reading from UserDefaults.standard? I noticed the Storage plugin has a "group" property in the options object, but it seems that doesn't refer to an App Group...

from capacitor-plugins.

ThomasKientz avatar ThomasKientz commented on April 29, 2024

@taylorhlabs it does still only support reading from UserDefaults.standard

Make sure to upvote the issue so the ionic team can track it

from capacitor-plugins.

viking2917 avatar viking2917 commented on April 29, 2024

@hieuhoangtrung Thanks for your suggestion. In your scenario how did you access (on the Ionic/js/capacitor side) the data stored in the group's UserDefaults? The Storage plugin does not seem to allow for this, not sure how else it might be done?

from capacitor-plugins.

viking2917 avatar viking2917 commented on April 29, 2024

so, I'm a poor iOS Developer (an Ionic hacker who learned Swift last night), but I implemented some changes to the Storage plugin that would allow for the passing of a 'suite' keyword, and then the Storage plugin would respect/retrieve from the NSUserDefaults of that suite.

I needed this because I want to share data between by Share Extension (heh heh) and my main app, as others here mentioned.

If someone competent wanted to review my changes beforehand (@jcesarmobile ??), I'd be willing to do a PR, but I'm not confident enough in my knowledge to just go for it. (Also I have not tried Android although I think the extra parameter, if passed, would just be ignored).

Changes were these: (complete altered files attached).

In definitions.d.ts, add the suite parameter

export interface ConfigureOptions {
    /**
     * Set the storage group.
     *
     * Storage groups are used to organize key/value pairs.
     *
     * Using the value 'NativeStorage' provides backwards-compatibility with
     * [`cordova-plugin-nativestorage`](https://www.npmjs.com/package/cordova-plugin-nativestorage).
     * WARNING: The `clear()` method can delete unintended values when using the
     * 'NativeStorage' group.
     *
     * @default CapacitorStorage
     * @since 1.0.0
     */
    group?: string;
    suite?: string;
}

in the Storage.swift file, add the suite parameter, hang on to it during initialization,

public struct StorageConfiguration {
    public enum Group {
        case named(String), cordovaNativeStorage
    }

    let group: Group
    // add optional suite string for use with NSUserDefaults
    let suite: String;

    public init(for suite: String = "", for group: Group = .named("CapacitorStorage")) {
        self.group = group
        self.suite = suite
    }
}

then alter the creation of the defaults variable to include the suite as necessary:


public class Storage {
    private let configuration: StorageConfiguration

    private var defaults: UserDefaults {
      if(configuration.suite.isEmpty) {
        return UserDefaults.standard
      } else {
        // if the suite configuration parameter is passed, use that suite for the UserDefaults DB.
       return UserDefaults(suiteName: configuration.suite) ?? UserDefaults.standard
      }
    }

in StoragePlugin.swift, grab the suite parameter if it is passed and give it to the constructor

public class StoragePlugin: CAPPlugin {
    private var storage = Storage(with: StorageConfiguration())

    @objc func configure(_ call: CAPPluginCall) {
        let group = call.getString("group")
        let suite = call.getString("suite")
        let configuration: StorageConfiguration

        if let suite = suite, group == nil {
          // if only suite is passed, just use that.
          configuration = StorageConfiguration(for: suite);
        } else {
          if let group = group, let suite = suite {
              if group == "NativeStorage" {
                  configuration = StorageConfiguration(for: suite, for: .cordovaNativeStorage)
              } else {
                  configuration = StorageConfiguration(for: suite, for: .named(group))
              }
          } else {
              configuration = StorageConfiguration()
          }
        }
        storage = Storage(with: configuration)
        call.resolve()
    }

In my share extension, to set the parameter:

...
UserDefaults(suiteName: <your-app-group-id>)?.set(value, forKey: <your desired storage key>)
...

then, in my (Ionic) app, I do this, and it works:

const setOptions = async () => {
   await Storage.configure({ suite: '<your-app-group-id>' });
};
setOptions();

const checkValue = async () => {
   const { value } = await Storage.get({ key: '<your desired storage key>' });
   console.log('storage:', value);
};
checkValue();

The only gotcha I have run across is that when you set the value, you must prepend 'CapacitorStorage.' to the key name because the Storage plugin will prepend that prefix before asking for it. E.g. if you want to store a key called 'foo', you must actually store 'CapacitorStorage.foo' .

Also I don't know that the suite name always has to be a shared App Group ID, but in particular if you want to share data between a Share Extension and an App, I believe that is required.

StorageTweaks.zip

from capacitor-plugins.

ThomasKientz avatar ThomasKientz commented on April 29, 2024

@jcesarmobile ping

from capacitor-plugins.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.