Serileştirme ve ters serileştirme, nesnelerin iletim veya depolama için bir biçime dönüştürülmesinin temel süreçleridir. Mobil geliştirmede, bu mekanizmalar her ağ isteğinde, durum kaydetmede ve işlemler arası iletişimde kullanılır. MDN Web Docs, 2024'ye göre, JSON, web ve mobil uygulamalarda en popüler serileştirme biçimi olmaya devam ediyor ve XML ile Protocol Buffers'ı geride bırakıyor.
Önemli Noktalar
Serileştirme, bir uygulama nesnesini ağ iletimi veya disk depolama için uygun bir biçime dönüştürme sürecidir. Ters serileştirme, alınan verilerden nesneyi geri yükleyerek ters dönüşümü gerçekleştirir. Mobil geliştirmede, serileştirme API isteklerinde, ekran durumu kaydetmede, önbelleğe almada ve Intent veya Bundle aracılığıyla veri aktarımında kullanılır.
Uygulama bileşenleri arasındaki veya uygulama ile sunucu arasındaki her etkileşim serileştirme gerektirir. REST API'ler verileri JSON veya XML'de iletir, gRPC Protocol Buffers kullanır ve Android'de işlem içi iletişim Parcelable kullanır. Serileştirme olmadan, karmaşık bir nesneyi işlem sınırı boyunca geçirmek veya bir veritabanına kaydetmek imkansızdır.
// Serileştirmenin genel prensibi
data class User(
val id: Int,
val name: String,
val email: String
)
// Serileştirme: nesne -> JSON
fun serializeUser(user: User): String {
return """{"id":${user.id},"name":"${user.name}","email":"${user.email}"}"""
}
// Ters serileştirme: JSON -> nesne
fun deserializeUser(json: String): User? {
// JSON'ı nesneye ayrıştırma
return Gson().fromJson(json, User::class.java)
}
| Biçim | Boyut | Hız | Okunabilirlik | Tipleme |
|---|---|---|---|---|
| JSON | orta | yüksek | yüksek | dinamik |
| XML | büyük | orta | yüksek | XSD şeması |
| Protocol Buffers | küçük | çok yüksek | düşük | katı .proto |
| FlatBuffers | küçük | maksimum | düşük | katı .fbs |
JSON (JavaScript Object Notation), JavaScript nesne sözdizimine dayalı hafif bir metin biçimidir. JSON, dizeleri, sayıları, boolean değerlerini, dizileri ve iç içe nesneleri destekleyerek mobil uygulamalardaki çoğu veri aktarım senaryosunu kapsar. Biçim platformdan bağımsızdır: her ekosistem, ayrıştırma için yerleşik araçlar sağlar.
JSON, basitliği ve çok yönlülüğü sayesinde kazanır. Geliştirici, temel kullanım için bir şemaya ihtiyaç duymaz — yapı, ayrıştırma sırasında dinamik olarak belirlenir. Biçimin okunabilirliği hata ayıklamayı ve test etmeyi basitleştirir: sunucu yanıtı herhangi bir geliştirici aracında görüntülenebilir. Her iki mobil platformda da JSON, üçüncü taraf kitaplıklara gerek kalmadan yerel olarak işlenir.
// Codable — Swift'te yerel JSON serileştirme
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), yüksek performanslı sistemler için Google tarafından geliştirilen ikili bir serileştirme biçimidir. JSON'ın aksine, protobuf bir .proto dosyasında önceden tanımlanmış bir şema gerektirir, ancak önemli ölçüde daha küçük veri boyutu ve daha yüksek işleme hızı sağlar. Biçim, gRPC, Firebase Firestore ve Google'ın dahili hizmetlerinde kullanılır.
Bir protobuf şeması, her biri benzersiz bir numaraya sahip yazılı alanlarla mesajları tanımlar. protoc derleyicisi, serileştirme ve ters serileştirmeyi otomatik olarak gerçekleştiren hedef dilde sınıflar oluşturur. Protobuf, geriye dönük uyumluluğu kaybetmeden alan ekleme ve çıkarma kuralları aracılığıyla şema gelişimini destekler.
// user.proto'da şema tanımı
syntax = "proto3";
message User {
int32 id = 1;
string name = 2;
string email = 3;
repeated string roles = 4;
}
// Kotlin'de oluşturulan kod
val user = UserProto.User.newBuilder()
.setId(1)
.setName("John")
.setEmail("john@test.com")
.build()
val bytes: ByteArray = user.toByteArray()
XML (eXtensible Markup Language), katı yapı, ad alanı desteği ve XSD şemaları aracılığıyla doğrulama sunan bir biçimdir. XML, kompaktlık ve ayrıştırma hızı açısından JSON'ın gerisinde kalır, ancak Android geliştirmede düzen dosyaları, AndroidManifest, kaynaklar ve Gradle yapılandırmaları için talep görmeye devam etmektedir. iOS'ta XML, plist dosyalarında ve bazı eski hizmetlerde kullanılır.
Android, XML ayrıştırma için üç yaklaşım sunar: DOM (tüm belgeyi belleğe yükleme), SAX (olay odaklı akış ayrıştırma) ve XmlPullParser (karma bir yaklaşım). XmlPullParser, mobil cihazlar için önerilen seçenektir çünkü sınırlı bellekle verimli bir şekilde çalışır ve belgeyi okurken işlemeye olanak tanır.
// Android'de XmlPullParser
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!!)
}
Her platform kendi serileştirme araçlarını sunar. iOS'ta birincil mekanizma, JSONEncoder ve JSONDecoder ile Codable protokolüdür; Objective-C ise NSJSONSerialization kullanır. Android, Gson, Moshi ve kotlinx.serialization kitaplıklarını kullanır. İşlemler arası veri aktarımı için Android Parcelable kullanırken iOS NSKeyedArchiver kullanır. Kotlin projeleri giderek kotlinx.serialization'ı seçiyor — JetBrains'in çoklu platformu destekleyen ve yansımaya dayanmayan, Kotlin derleyici eklentisi aracılığıyla derleme zamanında serileştiriciler oluşturan çözümü.
Android, Intent ve Bundle için iki serileştirme mekanizmasını destekler. Serializable, yansıma kullanan standart bir Java mekanizmasıdır ve bu da daha düşük performansa yol açar. Parcelable, writeToParcel ve createFromParcel yöntemlerinin manuel olarak uygulanmasını gerektiren Android'e özgü bir protokoldür, ancak doğrudan bayt manipülasyonu sayesinde onlarca kat daha hızlı çalışır.
// Android'de Parcelable
@Parcelize
data class UserParcel(
val id: Int,
val name: String,
val email: String
) : Parcelable
// Intent aracılığıyla aktarım
val intent = Intent(this, DetailActivity::class.java)
intent.putExtra("user", userParcel)
startActivity(intent)
iOS'ta, denetleyiciler arasında veri aktarımı için Data'ya ön serileştirme ile Codable kullanılırken, işlemler arası iletişim için NSKeyedArchiver kullanılır ve nesneleri ikili Property List biçimine dönüştürür. Modern SwiftUI projeleri, uygulama modülleri arasında aktarım için JSONEncoder aracılığıyla veri kodlamayı tercih eder.
Güvenilmeyen verilerin yanlış ters serileştirilmesi güvenlik açıklarına yol açabilir. Serileştirme yoluyla saldırılar, Java'da geçersiz kılınan readObject yöntemlerinden veya üçüncü taraf kitaplıkların güvensiz ters serileştiricilerinden yararlanır. Android'de, güvenilmeyen kaynaklardan gelen veriler için Serializable'dan kaçınılmalı, bunun yerine Parcelable veya ters serileştirmeden sonra tüm alanların manuel doğrulaması kullanılmalıdır. iOS'ta JSONDecoder varsayılan olarak türler konusunda katıdır, ancak JSONSerialization ile çalışırken geliştiriciler koşullu dönüştürme yoluyla türleri kontrol etmelidir.
Bir serileştirme biçimi seçerken performans gereksinimleri, veri boyutu ve uyumluluk dikkate alınır. REST API'ler ve mikro hizmet mimarisi için JSON en uygun seçim olmaya devam ediyor — tüm platformlar ve diller tarafından desteklenmektedir. Yüksek yüklü sistemler ve sınırlı bant genişliğine sahip mobil uygulamalar için daha küçük boyut ve daha hızlı ters serileştirme sunan Protocol Buffers tercih edilir. XML yalnızca yapılandırma senaryolarında ve eski sistemlerle entegrasyonda haklı çıkar. Modern projelerde, ters serileştirme adımı olmayan ikili bir biçim olan FlatBuffers'ın popülaritesi de artıyor ve oyun motorlarında ve gecikmeye duyarlı uygulamalarda kullanılıyor. Her biçimin kendi nişi vardır ve doğru seçim doğrudan uygulama hızını ve tüketilen trafik miktarını etkiler.
Sıkça Sorulan Sorular
Serileştirme, bir uygulama nesnesinin ağ üzerinden gönderilebilen veya bir dosyaya kaydedilebilen bir biçimde paketlenmesidir. Bir nesnenin fotoğrafını çektiğinizi hayal edin — fotoğraf serileştirmedir ve fotoğraftan nesneyi geri yüklemek ters serileştirmedir.
JSON, insan tarafından okunabilen ve şema gerektirmeyen bir metin biçimidir. Protocol Buffers, zorunlu şeması (.proto) olan, önemli ölçüde daha küçük boyutlu ve daha yüksek hızlı ikili bir biçimdir. Protobuf yüksek yüklü sistemler için, JSON ise evrensel uyumluluk için seçilir.
XML, yapılandırma dosyaları (AndroidManifest, düzen kaynakları), karmaşık iç içe yapıya sahip belgeler ve XSD aracılığıyla katı doğrulama gerektiren sistemler için standart olmaya devam ediyor. XML ayrıca ad alanı desteği gerektiren SOAP protokollerinde ve eski sistemlerde de kullanılır.
Codable, otomatik serileştirme ve ters serileştirme için Encodable ve Decodable'ı birleştiren bir Swift protokolüdür. Derleyici, yapının veya sınıfın tüm özellikleri için encode(to:) ve init(from:) yöntemlerinin uygulanmasını oluşturur.
Parcelable, yansıma kullanmadığı ve alanları doğrudan bir bayt akışına yazdığı için Serializable'dan önemli ölçüde daha hızlı çalışır. Modern cihazlarda fark, Parcelable lehine 10 kata kadar çıkabilir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun