Gestió de despeses individuals i conjuntes de la llar
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-12 13:36:24 +02:00
Ralcat Formulari: «Nou mitjà» al selector de mitjà de pagament 2026-10-12 13:22:32 +02:00
Ralcat.xcodeproj Versió 0.3 (5): moviments previstos 2026-10-12 12:42:53 +02:00
RalcatDomini Filtre Previstos, toc al saldo per veure'l previst i saldo conciliat fins avui 2026-10-12 12:58:50 +02:00
LICENSE Afegida LICENSE 2026-10-07 18:34:56 +02:00
Ralcat-Info.plist Info.plist: l'app no fa servir xifratge no exempt 2026-10-12 13:36:24 +02:00
Ralcat.entitlements Primera versió 2026-10-03 23:12:05 +02:00
README.md README: previstos, filtre Previstos, límit de còpies i altes des del formulari 2026-10-12 13:22:56 +02:00

Ralcat

App d'iOS, totalment en català, per gestionar les despeses individuals i conjuntes d'una llar de dues persones.

Cada membre anota les seves despeses i ingressos una sola vegada. Un interruptor «Despesa conjunta» fa que una despesa entri al balanç de la llar, i l'app calcula cada mes qui ha pagat més i quina transferència cal fer per quedar igualats.

Funcionalitats

  • Comptes individuals, amb saldo inicial, saldo d'avui i saldo conciliat.
  • Despeses i ingressos agrupats per dies, amb el saldo del compte al final de cada dia. Un filtre mostra tots els moviments, només els conciliats, només els no conciliats o només els previstos, amb els saldos corresponents. Els saldos es poden amagar. Des del formulari es poden crear categories i mitjans de pagament nous sense perdre el que s'ha escrit.
  • Moviments previstos: una despesa o un ingrés amb data futura (una factura que encara no s'ha cobrat) es mostra atenuat, amb un rellotge, i no compta al saldo d'avui (ni al conciliat) fins que arriba el dia. Tocant el saldo de dalt es veu el saldo previst, amb tots els previstos ja cobrats.
  • Despeses conjuntes: es reparteixen entre els dos membres (50/50 per defecte, configurable a Ajustos amb fins a dos decimals) i generen un balanç mensual amb la transferència de compensació.
  • Categories de despesa i d'ingrés: les de la llar, compartides, i les personals, lligades a cada compte. Cada categoria mostra quants moviments té i, en tocar-la, els llista per dies.
  • Mitjans de pagament (efectiu, targeta…), comuns a tots els comptes de cada membre. Com les categories, mostren quants moviments tenen al compte triat i, en tocar-los, els llisten.
  • Conciliació: cada moviment es pot marcar com a comprovat amb l'extracte del banc.
  • Resum per mesos i per anys dels ingressos, les despeses i l'estat de la llar, amb una gràfica que compara ingressos i despeses.
  • Sincronització amb iCloud entre els dos membres, sense servidor propi.
  • Recuperació automàtica des d'iCloud en instal·lar l'app en un mòbil nou.
  • Còpies de seguretat en JSON a iCloud Drive, que es poden restaurar. Es conserven les tres més recents.
  • Importació de dades d'una altra aplicació.
  • Aparença clara, fosca o del sistema, amb el disseny Liquid Glass d'iOS 26. Es pot triar el color d'accent de l'app i el color que tenyeix les despeses conjuntes pagades per l'altre membre.

Requisits

  • iOS 26 o posterior (només iPhone).
  • Xcode 27 i Swift 6.
  • Un compte de pagament de l'Apple Developer Program per a CloudKit.
  • Cada membre necessita una sessió d'iCloud. Sense iCloud, l'app funciona només en local.

Estructura del projecte

Ralcat.xcodeproj        Projecte de l'app
Ralcat/                 App SwiftUI (pantalles i estat)
  Model/                Magatzem (estat de l'app), delegats, formats
  Vistes/               Pantalles
Ralcat.entitlements     iCloud (CloudKit i iCloud Drive) i notificacions
Ralcat-Info.plist       Invitacions de CloudKit i carpeta d'iCloud Drive
RalcatDomini/           Paquet Swift amb la lògica, provada amb tests
  Sources/
    RalcatDomini/       Models, balanç, saldos, còpies de seguretat
    RalcatDades/        Base de dades local (SQLite amb GRDB)
    RalcatSincro/       Sincronització amb CloudKit (CKSyncEngine)
    RalcatImportacio/   Importació de dades externes
  Tests/                Tests de cada mòdul (Swift Testing)

La lògica és al paquet RalcatDomini, separada de l'app, i es prova amb tests. L'app només fa servir aquests mòduls.

Arquitectura

Dades locals

Cada dispositiu té una base de dades SQLite (amb GRDB). L'app la llegeix sencera en segon pla, calcula d'una vegada els saldos i l'agrupació per dies, i les pantalles només consulten aquestes dades en memòria.

Els canvis d'esquema es fan sempre amb migracions noves (v1, v2…), que conserven les dades existents.

Sincronització

La sincronització fa servir CloudKit amb CKSyncEngine:

  • Base de dades privada de cada membre, zona Personal: comptes, categories personals, mitjans de pagament, despeses individuals i ingressos.
  • Zona Llar, compartida amb un CKShare des de l'iCloud de qui crea la llar (el propietari): membres, llar, categories de la llar i despeses conjuntes. L'altre membre hi accedeix per la base de dades compartida.
  • Una despesa que passa a ser conjunta (o deixa de ser-ho) canvia de zona i conserva el mateix identificador.
  • Tots els camps es desen a encryptedValues, xifrats d'extrem a extrem.
  • Les referències entre registres són identificadors de text, perquè CKRecord.Reference no funciona entre zones.
  • Conflictes: guanya l'última modificació.

Qui crea la llar n'és el propietari (membre A) i convida l'altre membre (membre B) des d'Ajustos. L'altre membre obre la invitació i s'hi uneix.

Còpies de seguretat

Les còpies es desen a iCloud Drive → Ralcat, en un fitxer JSON llegible (imports en cèntims, dates en format AAAA-MM-DD). En restaurar-ne una només s'afegeix el que falta: no es modifica ni s'esborra res del que ja hi ha. Els membres de la còpia es fan correspondre amb els de la llar actual, de manera que també es pot restaurar en una llar nova.

Compilar i executar

  1. Obre Ralcat.xcodeproj amb Xcode.
  2. A Signing & Capabilities, tria el teu equip de desenvolupament.
  3. Si no ets l'autor, canvia el bundle identifier (cat.spla.Ralcat) i el contenidor d'iCloud (iCloud.cat.spla.Ralcat), tant al projecte com a Ralcat.entitlements, Ralcat-Info.plist i Sincronitzador.identificadorContenidor.
  4. Executa l'app en un iPhone o en un simulador amb iOS 26 o posterior.

Des del terminal:

xcodebuild build -project Ralcat.xcodeproj -scheme Ralcat \
  -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=26.1'

Tests

El paquet és només per a iOS, de manera que swift test no serveix. Els tests s'executen al simulador:

cd RalcatDomini
xcodebuild test -scheme RalcatDomini-Package \
  -destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=26.1'

Tecnologia

  • Swift 6 i SwiftUI, amb Liquid Glass.
  • SQLite amb GRDB 7, de Gwendal Roué (llicència MIT).
  • CloudKit amb CKSyncEngine i CKShare.
  • Swift Testing.

Estat

Versió 0.3, en desenvolupament i en ús per a una sola llar, distribuïda amb TestFlight. L'esquema de CloudKit està desplegat a producció; els builds instal·lats des d'Xcode fan servir l'entorn de desenvolupament. Qualsevol camp nou cal desplegar-lo a producció abans de pujar un build.

Autor

spla