วิธีซิงค์ข้อมูล iPhone หลักกับเว็บเซิร์ฟเวอร์แล้วส่งไปยังอุปกรณ์อื่น [ปิด]


293

ฉันทำงานกับวิธีการซิงค์ข้อมูลหลักที่จัดเก็บในแอปพลิเคชัน iPhone ระหว่างอุปกรณ์หลายชนิดเช่น iPad หรือ Mac เฟรมเวิร์กการซิงค์มีไม่มาก (ถ้ามี) สำหรับใช้กับ Core Data บน iOS อย่างไรก็ตามฉันได้คิดถึงแนวคิดต่อไปนี้:

  1. ทำการเปลี่ยนแปลงกับที่เก็บข้อมูลหลักโลคัลและการเปลี่ยนแปลงถูกบันทึก (a) หากอุปกรณ์ออนไลน์นั้นจะพยายามส่งเซ็ตการแก้ไขไปยังเซิร์ฟเวอร์รวมถึง ID อุปกรณ์ของอุปกรณ์ที่ส่งเซ็ตการแก้ไขนั้น (b) หากเซ็ตการแก้ไขไม่ถึงเซิร์ฟเวอร์หรือหากอุปกรณ์ไม่ได้ออนไลน์แอพจะเพิ่มการเปลี่ยนแปลงที่กำหนดไว้ในคิวเพื่อส่งเมื่อมันมาออนไลน์
  2. เซิร์ฟเวอร์ซึ่งนั่งอยู่ในคลาวด์ผสานการเปลี่ยนแปลงเฉพาะที่ได้รับกับฐานข้อมูลหลัก
  3. หลังจากชุดการเปลี่ยนแปลง (หรือชุดของคิวการเปลี่ยนแปลง) ถูกผสานบนเซิร์ฟเวอร์คลาวด์เซิร์ฟเวอร์จะผลักดันชุดการเปลี่ยนแปลงเหล่านั้นทั้งหมดไปยังอุปกรณ์อื่นที่ลงทะเบียนกับเซิร์ฟเวอร์โดยใช้ระบบการสำรวจบางประเภท (ฉันคิดว่าจะใช้บริการ Push ของ Apple แต่เห็นได้ชัดว่าตามความคิดเห็นนี้ไม่ใช่ระบบที่ใช้การได้)

มีอะไรแฟนซีที่ฉันต้องคิดเกี่ยวกับ? ผมมองที่กรอบ REST เช่นObjectiveResource , แกนทรัพยากรและRestfulCoreData แน่นอนว่าทั้งหมดนี้ทำงานร่วมกับ Ruby on Rails ซึ่งฉันไม่ได้ผูกติดอยู่ แต่เป็นจุดเริ่มต้น ข้อกำหนดหลักที่ฉันมีสำหรับวิธีแก้ไขปัญหาของฉันคือ:

  1. ควรทำการเปลี่ยนแปลงใด ๆ ในพื้นหลังโดยไม่หยุดเธรดหลักชั่วคราว
  2. ควรใช้แบนด์วิดท์ให้น้อยที่สุด

ฉันคิดถึงความท้าทายหลายประการ:

  1. ตรวจสอบให้แน่ใจว่า ID วัตถุสำหรับที่เก็บข้อมูลที่แตกต่างกันในอุปกรณ์ต่าง ๆ นั้นเชื่อมต่อกับเซิร์ฟเวอร์ กล่าวคือฉันจะมีตาราง ID วัตถุและรหัสอุปกรณ์ซึ่งเชื่อมโยงผ่านการอ้างอิงถึงวัตถุที่เก็บไว้ในฐานข้อมูล ฉันจะมีบันทึก (DatabaseId [ไม่ซ้ำกับตารางนี้], ObjectId [ไม่ซ้ำกับรายการในฐานข้อมูลทั้งหมด], Datafield1, Datafield2), ฟิลด์ ObjectId จะอ้างอิงตารางอื่น, AllObjects: (ObjectId, DeviceId, DeviceObjectId) จากนั้นเมื่ออุปกรณ์ผลักชุดการเปลี่ยนแปลงอุปกรณ์จะส่งรหัสอุปกรณ์และ objectId จากวัตถุข้อมูลหลักในที่เก็บข้อมูลภายในเครื่อง จากนั้นคลาวด์เซิร์ฟเวอร์ของฉันจะตรวจสอบกับ objectId และรหัสอุปกรณ์ในตาราง AllObjects และค้นหาระเบียนที่จะเปลี่ยนแปลงในตารางเริ่มต้น
  2. การเปลี่ยนแปลงทั้งหมดควรประทับเวลาเพื่อให้สามารถผสานได้
  3. อุปกรณ์จะต้องสำรวจเซิร์ฟเวอร์โดยไม่ต้องใช้แบตเตอรี่มากเกินไป
  4. อุปกรณ์ในท้องถิ่นจะต้องอัปเดตทุกอย่างที่อยู่ในหน่วยความจำหาก / เมื่อได้รับการเปลี่ยนแปลงจากเซิร์ฟเวอร์

