Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Adobe AIR Development

Reply
Contributor
underLabs
Posts: 37
Registered: ‎11-29-2010
My Device: Not Specified

Saving Settings of an Application - Even after closing

[ Edited ]

Hello Chaps,

 

This forum is pretty active :smileyhappy:

I was curious on the ability to save settings (numbers & strings) for an application on the Playbook even after its closed, so when the user reopens it, the settings are saved.

 

Is the capability of SharedObjects possible?

Please use plain text.
Trusted Contributor
PBDev
Posts: 108
Registered: ‎12-28-2010
My Device: Free PlayBook
My Carrier: Verizon

Re: Saving Settings of an Application - Even after closing

Yeah SharedObjects is the way to go. All of my apps come back just like they were never closed. Do a search I think some code was posted here.

Please use plain text.
Developer
TheDarkIn1978
Posts: 409
Registered: ‎12-10-2010
My Device: PlayBook
My Carrier: N/A

Re: Saving Settings of an Application - Even after closing

you can use Local Shared Objects or you can roll your own persistence data manager using the FileSystem APIs.


PlayBook Applications:
Drop Swatch
Please use plain text.
Developer
jtegen
Posts: 6,541
Registered: ‎10-27-2010
My Device: HTC One, PlayBook, LE Z10, DE Q10
My Carrier: Verizon

Re: Saving Settings of an Application - Even after closing

Local File system with XML is another way to go.

Please use plain text.
Developer
UberschallSamsara
Posts: 1,026
Registered: ‎12-29-2010
My Device: PlayBook, Z10 LE, Dev Alpha C

Re: Saving Settings of an Application - Even after closing

[ Edited ]
Example SharedObject usage was discussed in the 2nd weekly webcast, and example code is in the RSS reader example project:

Dev resource page:

http://us.blackberry.com/developers/tablet/devresources.jsp?IID=DEVTABOS01042011

Week 2 webcast: http://www.blackberry.com/developers/tabletos/myfirstapp

you may have to register to view the archive.

