Measurement Sync (iOS)¶
Measurement sync automatically uploads finished test results to the Surfmeter server so they appear in the Surfmeter Dashboard. The SDK queues each completed measurement and sends it in the background. The queue is stored on disk, so measurements survive app restarts and are retried after network failures.
See Measurement Sync (Android) for the corresponding Android behavior and APIs.
Setup¶
There is no queue-specific setup. Register the device before running a test, and create a Registry with the same API endpoint whenever the app starts. The registry configures the shared queue as soon as the device has credentials. Every finished test then hands its report to the queue automatically. Your result listener still receives the same report.
Authentication is handled inside ClientApi. It fetches a token when needed and keeps it for as long as the server says it is valid. Your app does not need to manage authentication tokens for measurement sync.
Timing¶
A measurement is queued as soon as its test finishes, and the queue tries to upload it immediately. Uploads pause while any quality test is running so the queue's network traffic does not distort the measurement. The SDK manages this lifecycle for its own tests.
If two tests run at once, sending waits for both to finish. A failed upload is retried every 60 seconds while the app is running. Anything still queued when the app closes is sent the next time a Registry is created for the registered device.
Unlike Android's WorkManager-based queue, iOS can upload measurements only while the app is running.
Queue Status and Manual Sync¶
You can read the pending count and trigger a sync attempt, for example when your app returns to the foreground:
// Get the number of pending measurements
let pending = MeasurementQueue.shared.getPendingCount()
// Try to send them now and handle the outcome
MeasurementQueue.shared.sendPendingMeasurements { result in
switch result {
case .success(let sentCount):
print("Sent \(sentCount) queued measurements")
case .failure(let error):
print("Upload failed: \(error.localizedDescription)")
}
}
The completion handler runs on the main queue after every measurement that was pending at call time has succeeded or failed once. It includes files that were already being uploaded without sending them twice. A failed upload stays queued for automatic retry.
The completion reports an error if a test is running or if Registry has not configured a server. Use the overload without a completion handler only when the app does not need the result of the attempt.
The iOS SDK does not expose a persistent status property equivalent to Android's isSending() and has no reset operation for measurements left in an intermediate state.
Upload Notifications¶
iOS does not broadcast the outcome of automatic uploads. Use the completion handler above for a manual sync attempt. For automatic uploads, inspect the MeasurementQueue log category as described under Logging.
Retries¶
The iOS queue retries failed uploads every 60 seconds while the app is running. A failed measurement stays queued without a fixed retry limit. Uploads resume the next time the app starts and creates a Registry for the registered device.
If the device loses its registration, the queue is cleared instead of retrying under credentials that are no longer valid.
Custom Measurements¶
If you run another measurement and want to prevent uploads from interfering with it, bracket that work with matching calls:
MeasurementQueue.shared.onTestStarted()
// ... run your own measurement ...
MeasurementQueue.shared.onTestFinished()
Every onTestStarted() call needs a matching onTestFinished() call. Otherwise, the queue keeps waiting and stops sending.
You can also add a compatible report to the queue yourself:
Storage and Limits¶
Pending measurements are stored as JSON files under Application Support/SurfmeterQualitySDK/queue in your app's container. A measurement is removed as soon as the server accepts it.
The queue keeps at most 50 measurements. When a new measurement exceeds that limit, the oldest measurement is dropped. The files are included in app backups, and deleting the app discards the queue.
When Registration Is Lost¶
A measurement is uploaded under the identity of the device that took it, so the queue is cleared when that identity is removed. This happens when your app calls clearRegistrationInfo() or when the server no longer accepts the device because it was disabled, its usage window expired, or its credentials are invalid.
Nothing is uploaded after that, and no further test can be built. If your app shows the pending count, expect it to drop to zero. See Disabled Devices.