มีอะไรอีกที่ฉันหายไปที่นี่ กรอบการทำงานแบบไหนที่ฉันควรจะมองให้เป็นไปได้?


5
คุณไม่สามารถพึ่งพา Push Notifications ที่ได้รับ ผู้ใช้สามารถแตะพวกเขาออกไปและเมื่อมีการแจ้งเตือนครั้งที่สองมาถึงระบบปฏิบัติการจะโยนครั้งแรกออกไป การแจ้งเตือนแบบพุช IMO นั้นเป็นวิธีที่ไม่ดีในการรับอัปเดตการซิงค์เนื่องจากผู้ใช้ขัดจังหวะ แอพควรทำการซิงค์ทุกครั้งที่เปิดตัว
Ole Begemann

ตกลง. ขอบคุณสำหรับข้อมูล - นอกเหนือจากการสำรวจเซิร์ฟเวอร์อย่างต่อเนื่องและตรวจสอบการอัปเดตเกี่ยวกับการเปิดตัวมีวิธีที่อุปกรณ์จะได้รับการอัพเดตหรือไม่? ฉันสนใจที่จะทำให้มันใช้งานได้หากแอปเปิดในหลายอุปกรณ์พร้อมกัน
เจสัน

1
(ฉันรู้ว่าสายไปหน่อย แต่ถ้ามีใครเข้ามาเจอเรื่องนี้และก็ยังสงสัย) เพื่อให้อุปกรณ์หลายเครื่องซิงค์พร้อมกันคุณสามารถเปิดการเชื่อมต่อกับอุปกรณ์อื่นหรือเซิร์ฟเวอร์และส่งข้อความเพื่อบอกอุปกรณ์อื่น ๆ ) เมื่อมีการอัพเดท (เช่นวิธีการทำงานของ IRC / การส่งข้อความโต้ตอบแบบทันที)
Dan2552

