Skip to content

Installation (iOS)

To use the SDK, you have to integrate the library into your app, then call the respective API.

Requirements

The SDK requires iOS 15.0 or later, and Xcode 15 or later to build against. The package supports iOS only.

AVPlayerQualityTest uses AVFoundation, so its supported streaming formats and codecs are the ones the device itself supports. In practice this means HLS playlists (live or VoD) and progressive MP4, with H.264 and H.265 video.

Permissions

The SDK makes network requests, which iOS allows by default. If you plan to test URLs served over plain HTTP, add an App Transport Security exception to your app's Info.plist. HTTPS URLs need no network permission or extra configuration.

Every test can also record connection changes and precise location updates. These fields make professional measurements easier to compare by place and network. Your app owns the permission request because only the app can explain this purpose to its users.

Configure the host app as follows:

  • Add NSLocationWhenInUseUsageDescription to the app's Info.plist and explain that precise location is recorded during a quality test and sent to the configured Surfmeter server.
  • Request When In Use location authorization before starting a test. The SDK does not present the system prompt.
  • Add the Access WiFi Information capability when the measurement needs the current Wi-Fi SSID and BSSID.
  • Optionally add NSLocationTemporaryUsageDescriptionDictionary if the app lets a user who selected approximate location grant temporary precise access.

Precise location is recommended for a professional measurement app, but it is not required for a test to run. If the user denies location access, disables Location Services, or leaves Precise Location off, the test still succeeds and geolocation_trace is empty. The SDK does not record approximate coordinates.

See Measurement Context and Privacy for the permission flow, example usage descriptions, collected fields, iOS limitations, and App Store privacy disclosures.

Background AVPlayer Playback

Background playback is optional and applies only to AVPlayerQualityTest. To let a test continue after the user leaves the app:

  • add the Background Modes capability to the host target and select Audio, AirPlay, and Picture in Picture
  • configure and activate the shared AVAudioSession with a playback category before starting the test
  • enable setAllowsBackgroundPlayback(true) on the test builder

The SDK checks the background-mode declaration but deliberately leaves the process-wide audio session under the host app's control. See AVPlayer Background Execution for the complete setup, external-player requirements, and iOS lifecycle limits.

Download

Download the SDK from the links you have been sent, and extract them locally. You will receive two archives:

  • SurfmeterQualitySDK-$version.zip contains the SurfmeterQualitySDK.xcframework folder with the compiled library and its debug symbols
  • SurfmeterQualitySDK-DemoApp-$version.zip contains the README, the license terms, the API documentation in the docs folder, and the demo app source code as QualitySDKExample.zip

Integration via Swift Package Manager

This is the recommended way to add the SDK. We host a Swift package at github.com/aveq-research/surfmeter-ios-quality-sdk which points at the compiled framework. The repository is private, so please ask at support@aveq.info for access to it first.

In Xcode, choose "File" → "Add Package Dependencies", enter the repository URL, and pick the version you want. Xcode downloads the framework and links it for you.

If you manage dependencies in a Package.swift of your own, add it there instead:

dependencies: [
    .package(url: "https://github.com/aveq-research/surfmeter-ios-quality-sdk.git", from: "1.4.0")
],
targets: [
    .target(
        name: "YourApp",
        dependencies: [
            .product(name: "SurfmeterQualitySDK", package: "surfmeter-ios-quality-sdk")
        ]
    )
]

Integration of the XCFramework

If you would rather not depend on a remote repository, add the framework by hand. Drag the SurfmeterQualitySDK.xcframework folder from the extracted archive into your Xcode project.

Set the framework to Embed & Sign

The SDK is a dynamic framework. Under your target's "General" → "Frameworks, Libraries, and Embedded Content", the framework must be set to "Embed & Sign". If it is only linked and not embedded, the app still runs in the simulator but crashes at launch on a physical device, because the framework is missing from the app bundle.

Verifying the Integration

Import the module and print the version to confirm everything is wired up:

import SurfmeterQualitySDK

print("Surfmeter Quality SDK \(Version.current)")

Once the SDK is part of your project, you can start using it.

API Documentation

The docs folder of the demo app archive holds the API reference for every public type in the SDK, generated with DocC. There are two ways to read it:

  • Double-click docs/SurfmeterQualitySDK.doccarchive to open it in Xcode, where it appears alongside Apple's own framework documentation.
  • Run docs/serve-docs.sh to read it in your browser. The script needs Python 3 and starts a local web server.

Note

Opening docs/html/index.html directly does not work. The browser will not load the documentation data from the file system, so the page stays empty. Use one of the two ways above.

Updating the SDK

If you integrated via Swift Package Manager, choose "File" → "Packages" → "Update to Latest Package Versions" in Xcode, or bump the version requirement in your Package.swift.

If you integrated the XCFramework by hand, download the new archive and replace the SurfmeterQualitySDK.xcframework folder with the new one.

Logging

The SDK logs through OSLog, using your app's bundle identifier as the subsystem. In the Console app, filter on that subsystem and on the QualityTest, AVPlayerObserver, WebQualityTest, JSEngine, Registry, ClientApi, MeasurementQueue, ConnectionDetailCollector, or GeolocationCollector categories to follow what the SDK is doing.

Completed reports are not written to the log because they can contain precise coordinates and Wi-Fi names.

You can turn the logging off, or send it to a subsystem of your own:

LoggingConfiguration.shared.loggingEnabled = false
LoggingConfiguration.shared.subsystem = "info.example.myapp.surfmeter"