Page 1 of 2

Custom Properties

Posted: Fri Jun 24, 2011 2:39 pm
by doobox
Hi there,

I have been reading everything i can find on Custom Properties in ios today.
I have seen the scenario using two stacks, and saving one as a data source.


I am still wondering after everything i have read.
Is the plain fact of the matter...
"you can not change the value of a custom property on ios, an expect that value to be still there after the app closes and re-starts. Unless you implement a workaround, as in the splash / data stack featured in this forum"



Kind Regards
Gary

Re: Custom Properties

Posted: Fri Jun 24, 2011 6:42 pm
by FourthWorld
Operating systems do not allow an executable to modify itself, so changing the properties in an object residing in the mainstack which is the standalone will not preserve those changes across sessions.

But as you noted, using a separate stack file for saving properties should be fine.

Re: Custom Properties

Posted: Fri Jun 24, 2011 6:53 pm
by doobox
That has confused me.

when i test this in a standalone mac app:

Code: Select all

set customproperty of this stack to "hello"
I can quit the app and restart it, and do:

Code: Select all

put the customproperty of this stack into field "test"
And this outputs "hello"
Not the case in an ios standalone.

How am i seeing the persistence of the custom property in a standalone mac app..?
When i started with the platform, i thought i had interpreted from the docs that custom property's were an easy option to store user data (ftp details for example).
Maybe i am getting mixed up with real code, an option i looked at before settling on Live code.



Kind regards Gary.

Re: Custom Properties

Posted: Fri Jun 24, 2011 7:21 pm
by doobox
We need something like this, from the Nimblekit platform.
That allows saving key value pairs, the the actual iPhone settings, the can also be accessed from the settings app in the phone if done right.

Basically the way nk handles the code is in the format:

Code: Select all

//In this example we use NKSettings class 
//to save/retrieve username from application settings.
var settings = new NKSettings();
settings.setValueForKey("UserName", "user");
var username = settings.getValueForKey("user");
Kind regards
Gary

Re: Custom Properties

Posted: Fri Jun 24, 2011 9:02 pm
by FourthWorld
I believe "customProperty" is a keyword so I'm surprised it works on any system.

Try using a unique name, like "uMyProperty", and make sure you're setting the property in a stack which isn't the standalone.

Re: Custom Properties

Posted: Fri Jun 24, 2011 11:17 pm
by doobox
Hi there,

Your right about the key word, I just wrote that off the cuff to be visual without realizing.
You are also right about custom properties not being persistent after a session is closed, when created on the standalone stack (god knows what i was doing before to make me think they were in osx)

That said i cant tell you how disappointed i am at discovering this limitation.
The splash and data stack demo, while being one solution. Seems a bit around the houses to me.
I also don't like the limitations. Having to replace all the data for any change to the stack.

What are the best alternatives.
I am thinking write the custom props to file on exit.
sQlite.

What does everyone do to handle small amounts of data, like usernames, ftp details etc.. Where the data needs to be stored and retrieved between sessions..?
Is the second stack really the best option, to save the data..?

Re: Custom Properties

Posted: Sat Jun 25, 2011 12:20 am
by ctflatt
I just completed an app that writes data to a text file in the documents folder onCloseStack.

It holds three specific pieces of data:

userName
weight
totalCalories

I know which line in the text holds which piece of data, so in a preOpenCard script I check to see if the text file exists. If it does, I retrieve line 1 and set the value of a field to it. I repeat this for each item, as needed.

In the closing script, these three values are written back out to the file, each on it's appropriate line.

HTH.

:Todd

Re: Custom Properties

Posted: Sat Jun 25, 2011 12:34 am
by doobox
Hey Todd,

Thank you,
I think this will be the way i will go with the limited data i need to stor between sessions for the app i am currently building.

I just posted in feature requests for the addition of, a method of storing key value pairs via the iPhones default settings. NSUserDefaults.

I think this would be a huge leap forward for making small apps for the iphone.

Kind Regards
Gary

Re: Custom Properties

Posted: Sat Jun 25, 2011 1:22 am
by FourthWorld
doobox wrote:That said i cant tell you how disappointed i am at discovering this limitation.
The splash and data stack demo, while being one solution. Seems a bit around the houses to me.
I also don't like the limitations. Having to replace all the data for any change to the stack.
This is not a limitation of LiveCode. This is how all OSes are designed, to prevent an app from modifying itself.

All apps store data externally from the application. You can do this with LiveCode too, using text files or binary files of a format of your own design if you choose. In fact, moving arrays from memory to disk and back again with arrayDecode and arrayEncode make this a snap.

But with LiveCode it's even easier than with most other dev systems: you can also use stack files for data storage.

A stack file can have any number of substacks, and only one stackfile will be the executable. You can create other stack files for data storage, and just set their filename property to the appropriate storage location and use the save command and you're done.

Many, many options for storing data in apps made with LiveCode, often easier to work with than anything else around.

Re: Custom Properties

Posted: Sat Jun 25, 2011 2:39 am
by doobox
Hi there,
I appreciate you giving more detail on the subject.
When i don't know all my options, i am terrified i am missing something easier :-)

I was just spoiled i guess, with the system NimbleKit has in place for saving persistent key value pairs.

Code: Select all

//In this example we use NKSettings class 
//to save/retrieve username from application settings.
var settings = new NKSettings();
settings.setValueForKey("UserName", "user");
var username = settings.getValueForKey("user");
While NK is lacking in many areas, that was a great part of the tool kit.
worked exactly like custom props but saved.

The way you are describing using a second stack to store data..?
Is this the same method as the splash and data featured here: http://forums.runrev.com/phpBB2/viewtop ... for+iPhone

Where the data stack is saved to the documents folder..?

Re: Custom Properties

Posted: Sat Jun 25, 2011 2:55 am
by doobox
A stack file can have any number of substacks, and only one stackfile will be the executable. You can create other stack files for data storage, and just set their filename property to the appropriate storage location and use the save command and you're done.
Just been messing with this, but i dont quite know what you mean by:
just set their filename property to the appropriate storage location and use the save command

Re: Custom Properties

Posted: Sat Jun 25, 2011 3:51 am
by jacque
The reason all apps save preference files is because they can't alter themselves. Your app has to do the same thing.

LiveCode provides a built-in way to get the default preferences folder for each OS, and that's where you should probably save them. You get a file name (which is a location on disk) like this:

Code: Select all

put specialFolderPath("preferences") into tFilePath
That variable now contains a file path to the folder. You need to add the name of your file to the end of it, as well as the slash:

Code: Select all

put tFilePath & "/myprefs.txt" into tFilePath -- now you have a full path to your file
Your stack should create a new stack, set is filename property to tFilePath (the variable you just created) and then save itself. Now you have a prefs file saved to disk. It is also still open in RAM. Most people set the stack's visible property to false so that it can't be seen; that way it doesn't matter what it looks like. Mine are always blank default stacks.

Now you can do what you want with key/value pairs. It's already built-in. You do it by setting custom properties of your prefs stack. For now, the easiest way is to use one property per key, which will hold one value. Like this:

Code: Select all

set the username of stack tFilePath to "user"
set the settings of stack tFilePath to "1,2,3,4,5"
Save the stack before closing it, or you'll lose the values. When you want to read the values, open the stack if it isn't already and:

Code: Select all

put the username of stack tFilePath into userVar
 put the settings of stack tFilePath into tSettingsList
You can also store key/value pairs as a string the way web URLs do it. That's not as straightforward but it's still pretty easy. You use the combine and split commands to work with these. For now, I'd start with the above until you get comfortable with custom properties.

Re: Custom Properties

Posted: Sat Jun 25, 2011 11:40 am
by doobox
I really appreciate your time, elaborating on this.

I have followed your instructions to the best of my ability. And this is what i have:

I am afraid i must be missing a key point here, as this is not working for me.
I have spent so much time trying to get this basic function, sorted.

Re: Custom Properties

Posted: Sat Jun 25, 2011 3:21 pm
by doobox
I am so near i can smell it.. :-)

I believe the stack is not receiving the shutdown message for some reason,
The saved copy of the data stack never gets the custom props written back to it..?

Code: Select all

on openStack
   put specialFolderPath("preferences") into tFilePath
   put tFilePath & "/myprefs.livecode" into tFilePath
   
   if not (there is a file tFilePath) then
      create stack tFilePath
      set the filename of stack tFilePath to tFilePath
      save stack tFilePath 
      --hide newstack
   else
      go stack tFilePath
      --save  stack tFilePath
      --hide stack tFilePath
      --go this stack
   end if
   
   set the username of stack tFilePath to "user"
   set the settings of stack tFilePath to "1,2,3,4,5"
   
   wait 3 seconds
   put empty into field "result"
   wait 3 seconds
   put the username of stack tFilePath into field "result"
   wait 2 seconds
   put the settings of stack tFilePath after field "result"
end openStack


on shutdown
  save stack tFilePath
  pass shutdown
end shutdown

Re: Custom Properties

Posted: Sat Jun 25, 2011 6:57 pm
by jacque
doobox wrote:I am so near i can smell it.. :-)

I believe the stack is not receiving the shutdown message for some reason,
The saved copy of the data stack never gets the custom props written back to it..?
Yes, you're very close. The reason it isn't saving is because tFilePath has no value in the shutdown handler; you haven't assigned one. Variables don't retain their values between handlers unless you specify them as script locals (or globals, but you don't need that here.)

To fix the problem, you need to declare a script local variable at the top of your script, not inside any handler. You can do this by placing this at the top of your script:

local tFilePath

Your openstack handler can remain the same, it will fill the variable with a value, and because the variable has been declared as a script local, it will be availalbe to every handler in the script. Then your shutdown handler will know what file you mean.