Tüm açık kaynak paketler
MimariSwift

iOS-Offline-First-Framework

Çevrimdışıyken de çalışan ve sunucunla senkronize olan, Swift uygulamaları için yerel bir store.

2YıldızSon Sürüm: v2.1.0 · Güncellendi: 21 Ekim 2026
Platformlar:iOS 17macOS 14tvOS 17watchOS 10visionOS 1

Lisans: MIT

Testler: 375Ölçüm:

Nasıl ölçüldü

swift test at tag v2.1.0 (205c546) on macOS 27.0.1 with Swift 6.4: 375 tests in 75 suites passed; run again with OFFLINE_FIRST_NODE set so the three reference-server suites ran, with the same result; the two end-to-end suites that need OFFLINE_FIRST_SERVER_URL were skipped. npm test of Examples/SyncServer on Node 26.11.1: 28 tests passed. The README states 372 tests on an iPhone simulator, which was not re-run here.

Özet

  • Kayıtları cihazdaki bir dosyada tutan, her değişikliği kuyruğa alan ve bağlantı olduğunda herhangi bir sunucuyla senkronize eden bir Swift paketi.
  • 2.1.0, 2.0.0'ın iki denetiminin ve sonraki turlarının veri bütünlüğü bulgularını düzeltir; her düzeltmenin önce kırmızı olan bir testi var.
  • Bir değişikliği yalnız store'un okuduğu bir push cevabı sonuçlandırır; kayıp ya da okunamayan cevaptan sonra değişiklik sonraki push'a kadar şüpheli kalır.
  • Yeni bir sunucu epoch'u yalnız aynı sync'in iki isteği bildirdiğinde sayılır ve store daha eski bir epoch'a asla geri dönmez.
  • Aynı URL'nin arkasındaki başka bir deployment'tan gelen cevaplar kısmen kapsanır; sekiz açık issue her durumu ve geri dönüş yolunu anlatır.

Uygulamanın kayıtlarını cihazdaki bir dosyada tutan, her değişikliği kuyruğa alan ve bağlantı olduğunda sunucuyla senkronize eden bir Swift paketi. Kaydetmek hiçbir zaman ağı beklemez. Aynı kayıt iki cihazda değiştiyse neyin kalacağına senin seçtiğin conflict policy karar verir. Her backend ile çalışır: referans sunucusu olan küçük bir HTTP protokolü, iki fonksiyonluk bir protocol üzerinden kendi API'n ya da testler ve preview'lar için bellek içi bir sunucu. Paketin hiçbir bağımlılığı yok.

Özellikler

  • Beklemeyen yazımlar: save ve delete atomik yazılan bir dosyaya ve yeniden başlatmalardan sağ çıkan bir bekleyen değişiklik kuyruğuna gider; başarısız push'lar exponential backoff ve jitter ile yeniden denenir, son denemeden sonra kaybolmak yerine bekletilir
  • Çakışma politikaları: hybrid logical clock zaman damgalarıyla last write wins, server wins, client wins, kendi merge fonksiyonun ya da çakışmasız alanlar (LWWRegister, LWWMap, GCounter, PNCounter, ORSet)
  • Her backend: HTTPSyncTransport, Examples/SyncServer'daki Node referans sunucusunun uyguladığı, belgelenmiş iki endpoint'li bir JSON protokolü konuşur; başka her API SyncTransport protocol'ünün arkasına yerleşir
  • SwiftUI: SyncedCollection bir store'un @Observable modelidir; otomatik sync cihaz çevrimiçi olduğunda ve yerel düzenlemelerden kısa süre sonra çalışır
  • Diskteki veri: anahtarı Keychain'de tutulan AES-GCM dosya şifrelemesi, kayıt şeması migration'ları ve bozuk dosyalar için bir politika
  • Hatalı sunuculara ve bozuk dosyalara karşı sınırlar: outbox boyutu, pull sayfaları, kayıt başına push sayısı, cevap, revision ve change token boyutları, dizininden çıkamayan dosya adları
  • Yazılı garantiler: sunucunun kabul ettiği bir yazımın yerine bayat bir kopya geçmez, bir değişikliği yalnız okunmuş bir cevap sonuçlandırır ve yeni bir sunucu epoch'u yalnız aynı sync'in iki isteği bildirdiğinde sayılır; Guarantees and limits makalesi sunucunun bunun için ne yapması gerektiğini yazar
  • Swift Testing ile test edilir: macOS'ta 375, iPhone simülatöründe 372 test; aralarında her conflict policy'yi kayıp istekler, yeniden başlatmalar, token reset'leri, bayat sayfalar ve çökmelerden geçiren property testleri ve CI'da referans sunucuya karşı uçtan uca suite'ler var; referans sunucunun kendi 28 Node testi var

