Rootless

Automate iOS, iPadOS, and macOS using plain JavaScript. Build custom widgets and interact directly with native APIs.

Download on the App Store
Rootless app interface

Plain JavaScript

Supports ES6. Scripts are stored as plain .js files on your disk.

Native APIs & Documentation

Integrate directly with iOS native APIs. Fully documented, available offline.

Siri Shortcuts

Trigger scripts via Siri. Present tables, websites, and custom HTML natively.

System Integration

Run from the Share Sheet, process inputs, and manage local files via Files.app.

x-callback-url

Communicate seamlessly and trigger workflows with other apps on your device.

Customizable & Ready

Tailor the code editor to your liking. Includes several example scripts to start immediately.

Documentation

Also inside the app, or as rootless.json.

Motion

Sensors, steps and activity

Everything CoreMotion reports. Each sensor is read once per call: the reading starts, the first sample comes back, the sensor stops. A script cannot subscribe to a stream, because a script runs to its last line and is then serialised, with no event loop left to receive a second sample. Ask for a series by sampling in a loop. Units are CoreMotion's own: g for acceleration, radians per second for rotation, microtesla for the magnetic field, radians for attitude, kilopascals for pressure. Nothing here answers on the simulator, and history reaches back seven days. Check Motion.isAvailable before reading a sensor that the device may not have.

Properties

isAvailableobject

Which sensors this device has: { accelerometer, gyroscope, magnetometer, attitude, barometer, steps, activity }.

Methods

Motion.accelerometer()Any

Acceleration on the three axes, in g, gravity included.

returns { x, y, z } in g.

Motion.gyroscope()Any

Rotation rate on the three axes, in radians per second.

returns { x, y, z } in rad/s.

Motion.magnetometer()Any

The magnetic field on the three axes, in microtesla. Raw, so it includes whatever the device itself is generating.

returns { x, y, z } in µT.

Motion.attitude()Any

The fused reading: where the device is pointing, with gravity told apart from the acceleration you caused.

returns { pitch, roll, yaw } in radians, plus gravity and userAcceleration as { x, y, z } in g, rotationRate in rad/s, and heading in degrees from magnetic north when the compass has settled. heading is absent while it has not.

Motion.pressure()Any

The barometer.

returns { kPa, relativeAltitude }. relativeAltitude is metres climbed since the reading began, so on a single sample it is near zero.

Motion.steps(from?, to?)Any

Steps over a window. With no arguments, since midnight; Motion.steps(DateTime.today()) is the same call written out. Anything older than seven days is clamped to seven days ago, which is all CoreMotion keeps.

  • from Any
  • to Any

returns { steps, distance, floorsAscended, floorsDescended, averageActivePace, from, to }. distance is a Distance, averageActivePace is seconds per metre and is absent when the window holds no movement, from and to are epoch seconds.

Motion.activity(from?, to?)Any

What the device was doing over a window, as a list of spans. With no arguments, since midnight.

  • from Any
  • to Any

returns [{ kind, confidence, start, end }]. kind is stationary, walking, running, cycling or automotive; confidence is low, medium or high; start and end are epoch seconds. CoreMotion records a change rather than a span, so each entry runs until the next one begins and the last runs to the end of the window.

Motion.activityTotals(from?, to?)Any

How long was spent doing what over a window. With no arguments, since midnight.

  • from Any
  • to Any

returns { stationary, walking, running, cycling, automotive }, each a Duration. A kind the window holds none of is absent.

Examples

How level the device is

var a = Motion.attitude();
var degrees = a.roll * 180 / Math.PI;