Parsing is the process of syntactic analysis of structured data, extracting information from JSON, XML, CSV, or Protobuf for use in an application. According to Square Engineering (2025), the choice of parsing strategy directly affects mobile application performance. Streaming parsing allows processing megabytes of data without loading the entire document into memory.
Key Takeaways
Parsing (syntactic analysis) is the process of converting a sequence of characters into a structured representation suitable for programmatic processing. In the context of mobile development, parsing refers to processing server responses, configuration files, local cache, and resource files. Each format requires its own approach: JSON — lightweight and built into the SDK, XML — strict with XSD schema validation, CSV — minimalistic for tabular data, Protobuf — binary with a rigid schema.
Any parser, regardless of format, goes through three stages. Lexical analysis splits raw text into tokens: keys, strings, numbers, delimiters, and comments. Syntactic analysis checks grammar correctness — bracket balance in JSON, proper tag nesting in XML. Output structure construction produces an object representation: JSONObject, Map, or a token stream for further processing. According to Apple (2026), the built-in Foundation parser on iOS uses lazy parsing — it only validates the beginning of JSON, saving resources.
Manual parsing (JSONSerialization, XmlPullParser) gives full control over the process and is useful for non-standard formats or when custom validation of each field is needed. Automated libraries (JSONDecoder, Moshi, kotlinx.serialization) speed up development but hide error handling details. The choice depends on requirements: if the data structure is dynamic or unknown in advance — manual parsing is preferable. If the schema is fixed — automated deserialization reduces code by 60-70%.
Parsing is a broader operation: it can be done in a streaming fashion and does not necessarily create a typed object. Deserialization is a specific case of parsing whose result is always an instance of a known class with specific property types. A JSON parser breaks a document into a Map or JsonElement, while a deserializer turns the same JSON into a concrete User, Order, or Product object with known fields and their types.
| Characteristic | Parsing | Deserialization |
|---|---|---|
| Result | JsonElement, Map, token stream | Typed object (User, Order) |
| Streaming mode | Yes (SAX, JsonReader) | No (entire object in memory) |
| Typing | Optional, dynamic types | Mandatory, static types |
| Example | XmlPullParser.next(), SAX events | json.decodeFromString<User>() |
Streaming parsing is the main advantage of parsing over deserialization. XmlPullParser on Android parses XML as it reads, without loading the entire document into RAM. This is critical for large API responses, parsing RSS feeds with hundreds of items, or processing arrays of thousands of JSON objects from a server dump. A streaming parser reads token by token, consuming a constant amount of memory regardless of document size.
JSON is the dominant data exchange format. On iOS, the built-in JSONSerialization parses JSON into Any, while JSONDecoder parses directly into a Codable structure. On Android, the standard org.json provides JSONObject and JSONArray for manual parsing. Gson and Moshi add automatic conversion. Choosing between manual and automated approaches is the first architectural decision of the networking layer.
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")
// user processing
}
Manual parsing via org.json is useful when the response structure is unknown in advance or varies greatly. This approach gives full control over error handling and nullable fields but requires more boilerplate code compared to automated deserialization. For small projects or prototypes it is acceptable, but in production, Moshi or kotlinx.serialization is preferred.
JsonReader from the Moshi library is a powerful tool for streaming JSON parsing. It reads the document token by token using methods like beginObject, nextName, nextString, nextInt, and endObject. This approach allows processing documents of any size with constant memory consumption. According to Google (2026), streaming parsing via JsonReader is 2-3x faster than loading the entire document into a JsonObject and consumes up to 80% less memory.
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()
The example shows JsonReader parsing JSON in a streaming fashion. Each call to nextName() and nextInt() advances the cursor to the next token. skipValue() skips unnecessary fields without parsing them — especially useful when JSON contains 50 fields but only 3 are needed. The result is minimal memory consumption and maximum speed.
XML continues to be used in Android projects for resources and in SOAP services of enterprise applications. On Android, the built-in XmlPullParser provides streaming parsing with minimal memory consumption — it does not load a DOM tree but generates START_TAG, TEXT, END_TAG events. iOS uses XMLParser with a delegate approach: parser(didStartElement:) and parser(foundCharacters:) methods handle elements sequentially.
CSV is the simplest format for exporting and importing tabular data. In mobile apps, CSV is used for report export, loading reference data (country lists, currencies, codes), and offline data synchronization. Streaming libraries are suitable for CSV parsing: Apache Commons CSV and OpenCSV process files line by line, escaping quotes and commas within values. On iOS, CSV parsing can be implemented via the NSString.components(separatedBy:) delimiter method with edge case handling.
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
}
}
Example of an XMLParser delegate on iOS for parsing an RSS feed. The didStartElement method is called on each opening tag, foundCharacters returns text content between tags, and didEndElement completes the element. This event-based architecture allows processing XML of any size without loading a DOM tree into memory — critical for limited resources on mobile devices.
On Android, the choice of CSV parser depends on data volume. OpenCSV supports a fluent API, annotations for POJO mapping, and custom delimiters. Apache Commons CSV is more low-level but faster on large files. For simple cases (1-2 columns), manual parsing via String.split(",") with escape handling is sufficient. For production projects with large CSV files, OpenCSV is recommended.
Protocol Buffers from Google is a binary serialization format that surpasses JSON in speed and compactness. A Protobuf message takes 3-6x less space than equivalent JSON and parses 4-10x faster thanks to its binary format and rigid schema. The main drawbacks are lack of human readability and the need to generate code from .proto files via the protoc compiler.
Streaming Protobuf parsing is implemented via CodedInputStream — the client reads fields as they arrive without loading the entire message. Each field has a tag (number + type), and the parser can skip unknown fields. According to Google (2026), streaming Protobuf parsing consumes up to 90% less memory when processing messages from 1 MB, which is critical for mobile devices with limited RAM. Protobuf-lite is a special version for Android, optimized for generated code size.
Frequently Asked Questions
JSONSerialization is manual parsing returning Any (Dictionary, Array) without typing. JSONDecoder is automatic deserialization into Codable types. JSONSerialization provides flexibility for dynamic structures, while JSONDecoder offers speed and type safety for known schemas. In production, JSONDecoder is recommended.
Streaming parsing is required for responses over 500 KB, when parsing RSS/Atom feeds, and when processing files on devices with limited memory. For typical API responses up to 100 KB, automatic deserialization via JSONDecoder or Moshi is preferable — cleaner code and faster development.
Android SDK includes org.json (JSONObject, JSONArray), XmlPullParser (XML), and android.util.JsonReader. CSV, YAML, and Protobuf require additional libraries: OpenCSV for CSV, SnakeYAML for YAML, protobuf-javalite for Protobuf.
Use lenient mode in kotlinx.serialization or JsonReader.setLenient(true) in Moshi — it forgives trailing commas, unescaped quotes, and single-line comments. For full validation, implement contract testing via Pact or Spring Cloud Contract.
SAX (Simple API for XML) is a streaming XML parser that generates startElement, characters, endElement events while traversing the document. It is implemented via XmlPullParser on Android and XMLParser on iOS. It is used in RSS readers, offline data synchronization, and SVG file processing.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also