() translation by (you can also view the original English article)
Bertahan data meluncurkan aplikasi adalah persyaratan yang kebanyakan aplikasi iOS, menyimpan preferensi pengguna dalam sistem default untuk mengelola kumpulan data besar dalam sebuah database relasional. Dalam artikel ini, kita akan menjelajahi strategi yang paling umum digunakan untuk menyimpan data dalam aplikasi iOS. Saya juga akan berbicara tentang sistem file pada iOS dan bagaimana aplikasi sandboxing mempengaruhi data kekal.
Pengenalan
Anda telah datang jauh, belalang, dan Anda telah belajar banyak. Tapi ada satu aspek penting dari iOS pengembangan yang belum kita bahas Namun, data kekal. Hampir setiap aplikasi iOS menyimpan data untuk digunakan nanti. Data toko aplikasi Anda bisa apa saja dari preferensi pengguna sementara cache atau bahkan besar set data relasional.
Sebelum membahas strategi yang paling umum data ketekunan pengembang memiliki di iOS platform, saya akan menghabiskan beberapa menit membahas sistem file dan konsep sandboxing aplikasi. Apakah Anda benar-benar berpikir Anda bisa menyimpan data aplikasi Anda dimanapun Anda 'd seperti pada sistem file? Pikir lagi, padawan.
Sistem file dan aplikasi Sandboxing
Keamanan di iOS platform telah menjadi salah satu prioritas utama Apple sejak iPhone diperkenalkan pada tahun 2007. Berbeda dengan aplikasi OS X, iOS aplikasi ditempatkan di sandbox aplikasi. Sandbox aplikasi tidak hanya merujuk ke direktori sandbox aplikasi dalam sistem file. Ini juga mencakup dikontrol dan terbatas akses ke data pengguna yang disimpan pada perangkat, Layanan sistem, dan perangkat keras.
Dengan diperkenalkannya Mac App Store, Apple telah mulai menegakkan sandboxing aplikasi pada OS X juga. Meskipun kendala mengenakan aplikasi OS X tidak sebagai ketat sebagai orang-orang yang dikenakan pada aplikasi iOS, konsep dasar sama. Ada perbedaan, meskipun. Sandbox aplikasi aplikasi iOS, misalnya, berisi bundel aplikasi, yang tidak benar untuk aplikasi OS X. Alasan untuk perbedaan ini terutama sejarah.
Sandboxing dan direktori
Sistem operasi menginstal setiap aplikasi iOS dalam direktori kotak pasir yang berisi direktori bundel aplikasi dan tiga direktori tambahan, Dokumen, Perpustakaan, dan tmp. Direktori kotak pasir aplikasi, sering disebut sebagai direktori home-nya, dapat diakses dengan memanggil fungsi Foundation sederhana, NSHomeDirectory ().
1 |
print(NSHomeDirectory()) |
Anda dapat mencoba ini sendiri. Membuat proyek Xcode baru berdasarkan template aplikasi pemandangan tunggal dan nama itu Data kekal.



Buka AppDelegate.swift dan menambahkan potongan kode di atas ke application(_:didFinishLaunchingWithOptions:). Jika Anda menjalankan aplikasi dalam simulator, output di konsol akan terlihat seperti ini:
1 |
/Users/Bart/Library/Developer/CoreSimulator/Devices/14F00EFB-2EAB-438C-B401-7FEFDA1D94AB/data/Containers/Data/Application/81B23594-3BA2-4AF9-B91A-F74A53FD6945 |
Namun, jika Anda menjalankan aplikasi di perangkat fisik, output akan terlihat sedikit berbeda seperti yang Anda lihat di bawah ini. Sandbox aplikasi dan keterbatasan yang ditetapkan yang identik, walaupun.
1 |
/var/mobile/Containers/Data/Application/41E7939B-6A39-4005-9C28-372FD9C7AD99 |
Mengambil path ke direktori dokumen aplikasi memerlukan sedikit lebih banyak pekerjaan seperti yang Anda lihat dalam potongan kode berikutnya.
1 |
let directories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) |
2 |
|
3 |
if let documents = directories.first { |
4 |
print(documents) |
5 |
}
|
Kita memanggil fungsi NSSearchPathForDirectoriesInDomains(), yang didefinisikan dalam kerangka dasar. Sebagai argumen pertama, kami menyampaikan dalam DocumentDirectory tipe NSSearchPathDirectory untuk menunjukkan bahwa kami hanya tertarik dengan direktori Dokumen aplikasi. Argumen kedua dan ketiga kurang penting untuk diskusi kita. Fungsi mengembalikan array tipe [String], yang berisi satu hasil, path ke direktori Dokumen aplikasi.
Mengapa Sandboxing?
Apakah manfaat dari sandboxing? Alasan utama untuk sandboxing aplikasi adalah keamanan. Dengan membatasi aplikasi untuk sandbox sendiri, dikompromikan aplikasi tidak menyebabkan kerusakan sistem operasi atau aplikasi lain.
Dengan aplikasi yang dikompromikan, maksud saya kedua aplikasi yang telah diretas, aplikasi yang sengaja jahat, serta aplikasi yang mengandung bug penting yang mungkin secara tidak sengaja menyebabkan kerusakan.
Meskipun aplikasi sandboxed di iOS platform, aplikasi dapat meminta akses ke file atau aset yang di luar sandbox aplikasi mereka melalui sejumlah antarmuka sistem tertentu. Contoh ini adalah perpustakaan musik yang disimpan pada perangkat. Tahu, bagaimanapun, bahwa kerangka kerja sistem bertanggung jawab atas operasi berkaitan dengan akses file.
Apa yang terjadi di mana?
Meskipun Anda dapat melakukan banyak hal yang Anda inginkan di kotak pasir aplikasi Anda, Apple telah memberikan beberapa panduan terkait dengan apa yang harus disimpan di mana. Penting untuk mengetahui tentang pedoman ini karena beberapa alasan. Ketika perangkat iOS dicadangkan ke komputer Anda atau ke iCloud, tidak semua file di kotak pasir disertakan dalam cadangan.
Direktori tmp, misalnya, harus hanya digunakan untuk sementara menyimpan file. Sistem operasi gratis untuk mengosongkan direktori ini setiap saat, misalnya, ketika perangkat rendah pada ruang disk. Direktori tmp tidak disertakan dalam backup.
Direktori dokumen dimaksudkan untuk data pengguna, sedangkan Perpustakaan direktori yang digunakan untuk aplikasi data yang ketat tidak terikat kepada pengguna. Direktori cache dalam direktori Perpustakaan adalah direktori lain yang tidak didukung.
Juga perlu diingat bahwa aplikasi Anda tidak seharusnya mengubah konten direktori bundel aplikasi. Direktori bundel aplikasi ditandatangani ketika aplikasi diinstal. Dengan memodifikasi isi direktori bundel aplikasi dengan cara apa pun, tanda tangan yang disebutkan tadi diubah, yang berarti sistem operasi tidak mengizinkan aplikasi untuk diluncurkan lagi. Ini adalah ukuran keamanan lain yang diletakkan pada tempatnya oleh Apple untuk melindungi pelanggan.
Opsi ketekunan data
Ada beberapa strategi untuk menyimpan aplikasi data pada disk. Dalam artikel ini, kita mengambil singkat melihat empat pendekatan umum pada iOS:
- sistem default
- Daftar properti
- SQLite
- Data inti
Mengakses opsi yang diuraikan dalam artikel ini tidak boleh dianggap sebagai dipertukarkan. Strategi masing-masing memiliki manfaat dan kelemahan. Mari kita mulai dengan melihat pada sistem default.
Pengguna default
Sistem default adalah sesuatu yang mewarisi iOS dari OS X. Meskipun itu dibuat dan dirancang untuk menyimpan preferensi pengguna, dapat digunakan untuk menyimpan setiap jenis data selama itu adalah jenis daftar properti, NSString, NSNumber, NSDate, NSArray, NSDictionary, dan NSData, atau salah satu varian bisa berubah.
Apa tentang jenis data yang cepat? Untungnya, Swift cukup pintar. Dapat menyimpan string dan angka dengan mengubah mereka untuk NSString dan NSNumber. Sama berlaku untuk Swift array dan kamus.
Sistem default adalah tidak lebih dari sebuah koleksi properti daftar, daftar properti satu per aplikasi. Daftar properti disimpan dalam folder preferensi di folder Perpustakaan aplikasi, mengisyaratkan pada daftar properti tujuan dan fungsi.
Salah satu alasan bahwa pengembang seperti sistem default adalah karena itu sangat mudah digunakan. Lihatlah contoh berikut untuk melihat apa maksud saya.
1 |
let userDefaults = NSUserDefaults.standardUserDefaults() |
2 |
|
3 |
// Setting Values
|
4 |
userDefaults.setBool(true, forKey: "Key1") |
5 |
userDefaults.setInteger(123, forKey: "Key2") |
6 |
userDefaults.setObject("Some Object", forKey: "Key3") |
7 |
userDefaults.setObject([1, 2, 3, 4], forKey: "Key4") |
8 |
|
9 |
// Getting Values
|
10 |
userDefaults.boolForKey("Key1") |
11 |
userDefaults.integerForKey("Key2") |
12 |
userDefaults.objectForKey("Key3") |
13 |
userDefaults.objectForKey("Key4") |
14 |
|
15 |
userDefaults.synchronize() |
Dengan memanggil standardUserDefaults() NSUserDefaults, referensi ke objek bersama default dikembalikan.
Pada baris terakhir, kita memanggil synchronize() pada objek bersama default menulis perubahan ke disk. Hal ini jarang diperlukan untuk memohon synchronize(), karena sistem default menyimpan perubahan bila diperlukan. Namun, jika Anda menyimpan atau memperbarui pengaturan yang menggunakan sistem default, kadang-kadang bisa berguna atau diperlukan untuk secara eksplisit menyimpan perubahan ke disk.
Pada pandangan pertama, sistem default tampaknya tak lebih dari sebuah toko kunci-nilai yang terletak di lokasi tertentu. Namun, NSUserDefaults kelas, yang didefinisikan dalam rangka Foundation, adalah lebih dari sebuah antarmuka untuk mengelola sebuah toko kunci-nilai. Lihatlah kelas dengan referensi untuk informasi lebih lanjut.
Sebelum kita melanjutkan, menyisipkan potongan kode di atas dalam aplikasi delegasi application(_:didFinishLaunchingWithOptions:) metode dan menjalankan aplikasi dalam simulator. Buka jendela Finder baru dan navigasikan ke Perpustakaan > pengembang > CoreSimulator > perangkat > <DEVICE_ID>> data > wadah > Data > aplikasi > <APPLICATION_ID>.</APPLICATION_ID> </DEVICE_ID>
<DEVICE_ID>dan <APPLICATION_ID>adalah dua pengidentifikasi unik untuk simulator dan aplikasi masing-masing.</APPLICATION_ID></DEVICE_ID> Lokasi sandbox aplikasi untuk simulator tergantung pada versi Xcode menggunakan. Jika Anda tidak menggunakan Xcode 7, jalan mungkin akan berbeda.
Anda dapat membuat hidup Anda lebih mudah dengan mencetak path ke direktori home aplikasi Anda untuk konsol Xcode's. Tambahkan berikut mencetak pernyataan untuk application(_:didFinishLaunchingWithOptions:).
1 |
print(NSHomeDirectory()) |
Folder bernama cryptically adalah direktori sandbox aplikasi. Di direktori kotak pasir aplikasi, buka folder Preferensi, yang terletak di folder Perpustakaan, dan periksa isinya.



Anda harus melihat daftar properti dengan nama yang identik dengan pengenal bundel aplikasi. Ini adalah penyimpanan default pengguna untuk aplikasi Anda. Ini adalah apa yang tampak seperti daftar properti dalam editor teks. Seperti yang Anda lihat, daftar properti akan disimpan pada disk sebagai sebuah file XML.
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3 |
<plist version="1.0"> |
4 |
<dict>
|
5 |
<key>Key1</key> |
6 |
<true/>
|
7 |
<key>Key2</key> |
8 |
<integer>123</integer> |
9 |
<key>Key3</key> |
10 |
<string>Some Object</string> |
11 |
<key>Key4</key> |
12 |
<array>
|
13 |
<integer>1</integer> |
14 |
<integer>2</integer> |
15 |
<integer>3</integer> |
16 |
<integer>4</integer> |
17 |
</array>
|
18 |
</dict>
|
19 |
</plist>
|
Jika Anda ingin membuat mengakses sandbox aplikasi dalam simulator mudah, kemudian saya mendorong Anda untuk melihat di SimPholders. Ini adalah utilitas kecil yang membuat bekerja dengan simulator jauh, jauh lebih mudah.
Daftar properti
Kita sudah dibahas daftar properti dalam seri ini. Sebagai soal fakta, Toko dukungan pengguna default database adalah daftar properti. Menggunakan properti daftar adalah strategi yang mudah untuk menyimpan dan mengambil objek grafik. Daftar properti telah sekitar selama berabad-abad, mudah digunakan, dan, oleh karena itu, mereka pilihan yang besar untuk menyimpan data dalam aplikasi iOS.
Seperti yang saya sebutkan sebelumnya, sangat penting untuk diingat bahwa daftar properti hanya dapat menyimpan data daftar properti. Apakah ini berarti bahwa hal itu tidak mungkin untuk menyimpan benda-benda custom model yang menggunakan properti daftar? Itu mungkin. Namun, custom model objek perlu Diarsipkan — bentuk serialisasi — sebelum mereka dapat disimpan dalam daftar properti. Pengarsipan objek hanya berarti bahwa objek harus dikonversi ke jenis data yang dapat disimpan dalam daftar properti, seperti contoh NSData.
Pengarsipan objek
Apakah Anda ingat NSCoding protokol yang didefinisikan dalam kerangka dasar? Protokol NSCoding mendefinisikan dua methods,init(coder:) dan encodeWithCoder(_:). Kelas yang mengimplementasikan metode ini untuk memungkinkan contoh kelas harus dikodekan dan diterjemahkan.
Encoding dan decoding adalah mekanisme yang mendasari untuk arsip objek dan distribusi. Bagaimana bekerja Arsip objek akan menjadi jelas sedikit kemudian di seri ini. Dalam pelajaran ini, saya hanya akan menunjukkan bagaimana untuk menulis array dan kamus ke disk menggunakan properti daftar.
Menulis ke File
Kode snippet berikut ini akan memberikan Anda gambaran betapa mudahnya untuk menulis array atau Kamus ke disk. Dalam teori, grafik objek yang tersimpan dalam daftar properti dapat sebagai kompleks atau sebagai besar seperti yang Anda inginkan. Namun, perlu diingat bahwa daftar properti ini tidak dimaksudkan untuk menyimpan puluhan atau ratusan megabyte data, mereka mencoba menggunakan hasil mungkin akan cara dalam kinerja terdegradasi.
1 |
let directories = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) |
2 |
|
3 |
if let documents = directories.first { |
4 |
if let urlDocuments = NSURL(string: documents) { |
5 |
let urlFruits = urlDocuments.URLByAppendingPathComponent("fruits.plist") |
6 |
let urlDictionary = urlDocuments.URLByAppendingPathComponent("dictionary.plist") |
7 |
|
8 |
// Write Array to Disk
|
9 |
let fruits = ["Apple", "Mango", "Pineapple", "Plum", "Apricot"] as NSArray |
10 |
let dictionary = ["anArray" : fruits, "aNumber" : 12345, "aBoolean" : true] as NSDictionary |
11 |
|
12 |
fruits.writeToFile(urlFruits.path!, atomically: true) |
13 |
dictionary.writeToFile(urlDictionary.path!, atomically: true) |
14 |
|
15 |
// Load from Disk
|
16 |
let loadedFruits = NSArray(contentsOfURL: urlFruits) |
17 |
if let fruits = loadedFruits { |
18 |
print(fruits) |
19 |
}
|
20 |
|
21 |
let loadedDictionary = NSDictionary(contentsOfURL: urlDictionary) |
22 |
if let dictionary = loadedDictionary { |
23 |
print(dictionary) |
24 |
}
|
25 |
}
|
26 |
}
|
Mari kita lihat di snipet kode di atas. Kita mulai dengan menyimpan referensi ke array literal dalam variabel bernama buah-buahan. Kami membuat URL file untuk menyimpan daftar properti yang kita akan membuat. URL file yang dibuat oleh menambahkan string ke URL file direktori dokumen. Kami menambahkan string adalah nama dari daftar properti yang kita buat di kedua, termasuk extensinya, .plist.
Menulis array disk semudah memanggil writeToFile(_:atomically:) array. Anda dapat mengabaikan atomically bendera untuk sekarang. Sebagai contoh menggambarkan, menulis sebuah kamus ke disk mengikuti pola yang sama. Contoh juga menggambarkan bagaimana membuat array dan kamus dari daftar properti, tapi ini adalah sesuatu yang kita sudah dibahas sebelumnya dalam seri ini. Menjalankan aplikasi dalam simulator dan navigasikan ke direktori dokumen aplikasi. Dalam direktori ini, Anda akan melihat daftar dua properti yang kami hanya dibuat.



Ini adalah apa yang daftar properti Kamus tampak seperti ketika Anda membukanya dalam editor teks.
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
3 |
<plist version="1.0"> |
4 |
<dict>
|
5 |
<key>aBoolean</key> |
6 |
<true/>
|
7 |
<key>aNumber</key> |
8 |
<integer>12345</integer> |
9 |
<key>anArray</key> |
10 |
<array>
|
11 |
<string>Apple</string> |
12 |
<string>Mango</string> |
13 |
<string>Pineapple</string> |
14 |
<string>Plum</string> |
15 |
<string>Apricot</string> |
16 |
</array>
|
17 |
</dict>
|
18 |
</plist>
|
SQLite
Jika aplikasi Anda adalah data didorong dan bekerja dengan data dalam jumlah besar, maka Anda mungkin ingin melihat ke dalam SQLite. Apa itu SQLite? Slogan di situs web SQLite berbunyi "kecil. Cepat. Dapat diandalkan. Memilih tiga. ", yang merangkum semua itu dengan baik.
SQLite adalah sebuah perpustakaan yang menerapkan database relasional tertanam ringan. Seperti namanya, itu adalah berdasarkan standar SQL (Structured Query Language) seperti MySQL dan PostgreSQL.
Perbedaan utama dengan database SQL lainnya adalah bahwa SQLite portabel dan sangat ringan. Bukan proses terpisah diakses dari aplikasi klien, SQLite serverless. Dengan kata lain, hal ini telah tertanam dalam aplikasi atau dikelola oleh sistem aplikasi yang berjalan pada, yang berarti sangat cepat.
SQLite website mengklaim bahwa itu adalah database SQL yang paling banyak digunakan. Aku tidak tahu jika ini masih terjadi, tetapi itu adalah jelas pilihan populer untuk penyimpanan data sisi klien. Keuntungan SQLite memiliki bekerja secara langsung dengan objek adalah bahwa SQLite banyak, jauh lebih cepat. Hal ini terutama disebabkan bagaimana relasional dan berorientasi objek bahasa pemrograman pada dasarnya berbeda.
Untuk menjembatani kesenjangan antara SQLite dan Objective-C, sejumlah solusi Object Relational Mapping (ORM) telah diciptakan dari waktu ke waktu. ORM bahwa Apple telah dibuat untuk iOS dan OS X ini dinamai inti Data, yang akan kita lihat kemudian dalam pelajaran ini.
Terbang daging itu FMDB
Menggunakan SQLite pada iOS berarti bekerja dengan sebuah perpustakaan berbasis C. Jika Anda memilih solusi berorientasi objek, maka saya sangat menyarankan Gus Mueller (Flying daging, Inc) Tujuan-C wrapper untuk SQLite, FMDB.
Perpustakaan adalah sangat performant. Saya telah menggunakan FMDB di masa lalu dan telah sangat senang dengan API dan Perpustakaan ketahanan dan keandalan.
Data inti
Pengembang baru untuk Data inti sering kesalahan Data inti untuk database sementara itu benar-benar solusi pemetaan relasional objek yang dibuat dan dikelola oleh Apple. Matt Gallagher telah menulis besar posting tentang perbedaan antara Data inti dan database. Data inti menyediakan model relasional berorientasi objek yang dapat serial ke XML, biner, atau SQLite toko. Data inti bahkan memiliki dukungan untuk Toko di memori.
Mengapa Anda menggunakan Data Inti daripada SQLite? Dengan mengajukan pertanyaan ini, Anda salah menganggap bahwa Core Data adalah database. Keuntungan menggunakan Data Inti adalah Anda bekerja dengan objek bukan data mentah, seperti baris dalam database SQLite atau data yang disimpan dalam file XML. Meskipun Core Data memiliki beberapa tahun yang sulit ketika pertama kali dirilis, ia telah tumbuh menjadi kerangka kerja yang kuat dengan banyak fitur, termasuk migrasi otomatis, pelacakan perubahan, kesalahan, dan validasi terintegrasi.
Fitur hebat lain yang banyak disukai oleh pengembang adalah editor model Data Inti, yang dibangun di dalam Xcode. Editor memungkinkan pengembang memodelkan model data aplikasi melalui antarmuka grafis.



Apakah Data inti adalah solusi yang tepat untuk aplikasi Anda tergantung pada data yang Anda berencana untuk mengelola, baik dari segi jumlah data serta model dasar. Jika Anda berencana untuk mengelola sangat besar set data, kemudian inti Data bisa menjadi bottleneck kinerja dari waktu ke waktu. Dalam hal ini, SQLite mungkin solusi yang lebih baik.
iCloud
Anda mungkin pernah mendengar tentang iCloud dan Anda mungkin bertanya-tanya mana iCloud cocok ke dalam kisah data kekal. Tidak seperti SQLite dan Data inti, iCloud bukan bentuk data kekal. Sebaliknya, itu adalah sebuah platform atau layanan untuk membuat data pengguna yang tersedia di beberapa perangkat dan beberapa contoh aplikasi- atau bahkan keluarga aplikasi.
ICloud platform meliputi beberapa layanan atau komponen. Komponen yang kepentingan kita adalah iCloud penyimpanan, yang mencakup empat jenis penyimpanan:
- CloudKit
- kunci-nilai Penyimpanan
- penyimpanan dokumen
- Penyimpanan Data inti
Jika Anda ingin membaca lebih lanjut tentang iCloud penyimpanan, saya sarankan membaca seri tentang iCloud penyimpanan.
Kesimpulan
Anda sekarang harus memiliki ide yang baik dari pilihan Anda harus menyimpan data ketika mengembangkan untuk iOS platform. Perlu diingat bahwa tidak semua strategi yang kita telah membahas sama.
Seri ini perlahan-lahan datang ke dekat. Dalam dua angsuran, kita akan menciptakan aplikasi lain untuk meletakkan apa yang telah kita pelajari sejauh ini ke dalam praktek. Cara terbaik untuk belajar adalah dengan melakukan.
Jika Anda memiliki pertanyaan atau komentar, Anda dapat meninggalkannya di komentar di bawah atau menghubungi saya di Twitter.