1
@ Dan2552: สิ่งที่คุณอธิบายนั้นเรียกว่า [long polling] [ en.wikipedia.org/wiki/ …และเป็นแนวคิดที่ดีอย่างไรก็ตามการเชื่อมต่อแบบเปิดใช้พลังงานแบตเตอรี่และแบนด์วิดท์ค่อนข้างมากบนอุปกรณ์มือถือ
johndodo

1
ต่อไปนี้เป็นบทแนะนำที่ดีจาก Ray Wenderlich เกี่ยวกับวิธีการซิงค์ข้อมูลระหว่างแอปและบริการบนเว็บของคุณ: raywenderlich.com/15916//
JRG-Developer

คำตอบ:


144

ฉันขอแนะนำให้อ่านอย่างละเอียดและใช้กลยุทธ์การซิงค์ที่ Dan Grover พูดถึงในการประชุม iPhone 2009 ที่นี่เป็นเอกสาร PDF

นี่เป็นโซลูชันที่ใช้งานได้และไม่ยากที่จะนำไปใช้ (Dan ใช้สิ่งนี้ในแอปพลิเคชั่นหลายตัว) ซ้อนทับโซลูชันที่อธิบายโดย Chris สำหรับการสนทนาเชิงลึกในเชิงทฤษฎีให้ดูกระดาษจาก Russ Cox (MIT) และ William Josephson (Princeton):

การซิงโครไนซ์ไฟล์กับ Vector Time Pairs

ซึ่งนำไปใช้อย่างเท่าเทียมกันกับข้อมูลหลักพร้อมการแก้ไขที่ชัดเจน นี่เป็นกลยุทธ์การซิงค์ที่น่าเชื่อถือและมีประสิทธิภาพโดยรวมที่มากขึ้น แต่ต้องการความพยายามมากขึ้นในการนำไปใช้อย่างถูกต้อง

แก้ไข:

ดูเหมือนว่าไฟล์ pdf ของ Grover จะไม่สามารถใช้งานได้อีกต่อไป (ลิงก์ที่ใช้งานไม่ได้มีนาคม 2015) อัปเดต: ลิงก์นี้มีให้บริการผ่านทาง Back Back Machine ที่นี่

Objective-C framework ที่เรียกว่าZSyncและพัฒนาโดย Marcus Zarra ได้เลิกใช้แล้วเนื่องจากในที่สุด iCloud ก็ดูเหมือนว่าจะสนับสนุนการซิงค์ข้อมูลหลักที่ถูกต้อง


ใครมีลิงค์อัพเดทสำหรับวิดีโอ ZSync บ้าง นอกจากนี้ ZSync ยังคงอยู่หรือไม่? ฉันเห็นมันได้รับการปรับปรุงล่าสุดในปี 2010
Jeremie Weldin

ความมุ่งมั่นครั้งสุดท้ายของ ZSync เกี่ยวกับ GitHub คือเมื่อเดือนกันยายน 2010 ซึ่งทำให้ฉันเชื่อว่ามาร์คัสหยุดการสนับสนุน
เน่าเสียง่าย Dave

1
อัลกอริทึมที่อธิบายโดย Dan Grover ค่อนข้างดี อย่างไรก็ตามมันจะไม่ทำงานกับรหัสเซิร์ฟเวอร์แบบมัลติเธรด (เช่นนี้จะไม่ขยายขนาดเลย) เนื่องจากไม่มีวิธีที่จะทำให้แน่ใจว่าไคลเอนต์จะไม่พลาดการอัปเดตเมื่อใช้เวลาเพื่อตรวจสอบการอัปเดตใหม่ . โปรดแก้ไขให้ฉันถ้าฉันผิด - ฉันจะฆ่าเพื่อดูการใช้งานสิ่งนี้
masi

1
@ แพทฉันเพิ่งส่งไฟล์ pdf ให้คุณตามที่ร้องขอ ไชโยมัสซิโมคาฟาโร
Massimo Cafaro

3
หายไปข้ามแพลตฟอร์มประสานข้อมูลภาพนิ่งรูปแบบไฟล์ PDF โดยแดนโกรเวอร์สามารถเข้าถึงได้ผ่านเครื่อง Wayback
Matthew Kairys

272

ฉันทำสิ่งที่คล้ายกับสิ่งที่คุณพยายามจะทำ ให้ฉันบอกสิ่งที่ฉันเรียนรู้และฉันจะทำอย่างไร

ฉันสมมติว่าคุณมีความสัมพันธ์แบบหนึ่งต่อหนึ่งระหว่างวัตถุข้อมูลของคุณกับโมเดล (หรือ db schema) บนเซิร์ฟเวอร์ คุณเพียงแค่ต้องการให้เนื้อหาเซิร์ฟเวอร์ซิงค์กับไคลเอนต์ แต่ลูกค้ายังสามารถปรับเปลี่ยนและเพิ่มข้อมูล ถ้าฉันเข้าใจถูกต้องแล้วอ่านต่อไป

ฉันเพิ่มสี่ฟิลด์เพื่อช่วยในการซิงโครไนซ์:

  1. sync_status - เพิ่มฟิลด์นี้ในโมเดลข้อมูลหลักของคุณเท่านั้น แอพนี้ใช้เพื่อตรวจสอบว่าคุณมีการเปลี่ยนแปลงที่รอดำเนินการกับรายการหรือไม่ ฉันใช้รหัสต่อไปนี้: 0 หมายถึงไม่มีการเปลี่ยนแปลง 1 หมายถึงมันอยู่ในคิวที่จะซิงโครไนซ์กับเซิร์ฟเวอร์และ 2 หมายความว่าเป็นวัตถุชั่วคราวและสามารถกำจัดได้
  2. is_deleted - เพิ่มสิ่งนี้ไปยังเซิร์ฟเวอร์และตัวแบบข้อมูลหลัก ลบกิจกรรมไม่ควรลบแถวออกจากฐานข้อมูลหรือจากแบบจำลองไคลเอ็นต์ของคุณเพราะจะทำให้คุณไม่มีข้อมูลที่จะซิงโครไนซ์กลับ ด้วยการตั้งค่าสถานะบูลีนแบบง่ายนี้คุณสามารถตั้งค่า is_deleted เป็น 1 ซิงโครไนซ์และทุกคนจะมีความสุข คุณต้องแก้ไขรหัสบนเซิร์ฟเวอร์และไคลเอนต์เพื่อสอบถามรายการที่ไม่ถูกลบด้วย "is_deleted = 0"
  3. last_modified - เพิ่มสิ่งนี้ไปยังเซิร์ฟเวอร์และตัวแบบข้อมูลหลัก ควรอัปเดตฟิลด์นี้โดยอัตโนมัติด้วยวันที่และเวลาปัจจุบันโดยเซิร์ฟเวอร์เมื่อใดก็ตามที่มีการเปลี่ยนแปลงอะไรในบันทึก ไม่ควรแก้ไขโดยไคลเอนต์
  4. guid - เพิ่ม id ที่ไม่ซ้ำกันทั่วโลก (ดูhttp://en.wikipedia.org/wiki/Globally_unique_identifier ) ในฟิลด์เซิร์ฟเวอร์และตัวแบบข้อมูลหลัก ฟิลด์นี้กลายเป็นคีย์หลักและมีความสำคัญเมื่อสร้างเรกคอร์ดใหม่บนไคลเอนต์ โดยปกติคีย์หลักของคุณคือจำนวนเต็มที่เพิ่มขึ้นบนเซิร์ฟเวอร์ แต่เราต้องจำไว้ว่าเนื้อหานั้นสามารถสร้างแบบออฟไลน์และซิงโครไนซ์ได้ในภายหลัง GUID ช่วยให้เราสามารถสร้างคีย์ขณะออฟไลน์ได้

บนไคลเอนต์เพิ่มรหัสเพื่อตั้งค่า sync_status เป็น 1 บนวัตถุโมเดลของคุณเมื่อใดก็ตามที่มีการเปลี่ยนแปลงและจำเป็นต้องซิงโครไนซ์กับเซิร์ฟเวอร์ วัตถุรูปแบบใหม่จะต้องสร้าง GUID

การประสานข้อมูลเป็นคำขอเดียว คำขอประกอบด้วย:

  • MAX last_modified time stamp ของวัตถุจำลองของคุณ สิ่งนี้บอกเซิร์ฟเวอร์ที่คุณต้องการเปลี่ยนแปลงหลังจากการประทับเวลานี้
  • อาร์เรย์ JSON ที่มีรายการทั้งหมดที่มี sync_status = 1

เซิร์ฟเวอร์ได้รับคำขอและทำสิ่งนี้:

  • ใช้เนื้อหาจากอาร์เรย์ JSON และแก้ไขหรือเพิ่มระเบียนที่มี ฟิลด์ last_modified ถูกอัพเดตโดยอัตโนมัติ
  • เซิร์ฟเวอร์ส่งคืนอาร์เรย์ JSON ที่มีวัตถุทั้งหมดที่มีการประทับเวลา last_modified มากกว่าการประทับเวลาที่ส่งในคำขอ ซึ่งจะรวมถึงวัตถุที่เพิ่งได้รับซึ่งทำหน้าที่เป็นการรับรองว่าบันทึกได้รับการซิงโครไนซ์กับเซิร์ฟเวอร์เรียบร้อยแล้ว

แอปได้รับการตอบสนองและทำสิ่งนี้:

  • ใช้เนื้อหาจากอาร์เรย์ JSON และแก้ไขหรือเพิ่มระเบียนที่มี แต่ละระเบียนจะได้รับการตั้งค่า sync_status เป็น 0

ฉันหวังว่าจะช่วย ฉันใช้การบันทึกคำและแบบจำลองแทนกัน แต่ฉันคิดว่าคุณเข้าใจ โชคดี.


2
Last_modified ฟิลด์ยังมีอยู่ในฐานข้อมูลท้องถิ่น แต่มันไม่ได้รับการปรับปรุงโดยนาฬิกาของ iPhone มันถูกตั้งค่าโดยเซิร์ฟเวอร์และทำข้อมูลให้ตรงกันกลับ วันที่ MAX (last_modified) คือสิ่งที่แอปส่งไปยังเซิร์ฟเวอร์เพื่อบอกให้ส่งทุกอย่างที่แก้ไขหลังจากวันที่นั้น
chris

3
มูลค่าทั่วโลกของลูกค้าสามารถแทนที่MAX(last_modified)แต่จะซ้ำซ้อนตั้งแต่MAX(last_modified)พอเพียง sync_statusมีอีกบทบาทหนึ่ง อย่างที่ฉันเขียนไว้ก่อนหน้านี้MAX(last_modified)กำหนดสิ่งที่จะต้องซิงค์จากเซิร์ฟเวอร์ในขณะที่sync_statusกำหนดสิ่งที่จะต้องซิงค์กับเซิร์ฟเวอร์
chris

2
@Flex_Addicted ขอบคุณ ใช่คุณจำเป็นต้องทำซ้ำฟิลด์สำหรับแต่ละเอนทิตีที่คุณต้องการซิงโครไนซ์ อย่างไรก็ตามคุณต้องระมัดระวังให้มากขึ้นเมื่อทำการซิงโครไนซ์โมเดลด้วยความสัมพันธ์ (เช่น 1-to-many)
chris

2
@BenPackard - คุณถูกต้อง วิธีการนี้ไม่ได้ทำการแก้ไขข้อขัดแย้งใด ๆ ฉันไม่ได้จัดการกับสิ่งนี้ในแอพของฉันเนื่องจากมีการแก้ไขบันทึกโดยผู้ใช้คนเดียว ฉันอยากรู้ว่าคุณจะแก้ไขปัญหานี้อย่างไร
chris

2
สวัสดี @ noilly พิจารณากรณีดังต่อไปนี้: คุณทำการเปลี่ยนแปลงวัตถุภายในเครื่องและจำเป็นต้องซิงโครไนซ์มันกลับไปที่เซิร์ฟเวอร์ การซิงค์อาจเกิดขึ้นหลายชั่วโมงหรือหลายวันต่อมา (บอกว่าคุณออฟไลน์มาระยะหนึ่งแล้ว) และในเวลานั้นแอปอาจถูกปิดและเริ่มใหม่สองสามครั้ง ในกรณีนี้วิธีการใน NSManagedObjectContext จะไม่ช่วยอะไรมาก
chris

11

หากคุณยังคงมองหาวิธีที่จะไปดูใน Couchbase มือถือ สิ่งนี้เป็นสิ่งที่คุณต้องการ ( http://www.couchbase.com/nosql-database/couchbase-mobile )


3
สิ่งนี้จะทำในสิ่งที่คุณต้องการหากคุณสามารถแสดงข้อมูลของคุณเป็นเอกสารแทนที่จะเป็นข้อมูลเชิงสัมพันธ์ มีงานอยู่รอบ ๆ แต่พวกเขาไม่สวยหรือคุ้มค่าเสมอไป
Jeremie Weldin

เอกสารเพียงพอสำหรับการใช้งานขนาดเล็ก
Hai Feng Kao

@radiospiel ลิงก์ของคุณใช้งานไม่ได้
Mick

สิ่งนี้จะเพิ่มการพึ่งพาที่แบ็คเอนด์จำเป็นต้องเขียนใน Couchbase DB แม้ว่าฉันจะเริ่มต้นด้วยแนวคิดของ NOSQL สำหรับการซิงค์ แต่ฉันไม่สามารถ จำกัด แบ็กเอนด์ของฉันให้เป็น NOSQL เนื่องจากเรามี MS SQL ที่ทำงานอยู่ในแบ็กเอนด์
thesummersign

@Mick: ดูเหมือนว่าจะทำงานอีกครั้ง (หรือคนคงเชื่อมโยงขอบคุณ?)
radiospiel

7

ที่คล้ายกันเช่น @Cris ฉันใช้คลาสสำหรับการซิงโครไนซ์ระหว่างไคลเอนต์และเซิร์ฟเวอร์และแก้ไขปัญหาที่ทราบแล้วทั้งหมด (ส่ง / รับข้อมูลไปยัง / จากเซิร์ฟเวอร์รวมความขัดแย้งตามการประทับเวลาลบรายการซ้ำในสภาพเครือข่ายที่ไม่น่าเชื่อถือ ไฟล์ ฯลฯ .. )

คุณเพียงแค่บอกคลาสที่เอนทิตีและคอลัมน์ใดควรซิงค์และเซิร์ฟเวอร์ของคุณอยู่ที่ไหน

M3Synchronization * syncEntity = [[M3Synchronization alloc] initForClass: @"Car"
                                                              andContext: context
                                                            andServerUrl: kWebsiteUrl
                                             andServerReceiverScriptName: kServerReceiverScript
                                              andServerFetcherScriptName: kServerFetcherScript
                                                    ansSyncedTableFields:@[@"licenceNumber", @"manufacturer", @"model"]
                                                    andUniqueTableFields:@[@"licenceNumber"]];


syncEntity.delegate = self; // delegate should implement onComplete and onError methods
syncEntity.additionalPostParamsDictionary = ... // add some POST params to authenticate current user

[syncEntity sync];

คุณสามารถค้นหาแหล่งที่มาตัวอย่างการทำงานและคำแนะนำเพิ่มเติมได้ที่นี่: github.com/knagode/M3 การซิงโครไนซ์


จะเป็นไรไหมถ้าเราเปลี่ยนเวลาของอุปกรณ์เป็นค่าผิดปกติ?
Golden

5

แจ้งให้ผู้ใช้อัปเดตข้อมูลผ่านการแจ้งเตือนแบบพุช ใช้เธรดพื้นหลังในแอปเพื่อตรวจสอบข้อมูลในเครื่องและข้อมูลบนเซิร์ฟเวอร์คลาวด์ในขณะที่การเปลี่ยนแปลงเกิดขึ้นบนเซิร์ฟเวอร์ให้เปลี่ยนข้อมูลในเครื่องในทางกลับกัน

ดังนั้นฉันคิดว่าส่วนที่ยากที่สุดคือการประมาณข้อมูลในด้านที่ไม่ถูกต้อง

หวังว่านี่จะช่วยคุณได้


5

ฉันเพิ่งโพสต์รุ่นแรกของ Core Data Cloud Syncing API ใหม่ของฉันซึ่งรู้จักกันในนาม SynCloud SynCloud มีความแตกต่างมากมายกับ iCloud เพราะอนุญาตให้ใช้กับส่วนต่อประสานผู้ใช้หลายคน นอกจากนี้ยังแตกต่างจาก API ที่ซิงค์อื่น ๆ เนื่องจากอนุญาตให้มีข้อมูลเชิงสัมพันธ์หลายตาราง

กรุณาหาข้อมูลเพิ่มเติมได้ที่http://www.syncloudapi.com

สร้างด้วย iOS 6 SDK ซึ่งเป็นรุ่นล่าสุดจนถึงวันที่ 9/27/2012


5
ยินดีต้อนรับสู่ Stack Overflow! ขอบคุณสำหรับการโพสต์คำตอบของคุณ! โปรดอ่านคำถามที่พบบ่อยเกี่ยวกับการส่งเสริมตนเองอย่างรอบคอบ
Andrew Barber

5

ฉันคิดว่าทางออกที่ดีสำหรับปัญหา GUID คือ "ระบบ ID แบบกระจาย" ฉันไม่แน่ใจว่าคำที่ถูกต้องคืออะไร แต่ฉันคิดว่านั่นคือสิ่งที่เอกสารเซิร์ฟเวอร์ MS SQL ใช้เรียกมัน (SQL ใช้ / ใช้วิธีนี้สำหรับการกระจาย / ซิงค์ฐานข้อมูล) มันค่อนข้างง่าย:

เซิร์ฟเวอร์กำหนด ID ทั้งหมด ทุกครั้งที่ทำการซิงค์ข้อมูลสิ่งแรกที่ตรวจสอบแล้วคือ "ฉันมีรหัสเหลือจำนวนเท่าใดบนไคลเอนต์นี้" หากไคลเอนต์ใกล้หมดไคลเอ็นต์จะถามเซิร์ฟเวอร์เพื่อหา ID บล็อกใหม่ ไคลเอนต์ใช้รหัสในช่วงนั้นสำหรับเรกคอร์ดใหม่ วิธีนี้ใช้งานได้ดีสำหรับความต้องการส่วนใหญ่หากคุณสามารถกำหนดบล็อกให้ใหญ่พอที่จะ "หมด" ก่อนการซิงค์ครั้งต่อไป แต่ไม่ใหญ่จนเกินกว่าที่เซิร์ฟเวอร์จะหมด หากไคลเอนต์หมดการจัดการอาจเป็นเรื่องง่ายเพียงแจ้งผู้ใช้ว่า "ขออภัยคุณไม่สามารถเพิ่มรายการเพิ่มเติมจนกว่าคุณจะซิงค์" ... หากพวกเขากำลังเพิ่มรายการจำนวนมากพวกเขาไม่ควรซิงค์เพื่อหลีกเลี่ยงข้อมูลเก่า มีปัญหาไหม

ฉันคิดว่าสิ่งนี้ดีกว่าการใช้ GUID แบบสุ่มเนื่องจาก GUID แบบสุ่มนั้นไม่ปลอดภัย 100% และมักจะต้องนานกว่า ID มาตรฐานมาก (128- บิตกับ 32 บิต) คุณมักจะมีดัชนีตาม ID และมักจะเก็บหมายเลข ID ในหน่วยความจำดังนั้นจึงเป็นเรื่องสำคัญที่จะต้องทำให้พวกเขามีขนาดเล็ก

ไม่ต้องการโพสต์เป็นคำตอบจริงๆ แต่ฉันไม่รู้ว่าใครจะเห็นเป็นความคิดเห็นและฉันคิดว่ามันสำคัญสำหรับหัวข้อนี้และไม่รวมอยู่ในคำตอบอื่น ๆ


2

ก่อนอื่นคุณควรคิดใหม่ว่าคุณมีข้อมูลกี่ตารางและความสัมพันธ์ ในโซลูชันของฉันฉันใช้การซิงค์ผ่านไฟล์ Dropbox ฉันสังเกตการเปลี่ยนแปลงใน MOC หลักและบันทึกข้อมูลเหล่านี้ไปยังไฟล์ (แต่ละแถวจะถูกบันทึกเป็น gzipped json) หากมีการเชื่อมต่ออินเทอร์เน็ตใช้งานได้ฉันจะตรวจสอบว่ามีการเปลี่ยนแปลงใด ๆ ใน Dropbox หรือไม่ (Dropbox ให้การเปลี่ยนแปลงเดลต้าแก่ฉัน) ดาวน์โหลดพวกเขาและผสาน (ชนะล่าสุด) และวางไฟล์ที่เปลี่ยนแปลงแล้ว ก่อนทำการซิงค์ฉันวางไฟล์ล็อคบน Dropbox เพื่อป้องกันไม่ให้ไคลเอนต์อื่นทำการซิงค์ข้อมูลที่ไม่สมบูรณ์ เมื่อดาวน์โหลดการเปลี่ยนแปลงจะปลอดภัยที่จะดาวน์โหลดข้อมูลบางส่วนเท่านั้น (เช่นการเชื่อมต่ออินเทอร์เน็ตที่หายไป) เมื่อการดาวน์โหลดเสร็จสิ้น (ทั้งหมดหรือบางส่วน) ก็จะเริ่มโหลดไฟล์ลงใน Core Data เมื่อมีความสัมพันธ์ที่ไม่ได้รับการแก้ไข (ไม่ได้ดาวน์โหลดไฟล์ทั้งหมด) จะหยุดโหลดไฟล์และพยายามดาวน์โหลดในภายหลัง ความสัมพันธ์ถูกเก็บไว้เป็น GUID เท่านั้นดังนั้นฉันสามารถตรวจสอบไฟล์ที่จะโหลดเพื่อให้มีความสมบูรณ์ของข้อมูลได้อย่างง่ายดาย การซิงค์เริ่มต้นหลังจากทำการเปลี่ยนแปลงข้อมูลหลัก หากไม่มีการเปลี่ยนแปลงใด ๆ จะทำการตรวจสอบการเปลี่ยนแปลงใน Dropbox ทุกสองสามนาทีและเมื่อเริ่มต้นแอพ นอกจากนี้เมื่อการเปลี่ยนแปลงถูกส่งไปยังเซิร์ฟเวอร์ฉันส่งการออกอากาศไปยังอุปกรณ์อื่นเพื่อแจ้งให้พวกเขาทราบเกี่ยวกับการเปลี่ยนแปลงเพื่อให้สามารถซิงค์ได้เร็วขึ้น แต่ละเอนทิตีที่ซิงค์มีคุณสมบัติ GUID (guid ยังใช้เป็นชื่อไฟล์สำหรับแลกเปลี่ยนไฟล์) ฉันยังมีฐานข้อมูล Sync ที่ฉันจัดเก็บการแก้ไข Dropbox ของแต่ละไฟล์ (ฉันสามารถเปรียบเทียบได้เมื่อ Dropbox delta รีเซ็ตสถานะของมัน) ไฟล์ยังมีชื่อเอนทิตี, สถานะ (ลบ / ไม่ถูกลบ), guid (เหมือนกับชื่อไฟล์), การแก้ไขฐานข้อมูล (เพื่อตรวจจับการย้ายข้อมูลหรือเพื่อหลีกเลี่ยงการซิงค์กับแอปเวอร์ชันที่ไม่เคยใช้) และแน่นอนว่าข้อมูล ดังนั้นฉันสามารถตรวจสอบไฟล์ที่จะโหลดเพื่อให้มีความสมบูรณ์ของข้อมูลได้อย่างง่ายดาย การซิงค์เริ่มต้นหลังจากทำการเปลี่ยนแปลงข้อมูลหลัก หากไม่มีการเปลี่ยนแปลงใด ๆ จะทำการตรวจสอบการเปลี่ยนแปลงใน Dropbox ทุกสองสามนาทีและเมื่อเริ่มต้นแอพ นอกจากนี้เมื่อการเปลี่ยนแปลงถูกส่งไปยังเซิร์ฟเวอร์ฉันส่งการออกอากาศไปยังอุปกรณ์อื่นเพื่อแจ้งให้พวกเขาทราบเกี่ยวกับการเปลี่ยนแปลงเพื่อให้สามารถซิงค์ได้เร็วขึ้น แต่ละเอนทิตีที่ซิงค์มีคุณสมบัติ GUID (guid ยังใช้เป็นชื่อไฟล์สำหรับแลกเปลี่ยนไฟล์) ฉันยังมีฐานข้อมูล Sync ที่ฉันจัดเก็บการแก้ไข Dropbox ของแต่ละไฟล์ (ฉันสามารถเปรียบเทียบได้เมื่อ Dropbox delta รีเซ็ตสถานะของมัน) ไฟล์ยังมีชื่อเอนทิตี, สถานะ (ลบ / ไม่ถูกลบ), guid (เหมือนกับชื่อไฟล์), การแก้ไขฐานข้อมูล (เพื่อตรวจจับการย้ายข้อมูลหรือเพื่อหลีกเลี่ยงการซิงค์กับแอปเวอร์ชันที่ไม่เคยใช้) และแน่นอนว่าข้อมูล ดังนั้นฉันสามารถตรวจสอบไฟล์ที่จะโหลดเพื่อให้มีความสมบูรณ์ของข้อมูลได้อย่างง่ายดาย การซิงค์เริ่มต้นหลังจากทำการเปลี่ยนแปลงข้อมูลหลัก หากไม่มีการเปลี่ยนแปลงใด ๆ จะทำการตรวจสอบการเปลี่ยนแปลงใน Dropbox ทุกสองสามนาทีและเมื่อเริ่มต้นแอพ นอกจากนี้เมื่อการเปลี่ยนแปลงถูกส่งไปยังเซิร์ฟเวอร์ฉันส่งการออกอากาศไปยังอุปกรณ์อื่นเพื่อแจ้งให้พวกเขาทราบเกี่ยวกับการเปลี่ยนแปลงเพื่อให้สามารถซิงค์ได้เร็วขึ้น แต่ละเอนทิตีที่ซิงค์มีคุณสมบัติ GUID (guid ยังใช้เป็นชื่อไฟล์สำหรับแลกเปลี่ยนไฟล์) ฉันยังมีฐานข้อมูล Sync ที่ฉันจัดเก็บการแก้ไข Dropbox ของแต่ละไฟล์ (ฉันสามารถเปรียบเทียบได้เมื่อ Dropbox delta รีเซ็ตสถานะของมัน) ไฟล์ยังมีชื่อเอนทิตี, สถานะ (ลบ / ไม่ถูกลบ), guid (เหมือนกับชื่อไฟล์), การแก้ไขฐานข้อมูล (เพื่อตรวจจับการย้ายข้อมูลหรือเพื่อหลีกเลี่ยงการซิงค์กับแอปเวอร์ชันที่ไม่เคยใช้) และแน่นอนว่าข้อมูล

โซลูชันนี้ทำงานกับไฟล์หลายพันไฟล์และเอนทิตีประมาณ 30 รายการ แทนที่จะใช้ Dropbox ฉันสามารถใช้ที่เก็บคีย์ / ค่าเป็นบริการเว็บ REST ซึ่งฉันต้องการจะทำในภายหลัง แต่ไม่มีเวลาสำหรับเรื่องนี้ :) สำหรับตอนนี้ในความคิดของฉันโซลูชันของฉันเชื่อถือได้มากกว่า iCloud และซึ่งสำคัญมาก ฉันสามารถควบคุมการทำงานของมันได้อย่างเต็มที่ (ส่วนใหญ่เป็นเพราะรหัสของฉันเอง)

อีกวิธีหนึ่งคือการบันทึกการเปลี่ยนแปลง MOC เป็นธุรกรรม - จะมีการแลกเปลี่ยนไฟล์กับเซิร์ฟเวอร์น้อยลง แต่เป็นการยากที่จะทำการโหลดเริ่มต้นตามลำดับที่ถูกต้องลงในข้อมูลหลักที่ว่างเปล่า iCloud คือการทำงานด้วยวิธีนี้และยังแก้ปัญหาการซิงค์อื่น ๆ ที่มีวิธีการที่คล้ายกันเช่นTICoreDataSync

- อัพเดท

หลังจากนั้นครู่หนึ่งฉันย้ายไปยังEnsembles - ฉันแนะนำวิธีนี้ในการพลิกโฉมพวงมาลัย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.