Перейти к содержанию

Библиотека Android и iOS

Информация

Получить SDK и уточнить условия его использования можно отправив запрос на адрес info@megabitus.com.

Установка библиотеки

iOS

SDK под iOS предоставляется в виде библиотеки в формате xcframework.

Установка через Xcode:

  1. Выбираем проект, чтобы перейти к его настройкам;
  2. Далее нажимаем + в пункте Frameworks, Libraries and Embedded content. В открывшемся окне нажимаем Add other и выбираем папку Megabitus.xcframework с диска;

Если все было сделано правильно — framework появится в таблице и его можно использовать.

Android

SDK под Android предоставляется в виде библиотеки в формате AAR.

Если вы используете Gradle для сборки приложения, добавьте следующую зависимость в Gradle файл приложения:

dependencies {
    // Megabitus SDK
    implementation(files("<path-to-file>/Megabitus.aar"))

    // Megabitus dependencies
    implementation(libs.ktor.client.okhttp)
    implementation(libs.ktor.client.content.negotiation)
    implementation(libs.ktor.serialization.kotlinx.json)
    implementation(libs.kotlinx.datetime)
    ...
}
Примечание

Замените <path-to-file> на путь к каталогу с файлом AAR.

Использование библиотеки

iOS

Пример использования Megabitus в вашем проекте:

...
import Megabitus

extension ContentView {
    class ViewModel: ObservableObject {
        @Published var state = ""
        @Published var server = ""
        @Published var testStarted = false
        @Published var error = ""

        var mbts: Megabitus
        var stateWatcher : Closeable?

        init() {
            // Инициализация библиотеки
            mbts = Megabitus()
            mbts.config(apiKey: "<API_Key>", host: "<Host>", serversPath: "v1/servers", resultPath: "v1/result")

            // Подписка на состояние замера
            stateWatcher = mbts.watchState().watch { currentState in
                self.state = String(describing: currentState)
                self.testStarted = currentState.stage > 0 && currentState.stage < 4
            }
        }

        func startTest() {
            // Получение сервера замера
            mbts.selectServer(deviceId: "TestID", position: GeoPosition(latitude: 64.5555, longitude: 40.5555)) { content, error in
                DispatchQueue.main.async {
                    if let content = content {
                        self.server = content.name

                        // Запуск замера
                        self.mbts.runSpeedtest(server: content, context: nil) { error in
                            DispatchQueue.main.async {}
                        }
                    } else {
                        self.error = error?.localizedDescription ?? "error"
                    }
                }
            }
        }

        func stopTest() {
            // Остановка замера
            self.mbts.stopSpeedtest() { error in
                DispatchQueue.main.async {}
            }
        }

        deinit {
            stateWatcher?.close()
        }
    }
}

struct ContentView: View {
    @ObservedObject private(set) var viewModel: ViewModel

    var body: some View {
        Text("Server: \(viewModel.server), state: \(viewModel.state)")
        Button(viewModel.testStarted ? "Stop" : "Start") {
            viewModel.error = ""
            if (viewModel.testStarted) {
                viewModel.stopTest()
            } else {
                viewModel.startTest()
            }
        }
        if (viewModel.error.count > 0) {
            Text("Error: \(viewModel.error)")
        }
    }
}
Примечание

замените <API_Key> на предоставленный вам уникальный API-ключ, <Host> на адрес сервера Megabitus.

Android

Пример использования Megabitus в вашем проекте:

...
import com.megabitus.mbtsdk.Megabitus
import com.megabitus.mbtsdk.GeoPosition

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Инициализация библиотеки
        val mbts = Megabitus()
        mbts.config("<API_Key>", "<Host>", "v1/servers", "v1/result")

        setContent {
            TestappTheme {
                Surface {
                    val scope = rememberCoroutineScope()
                    var serverText by remember { mutableStateOf("") }
                    var stateText by remember { mutableStateOf("") }
                    var errorText by remember { mutableStateOf("") }
                    var testStarted by remember { mutableStateOf(false) }


                    LaunchedEffect(true) {
                         launch {
                            // Подписка на состояние замера
                            mbts.observeState().collect { state ->
                                stateText = state.toString()
                                testStarted = state.stage in 1..3
                            }
                        }
                    }

                    GreetingView(serverText, stateText, errorText, testStarted, onButtonClick = {
                        scope.launch {
                            try {
                                errorText = ""
                                if (testStarted) {
                                    // Остановка замера
                                    mbts.stopSpeedtest()
                                } else {
                                    // Получение сервера замера
                                    val serverObj = mbts.selectServer("TestID", GeoPosition(latitude = 64.5555, longitude = 40.5555))
                                    if (serverObj != null) {
                                        serverText = serverObj.name
                                        // Запуск замера
                                        mbts.runSpeedtest(serverObj, application)
                                    } else {
                                        errorText = "Server not selected"
                                    }
                                }
                            } catch (e: Exception) {
                                errorText = e.localizedMessage ?: "error"
                            }
                        }
                    })
                }
            }
        }
    }
}

