Serialization and deserialization are fundamental processes of converting objects into a format for transmission or storage. In mobile development, these mechanisms are used with every network request, state saving, and interprocess communication. According to MDN Web Docs, 2024, JSON remains the most popular format for serialization on the web and in mobile applications, surpassing XML and Protocol Buffers.
Key Takeaways
Serialization is the process of converting an application object into a format suitable for network transmission or disk storage. Deserialization performs the reverse conversion, restoring the object from the received data. In mobile development, serialization is used in API requests, screen state saving, caching, and data transfer via Intent or Bundle.
Any interaction between application components or between the application and a server requires serialization. REST APIs transmit data in JSON or XML, gRPC uses Protocol Buffers, and intraprocess communication on Android uses Parcelable. Without serialization, it is impossible to pass a complex object across a process boundary or save it to a database.
// General principle of serialization
data class User(
val id: Int,
val name: String,
val email: String
)
// Serialization: object -> JSON
fun serializeUser(user: User): String {
return """{"id":${user.id},"name":"${user.name}","email":"${user.email}"}"""
}
// Deserialization: JSON -> object
fun deserializeUser(json: String): User? {
// parsing JSON to object
return Gson().fromJson(json, User::class.java)
}
| Format | Size | Speed | Readability | Typing |
|---|---|---|---|---|
| JSON | medium | high | high | dynamic |
| XML | large | medium | high | XSD schema |
| Protocol Buffers | small | very high | low | strict .proto |
| FlatBuffers | small | maximum | low | strict .fbs |
JSON (JavaScript Object Notation) is a lightweight text format based on JavaScript object syntax. JSON supports strings, numbers, boolean values, arrays, and nested objects, covering most data transfer scenarios in mobile applications. The format is platform-independent: each ecosystem provides built-in tools for parsing it.
JSON wins due to its simplicity and versatility. A developer does not need a schema for basic use — the structure is determined dynamically during parsing. The readability of the format simplifies debugging and testing: the server response can be viewed in any developer tool. On both mobile platforms, JSON is processed natively without requiring third-party libraries.
// Codable — native JSON serialization in Swift
struct User: Codable {
let id: Int
let name: String
let email: String
}
let jsonString = """{"id":1,"name":"John","email":"john@test.com"}"""
let jsonData = Data(jsonString.utf8)
let decoder = JSONDecoder()
let user = try! decoder.decode(User.self, from: jsonData)
Protocol Buffers (protobuf) is a binary serialization format developed by Google for high-performance systems. Unlike JSON, protobuf requires a predefined schema in a .proto file, but provides significantly smaller data size and higher processing speed. The format is used in gRPC, Firebase Firestore, and internal Google services.
A protobuf schema describes messages with typed fields, each having a unique number. The protoc compiler generates classes in the target language that perform serialization and deserialization automatically. Protobuf supports schema evolution through rules for adding and removing fields without breaking backward compatibility.
// Schema definition in user.proto
syntax = "proto3";
message User {
int32 id = 1;
string name = 2;
string email = 3;
repeated string roles = 4;
}
// Generated code in Kotlin
val user = UserProto.User.newBuilder()
.setId(1)
.setName("John")
.setEmail("john@test.com")
.build()
val bytes: ByteArray = user.toByteArray()
XML (eXtensible Markup Language) is a format with rigid structure, namespace support, and validation through XSD schemas. XML loses to JSON in compactness and parsing speed, but remains in demand in Android development for layout files, AndroidManifest, resources, and Gradle configurations. On iOS, XML is used in plist files and some legacy services.
Android provides three approaches to XML parsing: DOM (loading the entire document into memory), SAX (event-driven streaming parsing), and XmlPullParser (a hybrid approach). XmlPullParser is the recommended option for mobile devices, as it works efficiently with limited memory and allows processing the document as it is read.
// XmlPullParser on Android
fun parseUserXml(inputStream: InputStream): User? {
val parser = Xml.newPullParser()
parser.setInput(inputStream, Xml.Encoding.UTF_8.name)
var id: Int? = null
var name: String? = null
var email: String? = null
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.eventType == XmlPullParser.START_TAG
&& parser.name == "email") {
email = parser.nextText()
}
}
return User(id!!, name!!, email!!)
}
Each platform offers its own serialization tools. On iOS, the primary mechanism is the Codable protocol with JSONEncoder and JSONDecoder, while Objective-C uses NSJSONSerialization. Android uses Gson, Moshi, and kotlinx.serialization libraries. For interprocess data transfer, Android employs Parcelable, while iOS uses NSKeyedArchiver. Kotlin projects increasingly choose kotlinx.serialization — a JetBrains solution that supports multiplatform development and does not rely on reflection, generating serializers at compile time through the Kotlin compiler plugin.
Android supports two serialization mechanisms for Intent and Bundle. Serializable is a standard Java mechanism that uses reflection, leading to lower performance. Parcelable is an Android-specific protocol that requires manual implementation of writeToParcel and createFromParcel methods, but works tens of times faster due to direct byte manipulation.
// Parcelable on Android
@Parcelize
data class UserParcel(
val id: Int,
val name: String,
val email: String
) : Parcelable
// Transfer via Intent
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user", userParcel)
startActivity(intent)
On iOS, Codable with preliminary serialization into Data is used for data transfer between controllers, while NSKeyedArchiver is used for interprocess communication, converting objects into the binary Property List format. Modern SwiftUI projects prefer encoding data via JSONEncoder for transfer between application modules.
Incorrect deserialization of untrusted data can lead to vulnerabilities. Serialization attacks exploit overridden readObject methods in Java or unsafe deserializers in third-party libraries. On Android, you should avoid Serializable for data from untrusted sources, using Parcelable or manual validation of all fields after deserialization instead. On iOS, JSONDecoder is strict by default with types, but when working with JSONSerialization, developers must check types through conditional casting.
When choosing a serialization format, performance requirements, data size, and compatibility are considered. For REST APIs and microservice architecture, JSON remains the optimal choice — it is supported by all platforms and languages. For high-load systems and mobile applications with limited bandwidth, Protocol Buffers are preferable, offering smaller size and faster deserialization. XML is justified only in configuration scenarios and when integrating with legacy systems. Modern projects are also seeing the rise of FlatBuffers — a binary format with no deserialization step, used in game engines and latency-sensitive applications. Each format has its niche, and the right choice directly affects application speed and bandwidth consumption.
Frequently Asked Questions
Serialization is the packaging of an application object into a format that can be sent over a network or saved to a file. Imagine you take a photo of an object — the photo is serialization, and restoring the object from the photo is deserialization.
JSON is a text format that is human-readable and does not require a schema. Protocol Buffers is a binary format with a mandatory schema (.proto), significantly smaller size, and higher speed. Protobuf is chosen for high-load systems, while JSON is chosen for universal compatibility.
XML remains the standard for configuration files (AndroidManifest, layout resources), documents with complex nesting, and systems with strict XSD validation. XML is also used in SOAP protocols and legacy systems that require namespace support.
Codable is a Swift protocol that combines Encodable and Decodable for automatic serialization and deserialization. The compiler generates the implementation of encode(to:) and init(from:) methods for all properties of the structure or class.
Parcelable works significantly faster than Serializable because it does not use reflection and directly writes fields to a byte stream. On modern devices, the difference can reach a 10x speedup in favor of Parcelable.
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