One Logo Pool Ball
wwwwwwwwwwwwwwwwwww

Background tasks

Schedule iOS app refresh and processing work through BGTaskScheduler.

One.BackgroundTasks schedules short refresh jobs and longer processing jobs. iOS decides when a submitted job runs. A submitted request is not a timer, and submitting the same identifier again replaces its pending request. Define every handler in the native setupFile, which loads when a background launch starts JavaScript without opening a window.

vite.config.ts
one({
setupFile: { native: './background-setup.ts' },
native: {
app: {
name: 'MyApp',
ios: {
bundleId: 'com.example.myapp',
backgroundTasks: {
refresh: ['com.example.myapp.refresh'],
processing: ['com.example.myapp.maintenance'],
},
},
},
},
})
background-setup.ts
import { One } from 'one'
One.BackgroundTasks.defineTask('com.example.myapp.refresh', async ({ signal }) => {
const response = await fetch('https://example.com/feed', { signal })
// persist the data your app needs on its next launch
await response.text()
})
One.BackgroundTasks.defineTask('com.example.myapp.maintenance', async ({ signal }) => {
// check signal during work so expiration stops it promptly
})

Submit work from foreground JavaScript after defining handlers:

const tasks = One.BackgroundTasks
await tasks.submit('com.example.myapp.refresh', {
earliestBeginDateMs: Date.now() + 15 * 60_000,
})
await tasks.submit('com.example.myapp.maintenance', {
requiresNetworkConnectivity: true,
requiresExternalPower: true,
})
const pending = await tasks.getPending()
tasks.cancel('com.example.myapp.refresh')

defineTask returns an idempotent remover. The handler runs once per system launch. Resolving it reports success; throwing or rejecting reports failure. When iOS expires a task, its signal aborts and One reports failure to the system. Schedule the next run yourself from the handler or foreground app if you need recurring work. A job whose JavaScript handler never registers is reported as failed after a startup timeout. Processing requirements apply only to processing jobs.

One prebuild stamps BGTaskSchedulerPermittedIdentifiers and the matching fetch or processing background mode. It requires an existing iOS native setupFile when tasks are declared. Unknown identifiers reject with E_BACKGROUND_TASK_INPUT; scheduler failures reject with E_BACKGROUND_TASK_SUBMIT. iOS may defer or decline execution according to system conditions and app usage. Apple’s Background Tasks guide explains scheduling policy.

On the iOS 27 simulator, BGTaskScheduler.submit reports that scheduling is unavailable. The simulator proof checks that error, pending queries, cancellation, input errors, and injected delivery to the setup handler with completion and expiration. Apple documents its debugger launch and expiration hooks as device-only. Actual OS cold launch, timing, and expiration still need a physical-device run.

Background scheduling is implemented on iOS. Android and web validate registrations and requests, return an empty pending list, and leave registration, submission, and cancellation without system effects.

Edit this page on GitHub.