@Composable
fun GreetingView(serverText: String, state: String, errorText: String, testStarted: Boolean, onButtonClick: () -> Unit) {
    Column {
        Text(text = "Server: $serverText")
        Text(text = "State: $state")
        Button(onClick = onButtonClick) {
            Text((if (testStarted) "Stop" else "Start"))
        }
        if (errorText.isNotEmpty())
            Text(text = "Error: $errorText")
    }
}
Примечание

замените <API_Key> на предоставленный вам уникальный API-ключ, <Host> на адрес сервера Megabitus.

Доступные методы

  • config(apiKey: String, host: String, serversPath: String = "v1/servers", resultPath: String = "v1/result"): Инициализация библиотеки
  • selectServer(deviceId: String? = null, position: GeoPosition? = null, nodeId: String? = null, nodeHost: String? = null): MegabitusServer: Получение сервера замера
  • runSpeedtest(server: MegabitusServer, context: Any?): Запуск замера
  • stopSpeedtest(): Остановка замера

Описание класса MegabitusServer:

class MegabitusServer(
    val _id: String,        // ID сервера
    val name: String,       // Название сервера
    val provider: String,   // Провайдер
    val host: String,       // Адрес сервера
    val garbage: String,    // Download URL
    val url: String         // Upload URL
)

Подписка на события

  • mbts.observeState() (Android) / mbts.watchState() (iOS): Отслеживание текущего состояния замера, возвращающее SpeedtestState.

Описание класса SpeedtestState:

data class SpeedtestState(
    var stage: Int,                             // Стадия замера
    var error: MegabitusError?,                 // Описание ошибки
    var serverSelection: Int,                   // Стадия выбора сервера
    var ping: Int,                              // Текущее/последнее значение пинга
    var jitter: Double,                         // Текущее/последнее значение разброса
    var losses: Double,                         // Текущее/последнее значение потерь
    var download: Double,                       // Текущее/последнее значение Download
    var downloadDetails: ArrayList<Double>,     // Детали Download
    var upload: Double,                         // Текущее/последнее значение Upload
    var uploadDetails: ArrayList<Double>,       // Детали Upload
    var result: MegabitusResultSession?         // Результат
)

Описание класса MegabitusResultSession:

class MegabitusResultSession(
    val TestID: String? = "",                   // ID замера
    val ClientIP: String? = "",                 // IP клиента
    val Provider: String? = "",                 // Провайдер
    val ConnectionType: String? = "",           // Тип соединения
    val LocationType: String? = "",             // Тип локации
    val LocationLat: Double? = 0.0,             // Широта
    val LocationLng: Double? = 0.0,             // Долгота
    val LocationCountry: String? = "",          // Страна
    val LocationAAL1: String? = "",             // Регион
    val LocationAAL2: String? = "",             // Административный округ
    val LocationLocality: String? = "",         // Населенный пункт
    val Ping: Int? = 0,                         // Пинг
    val Jitter: Double? = 0.0,                  // Разброс
    val Losses: Double? = 0.0,                  // Потери
    val Download: Double? = 0.0,                // Download
    val DownloadDetails: ArrayList<Double>?,    // Детали Download
    val Upload: Double? = 0.0,                  // Upload
    val UploadDetails: ArrayList<Double>?       // Детали Upload
)

Стадии замера (значения поля stage):

0 — Начало замера
1 — Ping
2 — Download
3 — Upload
4 — Сохранение результата
5 — Окончание
-1 — Ошибка

Собираемые данные окружения

Общие данные:

versionApp — Версия библиотеки
clientIp — IP клиента

Данные об устройстве:

platform — Платформа
os — Версия ОС
deviceId — ID устройства
deviceModel — Модель устройства
deviceBrand — Бренд устройства

Данные о локации:

locationGPS — Доступ к данным локации
locationAccuracy — Точность
locationLatitude — Широта
locationLongitude — Долгота

Возможные проблемы и их решение

При возникновении ошибки вернется объект класса MegabitusError:

class MegabitusError(
    val code: Int,          // Код ошибки
    val message: String,    // Сообщение
    val details: String?,   // Детальное описание
)

Описание возможных кодов ошибок:

1100 — Stopped (Пользователь остановил замер)
2100 — Http status code incorrect (Сетевой запрос вернул статус, отличный от 200)
2200 — Network request error (Ошибка сетевого запроса)
3100 — Get servers failed (Не удалось получить список серверов замера)
3200 — Ping failed (Не удалось выполнить опрос сервера)
3300 — Save result failed (Не удалось сохранить результат замера)

✉ В случае возникновения проблем с установкой, внедрением или использованием библиотеки вы можете связаться с нами: info@megabitus.com.