Hi Erik,

I don't think you can have Flash serialize a Dictionary by passing a Dictionary 
to FileStream.writeObject.  However, you can certainly iterate the Dictionary 
and save everything.  And later, read it all back and repopulate the Dictionary.

Personally, when writing custom serialization, I like storing the length of a 
thing before the actual thing in the data stream.  Makes it easier to 
deserialize.  With BitmapData.encode you should be able to get a ByteArray to 
add to the FileStream.

Feel free to ask more questions if you're not sure how to do it.

-Alex

On 10/27/18, 10:13 AM, "Erik Thomas" <erikjtho...@icloud.com> wrote:

    Hi Alex:
    
    The icons and logos are loaded from a server on startup, and then kept up 
to date via a 20 second polling pattern where the app checks if anything has 
changed on the server. We timestamp all images and when one does change we get 
latest and update the image in the app.
    
    The way a ContentCache is used for BitmapImage and Image is to set the 
loader like this:
    
    public static var imageCache:ImageCache = new ImageCache(); // subclass of 
ContentCache
    _image.contentLoader = Model.imageCache;
    _image.source = "https/someImageUrl"
    
    When the image is first retrieved from the URL, the ContentCache loader 
will save the image into a Dictionary (key/value pairs) where the key is the 
URL and the value is the bitmapData of the image.
    
    Then when using ItemRenderers, and they get recycled, the when the image 
URL changes, ContentCache will look up the URL in it's Dictionary and if it's 
already been downloaded it will simply display it without having to make an 
HTTP request. 
    
    ContentCache is a very cool thing the Adobe engineers designed into 
Flex/Flash and it makes lists with icons and pictures far more responsive.
    
    What I want to do is persist the cache to disk and load it when the user 
logs in again. If any image have changed since the last time they launched the 
app, the first 20 second poll will indicate a timestamp has changed and the app 
will retrieve images with a timestamp after the one returned when polling. So 
they will always be up to date.
    
    I said the images don't change but that's not actually true, they just 
don't change often, maybe once a week we'll onboard new organizations and 
events with images. 
    
    Embedding images is not an option because every new onboarded entity will 
require a new app build, full regression testing, submission to Apple for 
review and the entire release process. That's a bad business model.
    
    Anyway, there must be a way in FileStream to save a Dictionary with key as 
String and value as ByteArray, but I haven't figured it out yet. Was hoping 
someone else knows how.
    
    Thanks, Alex.
    
    Erik
    
    PS: I know how I can do this, but it's too much work the way I know how, I 
would have to take each cached image, use pngencoder to encode the bitmapData 
(ByteArray) to a PNG and save each image as a separate file. Last count our 
image cache has about 1500 images so that means 1500 files, plus a hash file to 
match the image URL to a generated filename for the image. Loading will then 
require reversing the process. If you've used image encoders in Flash/AIR you 
know they're  pretty slow. If we don't gain any speed, it's not worth the 
effort.
    
    
    On Oct 26, 2018, at 3:44 PM, Alex Harui <aha...@adobe.com.INVALID> wrote:
    
    Erik,
    
    How do the icons and logos get into the cache in the first place?  If they 
don't change, is there any reason not to embed them in the application?
    
    -Alex
    
    On 10/26/18, 3:36 PM, "Erik J. Thomas" <e...@linqto.com> wrote:
    
       Hey all:
    
       Have any of you come across an example of persisting a ContentCache to 
disk and reading it back on app launch? We have lots of icons and logos for 
hundreds of companies and they don't change between sessions. 
    
       Like this (doesn't work though). ImageCache is a subclass of 
ContentCache to get access to the protected cachedData:Dictionary which is 
key/value pairs, with key as URL to image, and value is bitmapData.
    
       public function saveImageCache(imageCache:ImageCache):void {
          var cacheFile:File = File.applicationStorageDirectory;
          cacheFile = cacheFile.resolvePath(IMAGE_CACHE_FILE_NAME);
          if (cacheFile.exists) {
             cacheFile.deleteFile();
          }
          var fileStream:FileStream = new FileStream();
          fileStream.open(cacheFile, FileMode.WRITE);
          fileStream.writeObject(imageCache.getEntries()); // this is a 
Dictionary with byte array for image as value
          fileStream.close();
       }
    
       The writeObject API of FileStream does not marshal the bitmapData to 
disk. 
    
       /**
        * Loads a persisted image cache from disk.
        *
        * @return ContentCache
        */
       public function loadImageCache():ImageCache {
          var cacheFile:File = File.applicationStorageDirectory;
          cacheFile = cacheFile.resolvePath(IMAGE_CACHE_FILE_NAME);
          if (cacheFile.exists) {
             var fileStream:FileStream = new FileStream();
             fileStream.open(cacheFile, FileMode.READ);
             var entries:Dictionary = fileStream.readObject() as Dictionary;
             fileStream.close();
             var imageCache:ImageCache = new ImageCache();
             imageCache.loadEntries(entries);
             return imageCache;
          }
          return null;
       }
    
       The entries variable does populate with all the keys as URLs, but the 
values are null. FileStream won't read just raw binary data in this way.
    
       I don't want to have to save every image using an encoder into separate 
files and then load them all back if I can help it. 
    
       Just seems FileStream should be able to just write a blob of binary data 
to disk and retrieve it "as-is" but it doesn't or I can't find the way.
    
       Thanks for your suggestions.
    
       Erik
    
    
    

Reply via email to