Measurement Sync (iOS)¶
Measurement sync uploads test results to the Surfmeter server, so that measurements taken in your app show up in the Surfmeter Dashboard. The SDK queues each finished measurement and sends it in the background, retrying when the network is not available.
There is nothing to switch on. Sync follows from registration, which is required anyway before a test can run. See the Android page for how the same feature works there.
Setting It Up¶
Register the device, once, at startup. That is all:
import SurfmeterQualitySDK
let registry = Registry(apiEndpoint: "https://your-server.aveq.info/client_api/v1")
if !registry.isRegistrationValid() {
registry.registerClient(registrationKey: "REPLACE_WITH_YOUR_REGISTRATION_KEY") { result in
DispatchQueue.main.async {
switch result {
case .success:
print("Ready to measure")
case .failure(let error):
print("Registration failed: \(error.localizedDescription)")
}
}
}
}
From then on every test that finishes hands its report to the queue by itself, and the queue sends it. Your result listener still receives the same report as before, so nothing about the rest of your code changes.
Authentication is handled inside ClientApi. It fetches a token when it needs one and keeps it for as long as the server said it is good for, so there is no token handling on your side.
What Happens When¶
A measurement is queued the moment its test finishes, and the queue tries to send it right away. While a test is running the queue holds back, so its own network traffic does not distort the measurement. This applies across tests: if two run at once, sending waits for the last one to finish.
If a send fails, for example because the device is offline, the measurement stays on disk and the queue retries every 60 seconds until it gets through. Anything still queued when the app is closed is sent the next time a Registry is created on a registered device, which is to say the next time your app starts.
At most 50 measurements are kept. When a new one would go past that, the oldest are dropped.
Queue Status¶
To show what is going on, or to trigger a send when your app comes back to the foreground:
// How many measurements are still waiting
let pending = MeasurementQueue.shared.getPendingCount()
// Try to send them now
MeasurementQueue.shared.sendPendingMeasurements()
sendPendingMeasurements() does nothing while a test is running, or while there is no server to send to.
Measurements of Your Own¶
If you run measurements outside the SDK and want the queue to stay quiet during them, bracket them the way the tests do. Every onTestStarted() needs a matching onTestFinished(), otherwise the queue keeps waiting and stops sending:
MeasurementQueue.shared.onTestStarted()
// ... your own measurement ...
MeasurementQueue.shared.onTestFinished()
You can also hand the queue a report yourself, which is what the tests do internally:
Where the Queue Lives¶
Pending measurements are written as JSON files under Application Support/SurfmeterQualitySDK/queue in your app's container. They are removed as soon as the server has accepted them.
This means the queue is part of your app's data: it is included in backups, and deleting the app discards anything that had not been sent.
Differences from Android¶
The iOS queue covers the same ground, with a few things the Android SDK has that are not there yet:
- No broadcast when a measurement was sent or has failed for good. Watch the
MeasurementQueuelog category instead, as described under logging. - No way to ask whether a send is in progress, and no way to reset measurements that got stuck.
- Sending only happens while the app is running. Android hands the work to
WorkManager, which can finish an upload after the app is gone.
If you need any of these, please get in touch at support@aveq.info.