Alloy apps can communicate with the internet by proxying network requests through PebbleKit JS (PKJS) running on the phone.
Alloy apps have two JavaScript environments:
| Location | File Path | Runs On | Purpose |
|---|---|---|---|
| embeddedjs | src/embeddedjs/main.js |
Watch | Your app UI and logic |
| PKJS | src/pkjs/index.js |
Phone | Network proxy, location, config |
Code examples in this guide are labeled with 📱 PKJS or ⌚ Watch to indicate where they run.
To use fetch() or WebSocket on the watch, install the
@moddable/pebbleproxy package:
$ pebble package install @moddable/pebbleproxy
Then set up your src/pkjs/index.js:
📱 PKJS (src/pkjs/index.js):
const moddableProxy = require("@moddable/pebbleproxy");
Pebble.addEventListener('ready', moddableProxy.readyReceived);
Pebble.addEventListener('appmessage', moddableProxy.appMessageReceived);
If your app also needs to handle its own events, call the proxy functions from your handlers:
const moddableProxy = require("@moddable/pebbleproxy");
Pebble.addEventListener('ready', function(e) {
moddableProxy.readyReceived(e);
// Handle your own ready event here
});
Pebble.addEventListener('appmessage', function(e) {
if (moddableProxy.appMessageReceived(e))
return;
// Handle your own app messages here
});
Once the proxy is set up, use fetch() in your watch code:
⌚ Watch (src/embeddedjs/main.js):
async function fetchData() {
const url = new URL("http://api.open-meteo.com/v1/forecast");
url.search = new URLSearchParams({
latitude: 37.7749,
longitude: -122.4194,
current: "temperature_2m"
});
const response = await fetch(url);
const data = await response.json();
console.log("Temperature: " + data.current.temperature_2m);
}
watch.addEventListener("connected", ...) before
calling fetch() or opening a WebSocket| Method | Description |
|---|---|
response.json() |
Parse response as JSON |
response.text() |
Get response as string |
response.ok |
Boolean: true if status 200-299 |
response.status |
HTTP status code |
WebSockets are also handled by the @moddable/pebbleproxy package - no
additional proxy setup needed.
⌚ Watch (src/embeddedjs/main.js):
const ws = new WebSocket("ws://websockets.chilkat.io/wsChilkatEcho.ashx");
ws.binaryType = "arraybuffer";
ws.addEventListener("open", event => {
console.log("WebSocket connected");
ws.send("Hello from Pebble!");
ws.send(Uint8Array.of(0, 1, 2, 3, 4, 5));
});
ws.addEventListener("message", event => {
let data = event.data;
if (data instanceof ArrayBuffer) {
console.log("Received binary data");
data = new Uint8Array(data);
} else {
console.log("Received: " + data);
if (data === "Goodbye") ws.close(1000, "Done");
}
});
ws.addEventListener("close", event => {
console.log("Closed: " + event.code + " " + event.reason);
});
Check if the phone is connected from watch code:
⌚ Watch (src/embeddedjs/main.js):
function logConnected() {
console.log("App connected: " + watch.connected.app);
console.log("PebbleKitJS connected: " + watch.connected.pebblekit);
}
watch.addEventListener('connected', logConnected);
logConnected();
Network requests only work once the proxy is ready. Wait until
watch.connected.pebblekit is true before calling fetch() or opening a
WebSocket.
@moddable/pebbleproxy - required for fetch() and WebSocketconnected event or check watch.connected.pebblekitlocalStorage to reduce requestsFor more control over HTTP and WebSocket connections, Alloy also provides low-level ECMA-419 networking APIs:
HTTPClient - streaming HTTP client with fine-grained header controlWebSocketClient - low-level WebSocket with callback-based API, provides streaming supportThese are also handled by @moddable/pebbleproxy. See the
Advanced Networking guide for details.
The Pebble Examples repository includes networking examples:
hellofetch - HTTP requests using the fetch() APIhellowebsocket - WebSocket connections using the WebSocket API