Example code in Flash Builder format (rename to a .zip file and unzip it if you don't have Flash Builder):

http://us.blackberry.com/developers/tablet/RSSReader.fxp
Please use plain text.
Developer
peter9477
Posts: 6,473
Registered: ‎12-08-2010
My Device: PlayBook, Z10
My Carrier: none

Re: Saving Settings of an Application - Even after closing

The others have mentioned all but the flash.data API, which uses the excellent embedded SQLite database that's integrated with AIR.  This isn't the best thing to use if you don't understand anything about databases and SQL, but if you have a lot of data and it's very structured (multiple sets of data that you might think of as tabular, with relationships between items in different tables) then this may be the best option.

 

For just "settings", though, almost certainly SharedObjects is the way to go.


Peter Hansen -- (BB10 and dev-related blog posts at http://peterhansen.ca.)
Author of White Noise and Battery Guru for BB10 and for PlayBook | Get more from your battery!
Please use plain text.
Developer
studiochris
Posts: 165
Registered: ‎10-26-2010
My Device: BlackBerry® PlayBook™
My Carrier: .

Re: Saving Settings of an Application - Even after closing

[ Edited ]

If you have a lot of settings, I wouldn't recommend this because the XML stays completely loaded in memory (twice with this class). 

 

I usually use a super simple class I wrote for an XML file. The class has 5 methods, all public: load(), save(), setKey(), getKey(), revert(). The XML parts could be made a little more flexible, but this has fulfilled my needs, so I haven't bothered. It also does no error checking at all aside from file.exists. I added some comments to the file to explain what's happening. Feel free to expand on it.

 

You can nest the XML however you need, with one exception. The final nodes that will hold data to be retrieved by getKey() should be in the following format:

 

 

<keyName value="some value" />

 

License: Creative Commons Attribution 3.0 [http://creativecommons.org/licenses/by/3.0]
Author/Attribution Info: Chris Price | http://www.studiochris.us

package
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;

	public class SettingsProxy extends EventDispatcher
	{
		static public const NAME:String = "SettingsProxy";
		
		static public const SETTINGS_LOADED:String = "settingsLoaded";
		static public const SETTINGS_SAVED:String = "settingsSaved";
		
		//The XML file
		private var file:File;
		
		//XML loaded directly from the file.
		//ALWAYS contains the original contents of the file as it was loaded.
		private var masterCopy:XML;
		
		//A clone of masterCopy - this is the writable copy
		private var workingCopy:XML;
		
		//A FileStream object that can be reused thoughout the class
		private var fs:FileStream;
		
		//A reasonable base set of settings to use
		//to create the XML file if it doesn't exist.
		//This is also a last-resort fallback used to recreate
		//the file if it is corrupted or missing.
		private var settingsTemplate:XML = new XML('<whatever your="template" needs="1" />');

		public function SettingsProxy() {
			
			fs = new FileStream();
			
			file = new File(File.applicationStorageDirectory.nativePath + File.separator + 'settings.xml');
						
			if (!file.exists)
			{				
				fs.open(file, FileMode.WRITE);
				fs.writeUTFBytes('<?xml version="1.0" encoding="UTF-8"?>' + settingsTemplate.toXMLString());
				fs.close();
			}
			
			load();
		}
		
		//load the settings file
		public function load(e:Event = null):void
		{
			if (file.exists)
			{
				//Open the file, read it and set master Copy to the file's content as XML
				fs.open(file, FileMode.READ);
				masterCopy = new XML(fs.readUTFBytes(fs.bytesAvailable));
				fs.close();
				
				//create workingCopy, leaving masterCopy untouched
				workingCopy = masterCopy.copy();
				
				//tell the world that the settings have been loaded
				dispatchEvent(new Event(SETTINGS_LOADED));
			}
		}
		
		//Save workingCopy to the file, overwriting the original content.
		//Leave the possibility of an event triggering save in the future.
		//In my case, if I call this myself from the application, I do it directly
		//without passing an event; if the save is initiated by a user, the user is
		//actively committing to a settings change, and an Event (usually MouseEvent.CLICK)
		//is passed from the UI. (more below)
		public function save(e:Event = null):void
		{
			if (file.exists)
			{
				//open the file in WRITE mode, write the content of workingCopy
				//to the file and close the file
				fs.open(file, FileMode.WRITE);
				fs.writeUTFBytes('<?xml version="1.0" encoding="UTF-8"?>' + File.lineEnding + newSettings);
				fs.close();
				
				//If the user initiated the save function (usually through a save button),
				//reload the file. As noted above, if I call the save function, I don't do it
				//by passing an event usually.I know the app is using workingCopy, and I'm
				//not going to mess things up. This leaves flexibility as well. For instance,
				//if I save on the close event, there is no need to reload the settings. 
				//The app is closing; it doesn't need an 
				//extra wasted task. One more example
				//if I need to temporarily change a setting, I can do it, then revert back 
				//to masterCopy if I don't need the change any longer.
				if (e) 
				{
					load(e);
				}
				
			}
			
			//tell the world that the settings have been saved
			dispatchEvent(new Event(SETTINGS_SAVED));
		}
		
		public function setKey(key:String, value:String):void
		{
			//break key into individual strings
			var children:Array = key.split('.');
			
			//variable to hold the node that corresponds to key
			var finalKey:XML = new XML();
			
			//using the array created by key.split to climb down the XML object
			for (var i:uint = 0; i < children.length; ++i)
			{
				if (i == 0)
				{
					//set an initial value for key the first time through
					finalKey = XML(workingCopy.child(children[i])[0]);
				}
				else
				{
					//on each additional pass, climb further into the XML
					//rebuilding key as an E4X path, ending on the final
					//node specified by key
					finalKey = XML(finalKey.child(children[i])[0]);
				}
			}
			
			//set the value attribute of the final XML object
			//to the value passed to the function
			finalKey.@value = value;
		}
		
		public function getKey(key:String):String
		{
			//break key into individual strings
			var children:Array = key.split('.');
			
			//variable to hold the node that corresponds to key
			var finalKey:XML;
			
			//using the array created by key.split to climb down the XML object
			for (var i:uint = 0; i < children.length; ++i)
			{
				if (i == 0)
				{
					//set an initial value for finalKey the first time through
					finalKey = XML(workingCopy.child(children[i])[0]);
				}
				else
				{
					//on each additional pass, climb further into the XML
					//rebuilding key as an E4X path, ending on the final
					//node specified by key
					finalKey = XML(finalKey.child(children[i])[0]);
				}
			}
			
			//after reaching key in the XML, store its value attribute in
			//a temporary variable
			var value:String = finalKey.@value;
			
			//return the variable
			return value;
		}
		
		// A backup plan or "undo" for reverting to the file's content
		// as it existed the last time it was loaded (either on open 
		// or directly after a save)
		public function revert():void
		{
			workingCopy = masterCopy.copy();
			//just in case
			save();
		}
	}
}

 

 

 

Please use plain text.