Hızlı Başlangıç

swift
1import OfflineFirstFramework
2import SwiftUI
3 
4/// A to-do item. Any `Codable` struct with an `id` can be a record.
5struct Todo: SyncableRecord, Hashable {
6 var id = UUID()
7 var title: String
8 var isDone = false
9}
10 
11enum TodoStore {
12 // InMemorySyncServer stands in for a backend; swap in HTTPSyncTransport or your own
13 // SyncTransport when you have one. The initializer throws only for an invalid name or a
14 // store file it cannot read.
15 static let shared = try! OfflineStore<Todo>(name: "todos", transport: InMemorySyncServer<Todo>())
16}
17 
18struct ContentView: View {
19 @State private var todos = SyncedCollection(store: TodoStore.shared)
20 @State private var newTitle = ""
21 
22 var body: some View {
23 NavigationStack {
24 List {
25 TextField("New to-do", text: $newTitle)
26 .onSubmit {
27 let todo = Todo(title: newTitle)
28 newTitle = ""
29 Task { await todos.save(todo) }
30 }
31 ForEach(todos.records) { todo in
32 Text(todo.title)
33 }
34 }
35 .navigationTitle("To-dos")
36 .toolbar {
37 Text("\(todos.pendingCount) to sync")
38 }
39 .refreshable { await todos.sync() }
40 }
41 }
42}

Kurulum

Xcode (File › Add Package Dependencies…)

text
1https://github.com/muhittincamdali/iOS-Offline-First-Framework.git

Swift Package Manager

swift
1dependencies: [
2 .package(url: "https://github.com/muhittincamdali/iOS-Offline-First-Framework.git", from: "2.1.0")
3],
4targets: [
5 .target(name: "YourApp", dependencies: [
6 .product(name: "OfflineFirstFramework", package: "iOS-Offline-First-Framework")
7 ])
8]

Ekran Görüntüleri

OfflineTodos örnek uygulaması iPhone simülatöründe, tüm yapılacaklar senkronize, açık tema
OfflineTodos örnek uygulaması çevrimdışı, senkronizasyon bekleyen iki değişiklik, açık tema
OfflineTodos örnek uygulaması, tüm yapılacaklar senkronize, koyu tema
OfflineTodos örnek uygulaması çevrimdışı, senkronizasyon bekleyen iki değişiklik, koyu tema

Zaman Çizelgesi

  1. Repo bir grup manager sınıfı olarak açıldı; sync manager sonuçları simüle ediyor, hiçbir sunucuya bağlanmıyordu

  2. 1.0.0 sürümü etiketlendi; manifest olmayan bir Resources klasörü ve unsafe derleyici bayrakları içerdiği için sürümle dependency olarak eklenemiyordu

  3. Sadeleştirme: RxSwift ve CocoaLumberjack yerine Combine geldi, manager'lar kısaldı, sync hâlâ yer tutucuydu

  4. Senkronizasyon motorlu bir offline store olarak baştan kuruldu ve 2.0.0 olarak yayımlandı; SwiftPersistence paketi içine alınıp arşivlendi, 1.0.0 API'lerinin hiçbiri kalmadı. Aynı gün 2.0.0'ın iki denetimi, mutlaka düzeltilmesi gereken on bir veri bütünlüğü bulgusu listeledi

  5. v2.1.0: on beş düzeltme ve kontrol turunun ardından veri bütünlüğü sürümü; 14. ve 15. turlar regresyon getirdiği için atıldı, release dalı 13. turun son commit'ine döndü ve sekiz bilinen sınır issue olarak açıldı

Bağlantılar

Birleştirilen Depolar

İlgili Yazı

Yazıyı Oku