You may have noticed that some apps on your hub use a parent/child structure. In the Apps page on the hub, child apps appear nested under the parent app. For example, Rule Machine rules are all child apps of the parent Rule Machine app.
There are various reasons a developer may choose to use parent/child apps. To name a few possibilities, a parent/child relationship may be used:
In the first case, the parent app does little more besides allow the user to create new instances of a child app. In other cases, the parent or child app may may have methods that can be called from the child or parent apps to read or share information.
Parent apps may have more than one child app. Child apps can have only one parent. Parent apps may offer multiple apps (app names) as child apps. Most commonly, parent apps offer a single type of child app and allow multiple instances of this child app to be created, as we demonstrate below.
Parent and child apps are each complete sets of app code. Both must be installed in Apps Code. Add or create the parent app code first to avoid an error message that will prevent you from adding the child app code (as it will look for matching parent app code upon saving).
In the definition
of your child app code, specify a parent
parameter with a value in "namespace:name"
format, where namespace
and name
are those specified in the corresponding parent app code definition
.
For example:
definition(
name: "My Child App",
namespace: "MyNamespace",
parent: "MyNamespace:My Parent App",
// ...
)
In this case, the parent app code may look like:
definition(
name: "My Parent App",
namespace: "MyNamespace",
// ...
)
Typically, a parent app will display a list of child apps and allow the user to create new child apps. An easy way to do this is by using an alternative to input
named app
, which will show a list of matching child apps (each a link into that child app) as well as an option to create a new child app. For example, in the parent app:
preferences {
// ...
app name: "myChildApps", appName: "My Child App", namespace: "My Namespace",
title: "Create New Child App...", multiple: true
}
If necessary, parent and child apps can call methods on each other.
To get a list of all child apps in the parent app, call getChildApps()
.
If you have multiple app names (per metadata, not user-supplied app "labels"), you may also use findChildByAppName("Child App Name")
to find only specific types of child apps.
Example:
// run myMethod() in all child apps from parent:
getChildApps().each { it.myMethod("myParameter") }
Each child app has a parent
object, an InstalledApp object that refers to the parent app. For example, to call exampleMethod()
on the parent app (which must be a method defined in the parent app), use:
// run exampleMethod() in parent app from child app:
parent.exampleMethod()
Often, you want to allow multiple child apps but only one parent app. To do this, remember that you can use singleInstance: true
in the parent app metadata (and multiple: true
on the app
input, as above, to allow multiple children).
Note that app installs are not completed until the user selects the Install button (located where the Done button otherwise normally is). Installing an app places the app in the user's Apps list. If you want to avoid the user needing to select Install to complete installation of your parent app (or child app, but the parent can be particularly problematic due to the amount of setup the user may lose if they fail to realize it was not actually installed), recall that you can specify installOnOpen: true
in the app metadata.
Apps can have more than one level of parent/child nesting (e.g., the built-in Button Controllers app uses "grandchild apps" for each of the actual button rules in the set). However, this is typically discouraged.
You cannot directly access state
or atomicState
of a parent from a child app or vice versa.