Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS problem with NativeStorage.keys #106

Open
matthewhixson opened this issue Jan 5, 2018 · 16 comments
Open

iOS problem with NativeStorage.keys #106

matthewhixson opened this issue Jan 5, 2018 · 16 comments
Assignees
Labels

Comments

@matthewhixson
Copy link

Hi folks, I'm by no means an expert and I've only been using Cordova NativeStorage for a couple of days now. I'm having a bit of a problem when calling NativeStorage.keys(s, e)... returning instead a large array (189 items) of various WebKit keys - which I presume to be the NSUserDefaults.

To my knowledge, when debugging my iPhone via Safari I am able to set items to storage just fine, but I am unable to resolve any keys for them.

I am running iOS 11.2 on an iPhone 7plus device.

@alokrajiv
Copy link
Collaborator

@Matt-z91 Hi Matt, I just ran the test suit and key functions test passed on iPhone 7+ with iOS 11.1

it('should return the keys', function(done) {

If you are sure, then let me explore it further and get back. But, in the meantime could you explain your code/usage and/or try on an iOS <11.1.

Thanks!

@alokrajiv alokrajiv self-assigned this Jan 5, 2018
@matthewhixson
Copy link
Author

matthewhixson commented Jan 5, 2018

Thanks for your reply Alokrajiv.

I've managed to partially resolve the problem by changing my implementation. The scenario is as follows:

  • There are several items/objects we wish to store if device goes offline,
  • Objects are stored with a random key to later identify them,
  • Device goes offline - attempt to fetch all the objects via NativeStorage.keys.

(At this point, when NativeStorage.keys resolves, I receive a large array full of WebKit values and some NS values -- whether or not I should be seeing this on an iOS device I do not know. On Android I just get the array of keys I want).

  • When we're online, parse this array, adding items via their key to a separate array that we will call Promise.all on to fetch the our objects from persistent store in one go.

My solution for now is just to prefix all random keys with an identifier so I can differentiate between values I want and these WebKit values and such.

I'm not currently able to test this solution on iOS 11.1 today but will when I get the chance to.

@alokrajiv
Copy link
Collaborator

@Matt-z91 Another alternative will be save it as a config object and keep updating the object.

roughly like NativeStorage.getItem('config', (config)=>{config.foo = bar; NativeStorage.setItem('config', config)});

Sorry, you have to use a workaround :(

@alokrajiv alokrajiv added the bug label Jan 5, 2018
@alokrajiv
Copy link
Collaborator

alokrajiv commented Jan 5, 2018

@GillesC We have a BUG.

The test do check if the key exists, but not if there are other entries inside.

NativeStorage.keys((...args)=>console.log(...args));

showed me :

["AKLastCheckInSuccessDate", "WebKitSimpleLineLayoutEnabled", "AddingEmojiKeybordHandled", "WebKitTextAutosizingEnabled", "WebKitFantasyFont", "WebKitUserStyleSheetEnabledPreferenceKey", "WebKitCacheModelPreferenceKey", "WebKitJavaScriptRuntimeFlagsPreferenceKey", "WebKitPrivateBrowsingEnabled", "WebKitBackForwardCacheExpirationIntervalKey", …] (184) (main.js, line 148)

@alokrajiv
Copy link
Collaborator

Went till nc2() cordova.js#1045. The values are coming into the js command queue cordova.js#1036 from native code..which is interesting because why Webkit then... 😕 . But, it from the objective-c code for sure...so your territory :) @GillesC 👨‍💻

iOSExec.nativeCallback = function(callbackId, status, message, keepCallback, debug) {
    return iOSExec.nativeEvalAndFetch(function() {
        var success = status === 0 || status === 1;
        var args = convertMessageToArgsNativeToJs(message);
        function nc2() {
            cordova.callbackFromNative(callbackId, success, status, args, keepCallback);

@alokrajiv alokrajiv assigned GillesC and unassigned alokrajiv Jan 5, 2018
@matthewhixson
Copy link
Author

Thanks for delving into that Alokrajiv, it's much appreciated.

@GillesC
Copy link
Collaborator

GillesC commented Jan 5, 2018

It seems that iOS is already injecting some keys which can be used to control the WebKit behaviour of an application. And I am, thus, unsure how to resolve this problem. We can live with it. Or we could include our own prefix prior to storing it in nsuserdefaults. But this will make it more complex if users want to access the default injected keys.

@alokrajiv
Copy link
Collaborator

alokrajiv commented Jan 5, 2018

But, how is iOS injecting WebKit. Or is it happening at the Cordova Native Bridge?

Here?

pluginResult = [CDVPluginResult resultWithStatus: CDVCommandStatus_OK messageAsArray:keys];

@GillesC
Copy link
Collaborator

GillesC commented Jan 5, 2018

It could be also Cordova iOS which uses NSUserdefaults to store defaults for the used webview.

@GillesC
Copy link
Collaborator

GillesC commented Jan 5, 2018

@alokrajiv
Copy link
Collaborator

oh..ofcourse. Other components could be using NSUserDefaults.

So, that means we need to be careful not to return info not saved by the plugin!!

@GillesC
Copy link
Collaborator

GillesC commented Jan 5, 2018

The only problem is that we do not want to interfere with the keys used by Cordova or the WebKit (which can also access nsuserdefaults).

@alokrajiv
Copy link
Collaborator

We could do 2 things

  • maintain our book-keeping..ie.maintain our config which can include a list of indexes

  • prefix our index internally, so we don't mix our data with other application data

@GillesC
Copy link
Collaborator

GillesC commented Jan 5, 2018

@alokrajiv
Or use initWithSuiteName, which lets you define a specific db to store your variables. Hence, nog internal indexing is needed. And share these values with extensions. Which is already implemented in PR #91.

@shamilovtim
Copy link

Stumbled across this issue today. Going to see if I can store all of the keys under one identifier to solve this problem.

@shamilovtim
Copy link

I decided to switch to Ionic's regular Storage, could not get around this bug without substrings and iterating through a giant array.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants