Saya telah mengerjakan metode untuk menyinkronkan data inti yang disimpan dalam aplikasi iPhone antara beberapa perangkat, seperti iPad atau Mac. Tidak banyak (jika ada sama sekali) kerangka kerja sinkronisasi untuk digunakan dengan Core Data di iOS. Namun, saya telah memikirkan konsep berikut:
- Perubahan dibuat ke penyimpanan data inti lokal, dan perubahan disimpan. (a) Jika perangkat online, ia mencoba untuk mengirim perubahan ke server, termasuk ID perangkat dari perangkat yang mengirim perubahan tersebut. (B) Jika perubahan tidak mencapai server, atau jika perangkat tidak online, aplikasi akan menambahkan perubahan yang diatur ke antrian untuk mengirim ketika itu online.
- Server, yang duduk di cloud, menggabungkan set perubahan spesifik yang diterimanya dengan database masternya.
- Setelah set perubahan (atau antrian set perubahan) digabungkan pada server cloud, server mendorong semua set perubahan tersebut ke perangkat lain yang terdaftar di server menggunakan semacam sistem polling. (Saya berpikir untuk menggunakan layanan Push Apple, tetapi menurut komentar ternyata ini bukan sistem yang bisa diterapkan.)
Apakah ada hal mewah yang perlu saya pikirkan? Saya telah melihat kerangka kerja REST seperti ObjectiveResource , Core Resource , dan RestfulCoreData . Tentu saja, ini semua bekerja dengan Ruby on Rails, yang saya tidak terikat, tetapi ini adalah tempat untuk memulai. Persyaratan utama yang saya miliki untuk solusi saya adalah:
- Setiap perubahan harus dikirim di latar belakang tanpa menghentikan utas utama.
- Seharusnya menggunakan bandwidth sesedikit mungkin.
Saya telah memikirkan sejumlah tantangan:
- Memastikan bahwa ID objek untuk penyimpanan data yang berbeda pada perangkat yang berbeda terpasang pada server. Artinya, saya akan memiliki tabel ID objek dan ID perangkat, yang diikat melalui referensi ke objek yang disimpan dalam database. Saya akan memiliki catatan (DatabaseId [unik untuk tabel ini], ObjectId [unik untuk item di seluruh database], Datafield1, Datafield2), bidang ObjectId akan merujuk tabel lain, AllObjects: (ObjectId, DeviceId, DeviceObjectId). Kemudian, ketika perangkat mendorong set perubahan, itu akan melewati ID perangkat dan objekId dari objek data inti di penyimpanan data lokal. Kemudian server cloud saya akan memeriksa terhadap objectId dan ID perangkat di tabel AllObjects, dan menemukan catatan untuk berubah di tabel awal.
- Semua perubahan harus diberi stempel waktu, sehingga dapat digabungkan.
- Perangkat harus menyurvei server, tanpa menggunakan baterai terlalu banyak.
- Perangkat lokal juga perlu memperbarui apa pun yang tersimpan dalam memori jika / ketika perubahan diterima dari server.
Apakah ada hal lain yang saya lewatkan di sini? Kerangka kerja seperti apa yang harus saya perhatikan untuk memungkinkan hal ini?
Jawaban:
Saya sarankan untuk membaca dan menerapkan strategi sinkronisasi yang dibahas oleh Dan Grover dengan saksama di konferensi iPhone 2009, tersedia di sini sebagai dokumen pdf.
Ini adalah solusi yang layak dan tidak terlalu sulit untuk diterapkan (Dan mengimplementasikan ini di beberapa aplikasinya), tumpang tindih dengan solusi yang dijelaskan oleh Chris. Untuk diskusi teoretis yang mendalam tentang sinkronisasi, lihat makalah dari Russ Cox (MIT) dan William Josephson (Princeton):
Sinkronisasi File dengan Pasangan Waktu Vektor
yang berlaku sama baiknya untuk data inti dengan beberapa modifikasi yang jelas. Ini memberikan strategi sinkronisasi yang jauh lebih kuat dan andal, tetapi membutuhkan lebih banyak upaya untuk diimplementasikan dengan benar.
EDIT:
Tampaknya file pdf Grover tidak lagi tersedia (tautan rusak, Maret 2015). UPDATE: tautan tersedia melalui Way Back Machine di sini
Kerangka Objective-C yang disebut ZSync dan dikembangkan oleh Marcus Zarra telah ditinggalkan, mengingat bahwa iCloud akhirnya tampaknya mendukung sinkronisasi data inti yang benar.
sumber
Saya telah melakukan sesuatu yang mirip dengan apa yang Anda coba lakukan. Biarkan saya memberi tahu Anda apa yang telah saya pelajari dan bagaimana saya melakukannya.
Saya berasumsi Anda memiliki hubungan satu-ke-satu antara objek Data Inti Anda dan model (atau skema db) di server. Anda hanya ingin menjaga konten server tetap sinkron dengan klien, tetapi klien juga dapat memodifikasi dan menambahkan data. Jika saya benar, maka teruslah membaca.
Saya menambahkan empat bidang untuk membantu sinkronisasi:
Pada klien, tambahkan kode untuk mengatur sync_status ke 1 pada objek model Anda setiap kali ada perubahan dan perlu disinkronkan ke server. Objek model baru harus menghasilkan GUID.
Sinkronisasi adalah satu permintaan. Permintaan berisi:
Server menerima permintaan dan melakukan ini:
Aplikasi menerima respons dan melakukan ini:
Saya harap itu membantu. Saya menggunakan catatan kata dan model secara bergantian, tetapi saya pikir Anda mendapatkan idenya. Semoga berhasil.
sumber
MAX(last_modified)
, tetapi itu akan menjadi berlebihan karenaMAX(last_modified)
sudah cukup. Merekasync_status
memiliki peran lain. Seperti yang saya tulis sebelumnya,MAX(last_modified)
menentukan apa yang perlu disinkronkan dari server, sementarasync_status
menentukan apa yang perlu disinkronkan ke server.Jika Anda masih mencari cara untuk pergi, lihat ke ponsel Couchbase. Ini pada dasarnya melakukan semua yang Anda inginkan. ( http://www.couchbase.com/nosql-databases/couchbase-mobile )
sumber
Mirip seperti @Cris, saya telah mengimplementasikan kelas untuk sinkronisasi antara klien dan server dan menyelesaikan semua masalah yang diketahui sejauh ini (mengirim / menerima data ke / dari server, menggabungkan konflik berdasarkan cap waktu, menghapus entri duplikat dalam kondisi jaringan yang tidak dapat diandalkan, menyinkronkan data bertingkat dan file dll.)
Anda cukup memberi tahu kelas entitas mana dan kolom mana yang harus disinkronkan dan di mana server Anda.
Anda dapat menemukan sumber, contoh kerja dan instruksi lainnya di sini: github.com/knagode/M3Sinkronisasi .
sumber
Perhatikan pengguna untuk memperbarui data melalui pemberitahuan push. Gunakan utas latar belakang di aplikasi untuk memeriksa data lokal dan data di server cloud, sementara perubahan terjadi di server, ubah data lokal, dan sebaliknya.
Jadi saya pikir bagian yang paling sulit adalah memperkirakan data di sisi mana yang tidak valid.
Semoga ini bisa membantu kamu
sumber
Saya baru saja memposting versi pertama API Penyinkronan Data Cloud Core baru saya, yang dikenal sebagai SynCloud. SynCloud memiliki banyak perbedaan dengan iCloud karena memungkinkan untuk antarmuka sinkronisasi multi-pengguna. Ini juga berbeda dari api sinkronisasi lainnya karena memungkinkan untuk data relasional multi-tabel.
Silakan mencari tahu lebih lanjut di http://www.syncloudapi.com
Dibangun dengan iOS 6 SDK, ini sangat terkini pada 9/27/2012.
sumber
Saya pikir solusi yang baik untuk masalah GUID adalah "sistem ID terdistribusi". Saya tidak yakin apa istilah yang benar, tetapi saya pikir itulah yang digunakan oleh MS SQL server untuk menyebutnya (SQL menggunakan / menggunakan metode ini untuk database terdistribusi / sinkronisasi). Sederhana saja:
Server memberikan semua ID. Setiap kali sinkronisasi dilakukan, hal pertama yang diperiksa adalah "Berapa banyak ID yang tersisa pada klien ini?" Jika klien hampir habis, ia meminta server untuk blok ID baru. Klien kemudian menggunakan ID dalam rentang itu untuk catatan baru. Ini berfungsi baik untuk sebagian besar kebutuhan, jika Anda dapat menetapkan blok yang cukup besar sehingga "tidak" habis sebelum sinkronisasi berikutnya, tetapi tidak terlalu besar sehingga server habis seiring waktu. Jika klien pernah kehabisan, penanganannya bisa sangat sederhana, cukup beri tahu pengguna "maaf Anda tidak dapat menambahkan lebih banyak item sampai Anda menyinkronkan" ... jika mereka menambahkan banyak item, sebaiknya mereka tidak menyinkronkan untuk menghindari data yang sudah basi masalah sih?
Saya pikir ini lebih unggul daripada menggunakan GUID acak karena GUID acak tidak 100% aman, dan biasanya perlu lebih lama dari ID standar (128-bit vs 32-bit). Anda biasanya memiliki indeks berdasarkan ID dan sering menyimpan nomor ID dalam memori, jadi penting untuk tetap kecil.
Tidak benar-benar ingin memposting sebagai jawaban, tetapi saya tidak tahu bahwa ada orang yang akan melihat sebagai komentar, dan saya pikir ini penting untuk topik ini dan tidak termasuk dalam jawaban lain.
sumber
Pertama, Anda harus memikirkan kembali berapa banyak data, tabel, dan hubungan yang akan Anda miliki. Dalam solusi saya, saya telah menerapkan sinkronisasi melalui file Dropbox. Saya mengamati perubahan di MOC utama dan menyimpan data ini ke file (setiap baris disimpan sebagai gzipped json). Jika ada koneksi internet yang berfungsi, saya memeriksa apakah ada perubahan di Dropbox (Dropbox memberi saya perubahan delta), unduh dan gabungkan (kemenangan terbaru), dan akhirnya masukkan file yang diubah. Sebelum sinkronisasi saya meletakkan file kunci di Dropbox untuk mencegah klien lain menyinkronkan data yang tidak lengkap. Saat mengunduh perubahan, aman bahwa hanya sebagian data yang diunduh (mis. Koneksi internet terputus). Ketika pengunduhan selesai (sepenuhnya atau sebagian) mulai memuat file ke dalam Data Inti. Ketika ada hubungan yang tidak terselesaikan (tidak semua file diunduh) itu berhenti memuat file dan mencoba untuk menyelesaikan mengunduh nanti. Relasi disimpan hanya sebagai GUID, jadi saya dapat dengan mudah memeriksa file mana yang dimuat agar memiliki integritas data penuh. Sinkronisasi dimulai setelah perubahan data inti dilakukan. Jika tidak ada perubahan, selain memeriksa perubahan di Dropbox setiap beberapa menit dan pada startup aplikasi. Tambahan pula ketika perubahan dikirim ke server saya mengirim siaran ke perangkat lain untuk memberi tahu mereka tentang perubahan, sehingga mereka dapat melakukan sinkronisasi lebih cepat. Setiap entitas yang disinkronkan memiliki properti GUID (panduan juga digunakan sebagai nama file untuk bertukar file). Saya juga menyinkronkan basis data tempat saya menyimpan revisi Dropbox untuk setiap file (saya dapat membandingkannya ketika delta Dropbox menyetel ulang statusnya). File juga mengandung nama entitas, status (dihapus / tidak dihapus), panduan (sama dengan nama file), revisi basis data (untuk mendeteksi migrasi data atau untuk menghindari sinkronisasi dengan versi aplikasi yang tidak pernah) dan tentu saja data (jika baris tidak dihapus). jadi saya bisa dengan mudah memeriksa file mana yang akan dimuat untuk memiliki integritas data penuh. Sinkronisasi dimulai setelah perubahan data inti dilakukan. Jika tidak ada perubahan, selain memeriksa perubahan di Dropbox setiap beberapa menit dan pada startup aplikasi. Tambahan pula ketika perubahan dikirim ke server saya mengirim siaran ke perangkat lain untuk memberi tahu mereka tentang perubahan, sehingga mereka dapat melakukan sinkronisasi lebih cepat. Setiap entitas yang disinkronkan memiliki properti GUID (panduan juga digunakan sebagai nama file untuk bertukar file). Saya juga menyinkronkan basis data tempat saya menyimpan revisi Dropbox untuk setiap file (saya dapat membandingkannya ketika delta Dropbox menyetel ulang statusnya). File juga mengandung nama entitas, status (dihapus / tidak dihapus), panduan (sama dengan nama file), revisi basis data (untuk mendeteksi migrasi data atau untuk menghindari sinkronisasi dengan versi aplikasi yang tidak pernah) dan tentu saja data (jika baris tidak dihapus). jadi saya bisa dengan mudah memeriksa file mana yang akan dimuat untuk memiliki integritas data penuh. Sinkronisasi dimulai setelah perubahan data inti dilakukan. Jika tidak ada perubahan, selain memeriksa perubahan di Dropbox setiap beberapa menit dan pada startup aplikasi. Tambahan pula ketika perubahan dikirim ke server saya mengirim siaran ke perangkat lain untuk memberi tahu mereka tentang perubahan, sehingga mereka dapat melakukan sinkronisasi lebih cepat. Setiap entitas yang disinkronkan memiliki properti GUID (panduan juga digunakan sebagai nama file untuk bertukar file). Saya juga menyinkronkan basis data tempat saya menyimpan revisi Dropbox untuk setiap file (saya dapat membandingkannya ketika delta Dropbox menyetel ulang statusnya). File juga mengandung nama entitas, status (dihapus / tidak dihapus), panduan (sama dengan nama file), revisi basis data (untuk mendeteksi migrasi data atau untuk menghindari sinkronisasi dengan versi aplikasi yang tidak pernah) dan tentu saja data (jika baris tidak dihapus).
Solusi ini berfungsi untuk ribuan file dan sekitar 30 entitas. Alih-alih Dropbox saya bisa menggunakan key / value store sebagai layanan web REST yang ingin saya lakukan nanti, tetapi tidak punya waktu untuk ini :) Untuk saat ini, menurut saya, solusi saya lebih dapat diandalkan daripada iCloud dan, yang sangat penting, Saya memiliki kontrol penuh tentang cara kerjanya (terutama karena itu kode saya sendiri).
Solusi lain adalah menyimpan perubahan MOC sebagai transaksi - akan ada jauh lebih sedikit file yang dipertukarkan dengan server, tetapi lebih sulit untuk melakukan pemuatan awal dalam urutan yang benar ke dalam data inti yang kosong. iCloud bekerja dengan cara ini, dan juga solusi sinkronisasi lainnya memiliki pendekatan yang serupa, misalnya TICoreDataSync .
- PEMBARUAN
Setelah beberapa saat, saya pindah ke Ensembles - Saya merekomendasikan solusi ini untuk menemukan kembali roda.
sumber