8 Replies Latest reply on May 10, 2010 11:38 AM by chris.s.jordan

    EncryptedLocalStore... works in debug, but not when compiled.

    chris.s.jordan

      Okay, so I looked around the forum and saw a couple of people with this same problem, but their solutions didn't seem to help me. I don't know if it's because I didn't understand them, or what.

       

      Here's my problem.

       

      I've written a nifty little AIR app (AIR 1.5), using Aptana, JavaScript (jQuery) and HTML. The app works perfectly when run from the debugger inside of Aptana.

       

      However, when I deploy the application (sign it with my self-signed certificate, etc.) and then install it, all of the ELS functionality ceases to work.

       

      I'm obviously not the first person this has happened to, but I don't know what it is that I'm doing wrong.

       

      If it helps, here is the code for my DataStoreManager:

       

      var DataStoreManager = function(){
           return{
                __insert: function(key, data){
                     /**
                      * function to insert data into the local encrypted datastore
                      * @author: Chris Jordan
                      * @date: 03/22/2010
                      * 
                      * @param: key - the key to save the data to in the encrypted store.
                      * 
                      * NOTE:
                      *  This now relys on the global AppConfig object rather than any passed in values.
                      */
                     
                     var my = {};
                     //serialize the AppConfig object
                     my.serializedAppConfig = jQuery.toJSON(data);
                     my.byteArray = new air.ByteArray();
                     my.byteArray.writeUTFBytes(my.serializedAppConfig);
                     air.EncryptedLocalStore.setItem(key, my.byteArray);
                     em.dispatchEvent("DataStorageComplete");
                },
                __read: function(key){
                     /**
                      * function to read data from the local encrypted datastore
                      * @author: Chris Jordan
                      * @date: 03/23/2010
                      */
                     var my = {};
                     //get the byteArray back out of the encrypted local store
                     my.byteArray = air.EncryptedLocalStore.getItem(key);
                     if(my.byteArray != null){
                          //if we got something back, then read it and return it.
                          return my.byteArray.readUTFBytes(my.byteArray.bytesAvailable);
                     }
                     else{
                          return "";
                     }
                },
                __remove: function(key){
                     /**
                      * function to remove data from the local encrypted datastore
                      * @author: Chris Jordan
                      * @date: 03/23/2010
                      */
                     air.EncryptedLocalStore.removeItem(key);
                }
           };
      }();
      

       

      BTW, is there a better way to insert code snippets into a forum post? I just manually edited the html to make it a bit nicer to look at. Anyway, that aside, I'm hoping that someone can help me with my real issue.

       

      Thanks!

        • 1. Re: EncryptedLocalStore... works in debug, but not when compiled.
          chris.s.jordan Level 1

          Okay, so I switched from using the ELS to just writing my serialized string out to a file. This didn't fix my problem though. The app still behaves the same way. Only now, I can monitor that file that I'm writing the serialized string to, for changes and I learned something by doing this.

           

          My app has a config screen that gathers three pieces of information and stores it. So the user opens this screen, adds the data, and clicks save to write the data to a file, and close the window. So the end result of clicking save is that the config window closes (after having written the data to file).

           

          When I export the app and run it, I add some data and click save, but the window doesn't close. I can, at that point look at the config file and see that the data has indeed been serialized and written to the file. It just appears that the screen hasn't closed. So, I click save again (what else am I going to do?). This time the window closes, but an empty string has been written out to the file replacing the config string I had out there to begin with!

           

          So when I saw this behavior I immediately thought that maybe I had a timing issue. I should probably explain that I'm using jQuery (.bind and .trigger) to implement the observer pattern in this app. So, when I click the "Save" button, an event gets dispatched telling the app to write the data down to the disk. When that's done the function that is doing the writing announces that it's done saving, and in response to that announcement I dispatch two other events. One to close the config window, and one that rebuilds a menu using the new config data. These last two events should be mutually exclusive. They don't depend on each other. But just in case, I have tried just dispatching the close window event, and commenting out the rebuild menu event. That didn't help at all.

           

          So, like I said, maybe I've got some kind of timing issue here. So I took my dispatchEvent function and wrapped it in a timer.

           

          //the way my dispatchEvent function used to look (without the timer)
          var em = function(){
              return {
                  dispatchEvent: function(e, o){
                      jQuery(document).trigger(e,[ o || null ]);
                  }
              };
          }();
          
          //new and improved function with a timer...
          var em = function(){
              return {
                  dispatchEvent: function(e,o){
                      var my = {};
                      my.timeout = setTimeout(function(){
                          jQuery(document).trigger(e,[ o || null ]);
                      },100);
                  }
              };
          }();
          

           

          However, for all this... the timer didn't change things at all. I tried 100 milliseconds and 500 milliseconds. No difference. So, maybe it's not a timing issue... I don't know.

           

          This is really bugging the crap out of me. I'm doing something wrong I guess, but I can't seem to figure out for the life of me, what the hell it is! Maybe I've just been staring at the code too much, but I could really use a hand. Has anyone else ever encountered this kind of thing before?

           

          I'm starting to wonder what sort of apps have been written for the AIR platform using JavaScript. Is this happening because of the way I'm implementing the observer pattern or what? I know that last one would be difficult to answer without having all my code to look at, but I'm not beyond thinking that I've just done something wrong on that front.

           

          BUT...

           

          It works PERFECTLY when being run from within the IDE (again, that's Aptana in this case).

           

          What gives?

           

          Thanks for reading. I hope someone out there can help me.

          • 2. Re: EncryptedLocalStore... works in debug, but not when compiled.
            Joe ... Ward Level 4

            How are you closing the config window? That seems to be where the problem lies...

            • 3. Re: EncryptedLocalStore... works in debug, but not when compiled.
              chris.s.jordan Level 1

              Thanks for reading through all this and responding.

               

              Closing the window once the data has been written I dispatch an event called "DataStorageComplete". The following is executed upon dispatching that event:

               

              closeWindow: function(){
                   //clear all elements from AppConfig
                   window.AppConfig.splice(0,window.AppConfig.length);
                   //reinitialize the config object
                   ConfigManager.init();
                   em.dispatchEvent("WindowManager_closeWindow");
                   em.dispatchEvent("MenuManager_rebuildReinitMenu");
              },
              

               

              This function empties out my Config object (an array of objects) and then reads the new config from the disk. Once this is done, I dispatch the event that will *really* close the window, which looks like this:

               

              //while this function has the same name as the one above, each is in its own namespace.
              closeWindow: function(w){
                   if((w !== undefined || w !== null) && w.htmlHost !== undefined){
                        alert("Closing Window using w.htmlHost.windowClose");
                        w.htmlHost.windowClose()
                   }
                   else{
                        alert("Closing Window using window.close");
                        window.close();
                   }
              },
              

               

              The other event "rebuildReinitMenu" doesn't care about the window at all, and I've even commented it out before to see if it was getting in the way of things.

               

              My main problem here is that this ALL works perfectly when run from inside the IDE.

               

              In writing this response though, I'm wondering if the problem isn't with the line that calls ConfigManager.init() I'm assuming that WindowManager_closeWindow and MenuManager_rebuildReinitMenu are waiting until ConfigManager.init() returns before executing... maybe that's not the case. What do you think? That seems worth looking into.

               

              Any other thoughts?

               

              Thanks again for responding.

              • 4. Re: EncryptedLocalStore... works in debug, but not when compiled.
                Joe ... Ward Level 4

                I think the problem is that your window close logic is failing for some reason. I can't think of an obvious reason as to why it would work when debugging but not when installed, though.

                 

                Some things to check:

                Are you running against the same version of AIR in the installed vs the IDE scenario?

                Have you compared the installed directory with your development directory to see if anything is missing or different (the application descriptor is moved and some signature files added to the meta-inf directory, but everything else should be where you put them)?

                Try running straight from the ADL tool in the SDK. Run both the version in your development path and in the installed path with ADL. Next use the -nodebug flag of ADL, which is closer to the installed environment.

                1 person found this helpful
                • 5. Re: EncryptedLocalStore... works in debug, but not when compiled.
                  chris.s.jordan Level 1

                  Thanks Joe.

                   

                  I've never run anything directly from the ADL tool, so I'm not sure how to do it. But I'll do some googling and see if I can't figure it out. In Aptana, I believe it's using 2.0 beta, but I'm not using any 2.0 features. Also, in my application descriptor file, I've told it to build a 1.5.3 app. Still I can try configuring Aptana to use the 1.5.3 SDK.

                   

                  What does the -nodebug flag gain for me?

                   

                  Thanks again,

                  Chris

                  • 6. Re: EncryptedLocalStore... works in debug, but not when compiled.
                    Joe ... Ward Level 4

                    You can get information on ADL here: http://help.adobe.com/en_US/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118666ade46-7fd9. html

                     

                    It's pretty simple, the syntax is just:

                    adl appdescriptor.xml

                     

                    The WebKit engine in AIR isn't versioned in the same way as the rest of AIR. You will always get the latest version available. Thus even if you specify 1.5.3 in the application descriptor, you will get the newer version when running from the AIR 2 SDK.

                     

                    Adding the -nodebug flag makes ADL run the app in a way that is closer to how it is run when installed. If you run your development version with adl and -nodebug, it should behave the same as the installed version.

                    • 7. Re: EncryptedLocalStore... works in debug, but not when compiled.
                      chris.s.jordan Level 1

                      Okay, so I know it's been a long while since I've looked at this thread, but I tried what Joe suggested and ran the app directly using the adl -nodebug (both the development version and the version that gets included along with the compliled exe) and both work just fine. But running the compiled executible, still bombs.

                      • 8. Re: EncryptedLocalStore... works in debug, but not when compiled.
                        chris.s.jordan Level 1

                        Okay so I solved this. The problem was that I was using a jQuery plug-in (jquery.json.2-2.min.js) and it was improperly encoding the object that I was trying to store, so when I'd read the string out of the store, and try to deserialize it, I'd get an error, but I couldn't see this error until I ran the app using adl.exe from the command line.

                         

                        Anyway, just wanted folks to know in case it might ever help anyone else.

                         

                        On another note, I'm actually sorta surprised that AIR does not provide some JSON encoding/decoding capabilities given how seemingly ever present it is as a data transfer format.