Perform basic operations in application state

Before you can interact with application state, you must wait until it has been initialized. There are various ways to check that state is ready, which we'll cover in this section.

Once state is ready, you can interact with it through read/write operations. This section describes how to perform basic operations directly to application state; a common use case for this is to load initial values at startup.

For more complex interactions, see the sections about using change handlers and performing batch changes.

Steps

Confirm that state initialization is complete

Application state is automatically initialized when you create a new StateManager object in the service application. You will already have done this step; see Initialize the State Manager.

You cannot interact with application state until this initialization is complete. To tell whether application state is ready, you can either listen for the state initialized event, or query for the initialization status.

Listening to the event

On the service, the initialization event can be found in the StateManager class:

C++

stateManager->Initialized() += Bind(this, &MyApp::OnStateInitialized);

void MyApp::OnStateInitialized(StateManager& stateManager, EmptyEventArgs&)
{
    // Interact with application state
}				

.Net

stateManager.Initialized += new EventHandler(OnStateInitialized);

private void OnStateInitialized(object sender, EventArgs args)
{
    // Interact with application state
}

Java

stateManager.addInitializedHandler(new OnStateInitialized());

private class OnStateInitialized implements EventHandler<EmptyArgs>
{
    public void invoke(Object sender, EmptyArgs args)
    {
        // Interact with application state
    }
}

On the client, the initialization event can be found in the Framework class:

HTML5

pureweb.client.listen(pureweb.client.getClient(), pureweb.client.Framework.EventType.IS_STATE_INITIALIZED, function(){
    //Interact with application state
});

iOS (Obj-C)

[[PWFramework sharedInstance].isStateInitializedChanged addSubscriber:self action:@selector(stateInitialized)];

- (void)stateInitialized
{
    // Interact with application state
}

Android

framework.addIsStateInitializedHandler(new OnStateInitialized());

private class OnStateInitialized implements EventHandler<EmptyArgs> {
    public void invoke(Object source, EmptyArgs args) {
        // Interact with application state
    }
}

Querying for status

APIs:

Framework.isStateInitialized | HTML5 | Android
PWFramework.isStateInitialized | iOS

On clients, an alternative to listening to the initialization event is to use the isStateInitialized method, which returns a boolean value that indicates whether application state is initialized and ready for interactions.

HTML5

if (pureweb.client.framework.isStateInitialized()){
    //Interact with application state
}

iOS (Obj-C)

if ([[PWFramework sharedInstance] isStateInitialized]) {
    //Interact with application state
}

Android

if (framework.isStateInitialized())
{
    //Interact with application state
}


Write a value to a property

APIs:

TypelessStateManager.SetValue() | C++
XmlStateManager.SetValue() | .Net | Java | HTML5 | Android
PWXmlStateManager.setValue() | iOS

To write to application state, you call setValue, which simply requires the path of the property to set (see path notation), and the value to assign to the property.

Although setValue usually accepts values of different types such as strings, booleans and numbers (the only exception is Objective-C, where setValue only accepts strings), you should be aware that those values get converted to strings under the hood.

On the service

C++

MyApp::StateManager().TypelessStateManager().SetValue("/path", "value");

In C++, you may notice the setValueAs method, which allows you to specify a data type other than string. This is a legacy method, and we encourage you to use setValue instead. Not much would be gained by explicitly stating the type when writing the value, since you will still need to specify the type (if other than string) when you retrieve it.

.Net

Program.StateManager.XmlStateManager.SetValue("/path", "value");

Java

stateManager.getXmlStateManager().setValue("/path", "value");

On the client

HTML5

pureweb.getFramework().getState().setValue('/path', 'value');

iOS (Obj-C)

[[PWFramework sharedInstance].state setValue:@"/path" value:@"value"];

In Objective-C, the setValue method only accepts strings, so you must convert the value to a string before storing it in application state.

You can also use the setAppStatePathWithValue method to update an existing element with the provided value.

Android

framework.getState().setValue("/path", "value");

The value argument of setValue could be a call to another function, instead of the value itself. In this case, it will be necessary for that function to run and return its value before that value can be set in application state. This approach requires the use of a state lock.

It is also possible to set the value for several elements in a single operation using a method called setTree; see the section about performing batch changes.


Read a previously set value

APIs:

TypelessStateManager.GetValue() | C++
XmlStateManager.getValue() | .Net | Java | HTML5 | Android
PWXmlStateManager.getValue() | iOS

Reading values is very similar to writing them, with the exception that you only need to provide the path.

In most APIs, you can use getValue to retrieve the value as a string, or getValueAs to retrieve it as a different data type, as shown in the snippets below.

It is also possible to get an entire subsection of the application state tree in a single operation using a method called getTree. See the section about batch changes.

On the service:

C++

// To retrieve a value as a string
MyApp::StateManager().TypelessStateManager().GetValue("/path");

// To retrieve a value as an integer
MyApp::StateManager().TypelessStateManager().GetValueAs<int>("/path");

.Net

// To retrieve a value as a string
Program.StateManager.XmlStateManager.GetValue("/path");

// To retrieve a value as an integer
Program.StateManager.XmlStateManager.GetValueAs<int>("/path");

Java

// To retrieve a value as a string
stateManager.getXmlStateManager().getValue("/path");

// To retrieve a value as an integer
stateManager.getXmlStateManager().getValueAs(Integer.class, "/path");

On the client:

  In the JavaScript and Objective-C APIs, getValue always returns a string. Functions that need to manipulate the value must convert it to the needed format after retrieving it.

HTML5

// The value is always returned as a string
pureweb.getFramework().getState().getValue('/path');

iOS (Obj-C)

// The value is always returned as a string
[[PWFramework sharedInstance].state getValue:@"/path"];

In iOS, you can also use getValueWithAppStatePath to accomplish the same thing.

Android

// To retrieve a value as a string
framework.getState().getValue("/path");

// To retrieve a value as an integer
framework.getState().getValueAs(Integer.class, "/path");

Example

Loading the default pen color in Scribble

In this example, we set "red" as the default Scribble pen color at startup. We achieve this by listening for the state initialization event, and creating an event handler which writes to the ScribbleColor property in application state.

HTML5

Listen for the state initialization event:

pureweb.listen(framework, pureweb.client.Framework.EventType.IS_STATE_INITIALIZED, onIsStateInitializedChanged);

Define the event handler to assign the value red to the ScribbleColor property in application state.

function onIsStateInitializedChanged(e) {
    pureweb.getFramework().getState().setValue('/ScribbleColor', 'red');
}

iOS (Obj-C)

Listen for the state initialization event:

[[PWFramework sharedInstance].isStateInitializedChanged addSubscriber:self action:@selector(stateInitialized)];

Define the event handler to assign the value red to the ScribbleColor property in application state:

- (void)stateInitialized
{
    [[PWFramework sharedInstance].state setValue:@"/ScribbleColor" value:@"red"];
}

Android

Add a state initialization event handler, and handle the event by assigning the value red to the ScribbleColor property in application state:

framework.addIsStateInitializedHandler(new EventHandler<EmptyArgs>() {
    @Override
    public void invoke(Object source, EmptyArgs args) {
        framework.getState().setValue("/ScribbleColor", "red");
    }
});