Parental Control
Creating Parental Control
The tutorial discusses the 3 most common scenarios for parental control
With the changes in the Children’s Online Privacy Protection Act, or COPPA, no app targeting children can offer these things
- access to external content (including websites, reviews and ratings, “Like Us” on Facebook, etc),
- to collect user information or allow in-app purchase, without validating the current user is an adult.
Although extremely important, these requirements adds complexities to any developer willing to promote theirs services to parents of your users. In order to address the need of communication inside the app, parental controls or gates are now necessary, to avoid kids getting access to adult content.
Moms With Apps website wrote a extensive posting with examples from different studios. We strongly recommend the full reading, not only for learning more, but also for some ideas of how to implement your own gates with Kwik.
- http://blog.momswithapps.com/2013/08/20/how-are-kids-app-developers-communicating-to-parents/
- http://www.iubenda.com/blog/guide-coppa-mobile-apps/
- https://www.ftc.gov/tips-advice/business-center/privacy-and-security/children%27s-privacy
- https://en.wikipedia.org/wiki/Child_Online_Protection_Act
As you will read there, no parental control is child proof, especially when targeting children who can read and perform simple math. Nevertheless, without any of them your app will not be approved by the major stores, even if you only added a link to the app website.
Accessing content via gesture
The idea of this gate is to capture a “non-common” gesture before sending the parent to the adult page (in most cases this “adult page” is a page with information about the company behind the app, rating access, links to Facebook and Twitter, and so on).
Justin’s World (as well as Nosy Crow) uses this option:

While gestures in Kwik are very common and easy to access, via the Interactions Toolbox, they require a single finger (only mandatory exception is the Pinch, which naturally requires two fingers to work) to perform. Having a regular swipe (or drag) in the example above would not make any sense because any child would be able to, by try and error, swipe in any direction with his/her small finger.
So, how to enable mandatory gesture with more than one finger in Kwik?
- Drag can be changed to require multi finger and when the draggin is completed, fire the action to unlock the parent control.
- you need to manually edit the lua file of dragging, you can find it in /components/pageXXX/layer_drag.lua. Change single to multi
Before
function _M:allListeners(UI)
...
_K.MultiTouch.activate( dragLayer, "move", "single", {} )
...
end
After
function _M:allListeners(UI)
...
_K.MultiTouch.activate( dragLayer, "move", "multi", {} )
...
end
Swipe does not support multi finger
Accessing content via question and answer
This approach is pretty common. A question is presented and, depending on users answer, the gate is unlocked. Some uses multiple choices for answer entry, while others prefer the direct input mode.
77Sparx asks if you are an adult, and verifies with a math equation.

If you plan to use a multiple choice, take a look at our Creating a Quiz tutorial, as the basis is the same. If you plan the direct input approach, the video below may offer some guidance:

Accessing content via timed gesture
This is becoming more common now. Basically you need to press a button, or swipe an image, for a pre-determined amount of time. For example, “press the button for 5 seconds”. The team from Rocket Gamelabs was the first to implement this approach using Kwik.

As you may imagine, this requires more planning and some external code.
- Variables
- timed as number
- message as formula
- Button press
- timed = 0
- Timer every 1 second
External codes for Action
- timed_action.lua
print(layer.timedBtn.type) if layer.timedBtn.type == "press" then _K.timed = 0 _K.timerStash.timedGestureTimer = timer.performWithDelay(1000, function () if _K.timed == 5 or _K.message == "Released" then _K.message = "Released" else _K.timed = _K.timed + 1 _K.message = _K.timed .."s" end print(_K.message) end, 6) else -- release print("release", _K.message) if _K.message == "Released" then print("Fired") UI.scene:dispatchEvent({name="action_act_timed"}) else _K.timed = 0 _K.message = _K.timed .."s" end timer.cancel(_K.timerStash.timedGestureTimer) _K.timerStash.timedGestureTimer = nil end
Edit button lua for adding onRelease = onTimeBtnEventRelease
components/page01/timedBtn_button_but_timed.lua
-
Before
function _M:buttonLocal(UI) local sceneGroup = UI.scene.view local layer = UI.layer local function ontimedBtnEvent(self) if layer.timedBtn.enabled == nil or layer.timedBtn.enabled then layer.timedBtn.type = "press" UI.scene:dispatchEvent({name="timedBtn_button_but_timed", layer=layer.timedBtn }) end end layer.timedBtn = widget.newButton { id = "timedBtn", defaultFile = _K.imgDir..imagePath, overFile = _K.imgDir.."p1/timedover.png", width = imageWidth, height = imageHeight, onRelease = ontimedBtnEvent } ... end
-
After
function _M:buttonLocal(UI) local sceneGroup = UI.scene.view local layer = UI.layer local function ontimedBtnEvent(self) if layer.timedBtn.enabled == nil or layer.timedBtn.enabled then layer.timedBtn.type = "press" UI.scene:dispatchEvent({name="timedBtn_button_but_timed", layer=layer.timedBtn }) end end -- local function ontimedBtnEventRelease(self) if layer.timedBtn.enabled == nil or layer.timedBtn.enabled then layer.timedBtn.type = "release" -- but_timed(layer.timedBtn) UI.scene:dispatchEvent({name="timedBtn_button_but_timed", layer=layer.timedBtn }) end end -- layer.timedBtn = widget.newButton { id = "timedBtn", defaultFile = _K.imgDir..imagePath, overFile = _K.imgDir.."p1/timedover.png", width = imageWidth, height = imageHeight, onPress = ontimedBtnEvent, onRelease = ontimedBtnEventRelease } ... end
Enjoy!