Парсинг — це процес синтаксичного аналізу структурованих даних, що витягує інформацію з JSON, XML, CSV або Protobuf для використання в додатку. За даними Square Engineering (2025), вибір стратегії парсингу безпосередньо впливає на продуктивність мобільного додатка. Потоковий парсинг дозволяє обробляти мегабайти даних без завантаження всього документа в пам'ять.
Головне
Парсинг (синтаксичний аналіз) — це процес перетворення послідовності символів у структуроване представлення, придатне для програмної обробки. У контексті мобільної розробки під парсингом розуміють розбір відповідей сервера, конфігураційних файлів, локального кешу та файлів ресурсів. Кожен формат потребує власного підходу: JSON — легкий та вбудований в SDK, XML — строгий з валідацією схеми XSD, CSV — мінімалістичний для табличних даних, Protobuf — бінарний з жорсткою схемою.
Будь-який парсер, незалежно від формату, проходить три етапи. Лексичний аналіз розбиває сирий текст на лексеми: ключі, рядки, числа, роздільники та коментарі. Синтаксичний аналіз перевіряє коректність граматики — баланс дужок в JSON, правильність вкладеності тегів у XML. Побудова вихідної структури формує об'єктне представлення: JSONObject, Map або потік токенів для подальшої обробки. За даними Apple (2026), вбудований Foundation-парсер на iOS використовує лінивий розбір — він валідує лише початок JSON, економлячи ресурси.
Ручний парсинг (JSONSerialization, XmlPullParser) дає повний контроль над процесом і корисний при нестандартних форматах або необхідності кастомної валідації кожного поля. Автоматичні бібліотеки (JSONDecoder, Moshi, kotlinx.serialization) прискорюють розробку, але приховують деталі обробки помилок. Вибір залежить від вимог: якщо структура даних динамічна або заздалегідь невідома — ручний парсинг кращий. Якщо схема фіксована — автоматична десеріалізація скорочує код на 60-70%.
Парсинг — ширша операція: він може виконуватися потоково і не обов'язково створює типізований об'єкт. Десеріалізація — окремий випадок парсингу, результатом якого завжди є екземпляр заздалегідь відомого класу з конкретними типами властивостей. Парсер JSON розбере документ на Map або JsonElement, а десеріалізатор перетворить той самий JSON на конкретний об'єкт User, Order або Product з відомими полями та їхніми типами.
| Характеристика | Парсинг | Десеріалізація |
|---|---|---|
| Результат | JsonElement, Map, потік токенів | Типізований об'єкт (User, Order) |
| Потоковий режим | Так (SAX, JsonReader) | Ні (весь об'єкт у пам'яті) |
| Типізація | Необов'язкова, dynamic types | Обов'язкова, статичні типи |
| Приклад | XmlPullParser.next(), SAX події | json.decodeFromString<User>() |
Потоковий парсинг — головна перевага парсингу над десеріалізацією. XmlPullParser на Android розбирає XML у міру читання, не завантажуючи весь документ в оперативну пам'ять. Це критично для великих відповідей API, парсингу RSS-стрічок з сотнями елементів або обробки масиву з тисяч об'єктів JSON із серверного дампу. Потоковий парсер читає токен за токеном, споживаючи константну кількість пам'яті незалежно від розміру документа.
JSON — домінуючий формат обміну даними. На iOS вбудований JSONSerialization розбирає JSON в Any, а JSONDecoder — одразу в Codable-структуру. На Android стандартний org.json надає JSONObject і JSONArray для ручного розбору. Gson та Moshi додають автоматичне перетворення. Вибір між ручним та автоматичним підходом — перше архітектурне рішення мережевого шару.
val jsonString = """{"users":[{"id":1,"name":"Alice"}]}"""
val jsonObject = JSONObject(jsonString)
val usersArray = jsonObject.getJSONArray("users")
for (i in 0 until usersArray.length()) {
val item = usersArray.getJSONObject(i)
val id = item.getInt("id")
val name = item.getString("name")
// обробка користувача
}
Ручний парсинг через org.json корисний, коли структура відповіді заздалегідь невідома або сильно варіюється. Такий підхід дає повний контроль над обробкою помилок та nullable-полів, але потребує більше шаблонного коду порівняно з автоматичною десеріалізацією. Для невеликих проєктів або прототипів це прийнятно, але в production краще використовувати Moshi або kotlinx.serialization.
JsonReader з бібліотеки Moshi — потужний інструмент потокового парсингу JSON. Він читає документ токен за токеном, використовуючи методи beginObject, nextName, nextString, nextInt та endObject. Такий підхід дозволяє обробляти документи будь-якого розміру з константним споживанням пам'яті. За даними Google (2026), потоковий парсинг через JsonReader у 2-3 рази швидший за завантаження всього документа в JsonObject і споживає до 80% менше пам'яті.
val reader = JsonReader(StringReader(json))
reader.beginObject()
while (reader.hasNext()) {
val name = reader.nextName()
when (name) {
"id" -> val id = reader.nextInt()
"name" -> val name = reader.nextString()
"email" -> val email = reader.nextString()
else -> reader.skipValue()
}
}
reader.endObject()
У прикладі показано JsonReader, що розбирає JSON потоково. Кожен виклик nextName() та nextInt() просуває курсор на наступний токен. skipValue() пропускає непотрібні поля без їх розбору — це особливо корисно, коли JSON містить 50 полів, а потрібні лише 3. Результат — мінімальне споживання пам'яті та максимальна швидкість.
XML продовжує використовуватися в Android-проєктах для ресурсів та в SOAP-сервісах корпоративних додатків. На Android вбудований XmlPullParser забезпечує потоковий розбір з мінімальним споживанням пам'яті — він не завантажує DOM-дерево, а генерує події START_TAG, TEXT, END_TAG. iOS використовує XMLParser з делегатним підходом: методи parser(didStartElement:) та parser(foundCharacters:) обробляють елементи послідовно.
CSV — найпростіший формат для експорту та імпорту табличних даних. У мобільних додатках CSV використовується для вивантаження звітів, завантаження довідників (списки країн, валют, кодів) та синхронізації офлайн-даних. Для парсингу CSV підходять потокові бібліотеки: Apache Commons CSV та OpenCSV обробляють файли рядок за рядком, екрануючи лапки та коми всередині значень. На iOS CSV-парсинг можна реалізувати через делімітер NSString.components(separatedBy:) з обробкою крайніх випадків.
class CSVParser: NSObject, XMLParserDelegate {
private var currentItem: [String: String] = [:]
private var currentElement: String = ""
func parser(
_ parser: XMLParser,
didStartElement elementName: String,
namespaceURI: String?,
qualifiedName qName: String?,
attributes attributeDict: [String: String]
) {
currentElement = elementName
if elementName == "item" {
currentItem = [:]
}
}
func parser(_ parser: XMLParser,
foundCharacters string: String) {
currentItem[currentElement] = string
}
}
Приклад делегата XMLParser на iOS для розбору RSS-стрічки. Метод didStartElement викликається на кожному відкриваючому тезі, foundCharacters повертає текстовий вміст між тегами, didEndElement завершує елемент. Така подієва архітектура дозволяє обробляти XML будь-якого розміру без завантаження DOM-дерева в пам'ять — критично для обмежених ресурсів мобільних пристроїв.
На Android вибір CSV-парсера залежить від обсягу даних. OpenCSV підтримує fluent API, анотації для мапінгу на POJO та кастомні роздільники. Apache Commons CSV — більш низькорівневий, але швидший на великих файлах. Для простих випадків (1-2 колонки) достатньо ручного розбору через String.split(",") з обробкою екранування. Для production-проєктів з великими CSV-файлами рекомендується OpenCSV.
Protocol Buffers від Google — бінарний формат серіалізації, що перевершує JSON за швидкістю та компактністю. Protobuf-повідомлення займає в 3-6 разів менше місця, ніж еквівалентний JSON, і парситься в 4-10 разів швидше завдяки бінарному формату та жорсткій схемі. Основні недоліки: відсутність людської читабельності та необхідність генерації коду з .proto-файлів через protoc-компілятор.
Потоковий парсинг Protobuf реалізується через CodedInputStream — клієнт читає поля в міру надходження без завантаження всього повідомлення. Кожне поле має tag (номер + тип), і парсер може пропускати невідомі поля. За даними Google (2026), потоковий розбір Protobuf споживає до 90% менше пам'яті при обробці повідомлень від 1 МБ, що критично для мобільних пристроїв з обмеженою оперативною пам'яттю. Protobuf-lite — спеціальна версія для Android, оптимізована за розміром згенерованого коду.
Часті запитання
JSONSerialization — ручний парсинг, що повертає Any (Dictionary, Array) без типізації. JSONDecoder — автоматична десеріалізація в Codable-типи. JSONSerialization дає гнучкість для динамічних структур, JSONDecoder — швидкість і типову безпеку для відомих схем. У production рекомендується JSONDecoder.
Потоковий парсинг обов'язковий при відповідях від 500 КБ, при парсингу RSS/Atom стрічок і при розборі файлів на пристроях з обмеженою пам'яттю. Для типових API-відповідей до 100 КБ автоматична десеріалізація через JSONDecoder або Moshi краща — код чистіший і швидше розробляється.
Android SDK включає org.json (JSONObject, JSONArray), XmlPullParser (XML) та android.util.JsonReader. Для CSV, YAML та Protobuf потрібні додаткові бібліотеки: OpenCSV для CSV, SnakeYAML для YAML, protobuf-javalite для Protobuf.
Використовуйте lenient режим у kotlinx.serialization або JsonReader.setLenient(true) у Moshi — він прощає зайві коми, неекрановані лапки та однорядкові коментарі. Для повної валідації впровадьте контрактне тестування через Pact або Spring Cloud Contract.
SAX (Simple API for XML) — потоковий XML-парсер, що генерує події startElement, characters, endElement при обході документа. Реалізований через XmlPullParser на Android та XMLParser на iOS. Застосовується в RSS-читачах, синхронізації офлайн-даних та обробці SVG-файлів.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також