دسریالیسازی — فرآیند بازیابی شیء از جریان دادههای JSON، XML یا Protobuf است که برای هر برنامه موبایلی که با API از راه دور کار میکند ضروری است. به گزارش Apple Developer (2026)، پردازش نادرست دادههای ورودی یکی از علل شایع کراش در دستگاهها است. JSONDecoder در iOS و Gson در Android ابزارهای استاندارد هستند، اما هر کدام ویژگیها و محدودیتهای خود را دارند.
نکات کلیدی
دسریالیسازی — فرآیند تبدیل جریان بایتها یا متن ساختاریافته به شیء زبان برنامهنویسی است. در توسعه موبایل، این فرآیند هر بار که برنامه پاسخی از سرور دریافت میکند اتفاق میافتد: رشته JSON به یک نمونه از کلاس User، Order یا Product تبدیل میشود. پایداری صفحاتی که دادهها را به کاربر نشان میدهند مستقیماً به صحت دسریالیسازی بستگی دارد.
سریالیسازی و دسریالیسازی فرآیندهای متقابل هستند، در عمل به ندرت متناظر. سریالیسازی شیء را برای ارسال به سرور به رشته تبدیل میکند، دسریالیسازی شیء را از رشته دریافتی بازیابی میکند. سرور ممکن است فیلدی را بفرستد که در مدل مشتری نیست، از فرمت تاریخ دیگری استفاده کند یا به جای عدد null برگرداند. به گزارش Square Engineering (2025)، ناهماهنگی فرمتها علت 23% خطاهای لایه شبکه در برنامههای Android است. برای کاهش ریسک، نسخهبندی شما و مشخصات قرارداد سختگیرانه از طریق OpenAPI اعمال میشود.
JSON به دلیل خوانایی انسانی و پشتیبانی داخلی محبوبترین فرمت برای APIهای موبایل است. Protobuf از Google در سیستمهای با بار بالا استفاده میشود — 3-6 برابر فشردهتر از JSON و سریعتر تجزیه و تحلیل میشود، اما نیازمند تولید کد از فایلهای .proto است و بدون ابزار قابل خواندن نیست. XML در برنامههای موبایل مدرن کمتر مشاهده میشود، اما در خدمات SOAP سیستمهای سازمانی و فایلهای پیکربندی Android کاربرد دارد. MessagePack — فرمت دودویی مشابه JSON از نظر ساختار، اما فشردهتر، محبوب در سیستمهای بلادرنگال.
فرآیند دسریالیسازی از سه مرحله عبور میکند. ابتدا توکنسازی متن خام را به توکنها تقسیم میکند: کلیدها، رشتهها، اعداد و جداکنندهها. سپس تحلیل نحوی صحت ساختار را بررسی میکند — آیا پرانتزها بسته هستند، نوع گیومه مناسب است، آیا فرمت مطابق مشخصات RFC 8259 است. مرحله نهایی — نقشهبرداری به مدل شیئگرایی برنامه، جایی که به هر کلید JSON یک ویژگی کلاس با توجه به راهبرد نامگذاری تعیین میشود.
در توسعه موبایل دو رویکرد برای نقشهبرداری شکل گرفته است. Reflection (Gson، JSONSerialization) ساختار کلاس را در زمان اجرا از طریق Java Reflection API یا Objective-C runtime تحلیل میکند — انعطافپذیر است و نیازی به پیکربندی اضافی ندارد، اما کندتر است و حافظه بیشتری مصرف میکند. Code generation (Moshi codegen، kotlinx.serialization، Codable) کد را در مرحله کامپایل تولید میکند: سریعتر، از نظر انواع ایمنتر و ساختار داخلی را از طریق reflection آشکار نمیکند. JetBrains و Square برای بناهای تولید code generation را توصیه میکنند — افزایش عملکرد در بنچمارکهای Google به 2-4 برابر میرسد.
struct User: Codable {
let id: Int
let name: String
let email: String
let createdAt: Date
}
let json = """
{
"id": 42,
"name": "Alice",
"email": "alice@example.com",
"created_at": "2026-06-01T12:00:00Z"
}
"""
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let user = try decoder.decode(User.self, from: data)
نمونه دسریالیسازی JSON به مدل User در Swift. راهبرد convertFromSnakeCase به طور خودکار کلیدهای snake_case API را به ویژگیهای camelCase مدل تبدیل میکند — روش استاندارد در پروژههای iOS. پارامتر data بایتهای خام پاسخ سرور است که از طریق URLSession دریافت شده. مدیریت خطا از طریق try امکان گیرنتاری JSON نامعتبر را بدون کراش برنامه فراهم میکند.
JSONDecoder از چهار راهبرد کلید پشتیبانی میکند: useDefaultKeys (مطابقت دقیق)، convertFromSnakeCase (snake_case → camelCase)، custom (closure) و convertFromKebabCase (kebab-case → camelCase). برای تاریخها .iso8601، .secondsSince1970، .millisecondsSince1970 و dateFormatter سفارشی پیشبینی شده است. انتخاب راهبرد مناسب اولین گام به سمت دسریالیسازی پایدار است که از اکثر خطاهای ناهماهنگی فرمت جلوگیری میکند.
JSONDecoder — مکانیسم استاندارد دسریالیسازی در iOS SDK است که با پروتکل Codable کار میکند. JSONDecoder به طور خودکار JSON را به نمونههای struct یا class تجزیه و تحلیل میکند و از شیئهای تودرتو، آرایهها و انواع پایه پشتیبانی میکند. برای منطق سفارشی از روش init(from: Decoder) استفاده میشود — این روش به شما امکان میدهد فرمتهای غیراستاندارد، فیلدهای حذفشده در نسخه قدیمی API را مدیریت کنید یا چندین کلید JSON را در یک ویژگی ادغام کنید.
struct Order: Decodable {
let orderId: String
let amount: Double
let status: OrderStatus
enum OrderStatus: String, Decodable {
case pending, confirmed, shipped, cancelled
}
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let order = try decoder.decode(Order.self, from: jsonData)
DateDecodingStrategy مشخص میکند که JSONDecoder رشتههای حاوی تاریخ را چگونه تفسیر کند. بیشتر از همه .iso8601 استفاده میشود — فرمت استاندارد REST API. Enum تودرتو OrderStatus به طور خودکار از مقادیر رشته JSON کدگشایی میشود. این امکان از اعداد جادویی جلوگیری میکند و کد را خودمستند میسازد — وضعیت سفارش همواره یک مجموعه سختگیرانه از مقادیر دارد.
از Swift 4.2 به بعد، Codable از property wrappers برای دسریالیسازی سفارشی ویژگیهای فردی پشتیبانی میکند. @DefaultValue — ایدار کردی محبوبی است که اگر فیلد در JSON وجود نداشته باشد، مقدار پیشفرض را تعیین میکند. @LosslessString رشته را به عدد و برعکس تبدیل میکند. این وقتی که سرور id را به صورت رشته «123» ارسال میکند و مدل Int انتظار دارد، خیلی مفید است. Property wrappers کد الگویی را در init(from:) کاهش میدهند و مدلها را تمیزتر میکنند.
در Android انتخاب کتابخانه دسریالیسازی به زبان و نیازهای پروژه بستگی دارد. Gson از Google — رایجترین گزینه است که از طریق reflection کار میکند، اما در سلسله مراتب پیچیده مشکلات عملکردی دارد. Moshi از Square هم reflection و هم code generation را پشتیبانی میکند، حافظه کمتری مصرف میکند و پاسخهای بزرگ را سریعتر پردازش میکند. kotlinx.serialization از JetBrains — راهحل اصلی Kotlin با ادغام در کامپایلر است که اصلاً از reflection استفاده نمیکند.
@Serializable
data class User(
@SerialName("user_id")
val userId: Int,
val name: String,
val email: String,
@SerialName("created_at")
val createdAt: String
)
val json = Json { ignoreUnknownKeys = true }
val user = json.decodeFromString<User>(response)
@Serializable — انوتاسیون کامپایلر Kotlin است که تولید کد را برای کلاس فعال میکند. پارامتر ignoreUnknownKeys اگر سرور فیلدی را که در مدل نیست بفرستد، از کراش جلوگیری میکند. برای نقشهبرداری کلیدهای snake_case از @SerialName استفاده میشود — معادل convertFromSnakeCase در iOS. به گزارش JetBrains (2026)، این کتابخانه از چندسیستمی پشتیبانی میکند: همان کلاس Serializable در Android، iOS (KMP) و سرور Kotlin کار میکند.
انتخاب بین کتابخانهها به یک معامله سرعت-انعطاف خلاصه میشود. Gson برای پروتوتیپها و پروژههای Java مناسب است — نیازی به انوتاسیون ندارد و بدون پیکربندی کار میکند. Moshi موقعیت میانی را اشغال میکند: codegen از طریق @JsonClass(generateAdapter = true) سرعتی نزدیک به kotlinx.serialization و حالت reflection انعطاف Gson را فراهم میکند. kotlinx.serialization — سریعترین گزینه برای پروژههای خالص Kotlin است، اما به Kotlin 1.4+ و افزونه Kotlin Serialization در Gradle نیاز دارد.
| کتابخانه | مکانیسم | سرعت | KMP |
|---|---|---|---|
| Gson | Reflection | پایین | خیر |
| Moshi | Reflection / Codegen | متوسط / بالا | خیر |
| kotlinx.serialization | Compiler codegen | بالا | بله |
Type mismatch — وضعیتی که JSON شامل مقدار یک نوع است و مدل نوع دیگری را انتظار دارد. سرور به جای عدد، رشته «42» یا به جای boolean true، عدد 1 را ارسال کرد. در iOS، JSONDecoder به طور پیشفرض DecodingError.typeMismatch صادر میکند، در Android، Gson سعی در تبدیل میکند، و Moshi و kotlinx.serialization نیازمند اداپترهای صریح هستند. راهحل — استفاده از راهبردهای lenient یا دسریالیسازهای سفارشی برای فیلدهای مشخص.
وقتی سرور فیلد اختیاری را وارد نمیکند، کد با خطا مواجه میشود. Optional در Swift و انواع nullable در Kotlin مشکل را حل میکنند: اگر فیلد null است یا در JSON وجود ندارد، ویژگی مقدار nil/null را میگیرد و برنامه به کار خود ادامه میدهد. برای فیلدهای اجباری، توجه به وجود آنها در سطح مشتری API قبل از دسریالیسازی ارزش دارد. Moshi و kotlinx.serialization به طور پیشفرض به همه فیلدها نیاز دارند — علامتگذاری nullable و مقادیر پیشفرض این محدودیت را برطرف میکنند.
تغییر ساختار JSON در سرور — منبع شایع کراشهای تولید است. روش استاندارد — نسخهبندی شما از طریق فیلد version در شیء ریشه و پشتیبانی از 2-3 نسخه قبلی در طرف مشتری. kotlinx.serialization به شما امکان میدهد چندین مدل را برای نسخههای مختلف اعلان کنید و پس از تجزیه و تحلیل اولیه به JsonElement، مناسب را بر اساس فیلد version انتخاب کنید. حفاظت اضافی — ignoreUnknownKeys برای فیلدهای جدید و مقادیر پیشفرض برای فیلدهایی که ممکن است حذف شوند.
| خطا | نشانه | کتابخانه با حفاظت |
|---|---|---|
| Type mismatch | DecodingError / استثنا | kotlinx — coerceInputValues = true |
| عدم وجود فیلد | کراش در دسترسی | Moshi — @Transient + default |
| فرمت نادرست تاریخ | خطای کدگشایی | JSONDecoder — dateDecodingStrategy |
| فیلدهای اضافی | نادیده گرفته یا کراش | kotlinx — ignoreUnknownKeys = true |
| Null در فیلد non-null | کراش زمان اجرا | Moshi — lenient + @Nullable |
ثبت خطاهای دسریالیسازی — روش اجباری در تولید است. decode را در do/catch بپیچید، JSON خام و نوع مدل مورد انتظار را در Crashlytics یا Sentry ثبت کنید. این به شما امکان میدهد سریعاً مشخص کنید که کدام فیلد کدام API و در کدام نسخه برنامه مشکل دارد. بدون ثبت، خطای دسریالیسازی مانند یک کراش اسرارآمیز بدون کنتکست به نظر میرسد.
سوالات متداول
تجزیه و تحلیل — تجزیه متن ساختاریافته به عناصر تشکیلدهنده بدون ایجاد اجباری مدل تایپشده. دسریالیسازی یک حالت ویژه از تجزیه و تحلیل است که نتیجه آن یک شیء کامل زبان با انواع ویژگی شناخته شده است. تجزیه و تحلیل میتواند جریانی باشد، دسریالیسازی همواره یک شیء کامل ایجاد میکند.
برای پروژه در Kotlin خالص، kotlinx.serialization توصیه میشود — در کامپایلر ادغام شده، از reflection استفاده نمیکند و از Kotlin Multiplatform پشتیبانی میکند. برای پروژه موجود در Java — Moshi با code generation. Gson را بهتر است برای پروژههای legacy بگذارید که جایگزینی آن نیازمند کار زیادی است.
در iOS از keyDecodingStrategy = .convertFromSnakeCase در JSONDecoder استفاده کنید. در Android در kotlinx.serialization برای هر فیلد از @SerialName استفاده کنید. در Moshi از @Json(name=«field_name») یا JsonAdapter.Factory سراسری استفاده کنید. سبک یکپارچه در سطح پروژه — best practice است که در قرارداد API توافق شده است.
عاملترین دلیل — null غیرمنتظره از سرور برای فیلدی که اجباری اعلان شده است. در توسعه، سرور دادههای کامل را برمیگرداند، در تولید پاسخ مختصری ارسال میشود. راهحل: تمام فیلدهای بالقوه غایب را به عنوان nullable (Kotlin) یا optional (Swift) علامتگذاری کنید، از ignoreUnknownKeys و مقادیر پیشفرض استفاده کنید.
Code generation (Moshi codegen، kotlinx.serialization، Codable) در بنچمارکهای Google 2-4 برابر سریعتر از reflection کار میکند. علاوه بر سرعت، تولید کد از نظر انواع ایمنتر است، نیازی به فراواندادهای کلاس در زمان اجرا ندارد، و خطاهای نوع در مرحله کامپایل گیرنتاری میشوند نه در لحظه دسریالیسازی.
نتیجهگیری
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید