SPB Git

spb/lou-ka-ios Public

Lou·Ka iOS — app SwiftUI native de l'agrégateur de logements du Québec : filtres avancés, carte, stats, et mode Découverte (swipe) avec recommandation on-device

Swift 100%
7.5 KB · 158 lines markdown
Rendered Raw Blame History
1<div align="center">23# Lou·Ka — app iOS45### Tous les logements à louer du Québec. Dans votre poche.67**Compagnon natif de [www.lou-ka.com](https://www.lou-ka.com)** · [dépôt web](https://git.spboucher.ai/lou-ka.git)89![Swift](https://img.shields.io/badge/Swift-5.9-141814?style=for-the-badge&logo=swift&logoColor=d9f26b)10![SwiftUI](https://img.shields.io/badge/SwiftUI-iOS_17%2B-141814?style=for-the-badge&logo=apple&logoColor=d9f26b)11![XcodeGen](https://img.shields.io/badge/XcodeGen-project.yml-141814?style=for-the-badge&logoColor=d9f26b)12![TestFlight](https://img.shields.io/badge/TestFlight-1.2_(3)-141814?style=for-the-badge&logoColor=d9f26b)1314![Annonces](https://img.shields.io/badge/annonces_live-9000%2B-1c5c41?style=flat-square)15![Sources](https://img.shields.io/badge/sources-190%2B-1c5c41?style=flat-square)16![Reco](https://img.shields.io/badge/reco-on--device-1c5c41?style=flat-square)17![Design](https://img.shields.io/badge/design-%C3%A9ditorial_sharp-1c5c41?style=flat-square)1819*App SwiftUI 100 % native branchée sur l'API de production Lou-Ka —20mêmes 9 000+ annonces, même design signature papier/encre/lime,21plus un mode Découverte qui apprend vos goûts à chaque swipe.*2223</div>2425---2627## Les cinq onglets2829| | Onglet | Ce qu'on y fait |30|---|---|---|31| 📋 | **Annonces** | Recherche débouncée, chips de taille (1½…Studio), filtres complets (ville, **quartier dépendant de la ville**, loyer min–max, disponibilité, animaux, meublé, superficie, gestionnaire), pastilles de filtres actifs retirables d'un tap |32| 🔥 | **Découvrir** | Une annonce plein écran à la fois, photos défilables façon *stories*. **Swipe à droite = coup de cœur 💚, à gauche = on passe.** L'algorithme apprend et reclasse la pile en continu |33| 🗺 | **Carte** | Pastilles lime sur MapKit, presets de ville (Québec, Lévis, Montréal, Gatineau…), mini-fiche au tap → fiche complète |34| 📊 | **Stats** | Tuiles KPI (médian, moyen, libres maintenant), histogramme des loyers, palmarès régions/villes/tailles, inclusions de l'offre, baisses de prix |35| 🏢 | **Sources** | Registre des 255 gestionnaires : statut, compteurs, dernière synchronisation, recherche |3637La **fiche complète** reprend tout le contenu du site : galerie paginée, faits38(dispo, superficie, étage, stationnement…), inclusions, description structurée39(digest), carte, points d'intérêt à proximité, statistiques de quartier, et le40bouton « Voir l'annonce originale » vers le site du gestionnaire.4142## L'app en images4344<div align="center">4546| Accueil — recherche & filtres | Découverte — swipe & reco | Fiche complète |47|:---:|:---:|:---:|48| ![Accueil](docs/captures/accueil.png) | ![Découverte](docs/captures/decouverte.png) | ![Fiche](docs/captures/fiche.png) |4950| Carte province | Le marché en chiffres | Registre des sources |51|:---:|:---:|:---:|52| ![Carte](docs/captures/carte.png) | ![Stats](docs/captures/stats.png) | ![Sources](docs/captures/sources.png) |5354</div>5556## Le mode Découverte, en 30 secondes5758Chaque swipe nourrit un **moteur de recommandation on-device** (`LouKa/Reco.swift`) :59601. Chaque annonce est décomposée en caractéristiques : ville, quartier, taille,61   tranche de prix (300 $), meublé, animaux, balcon, stationnement, gestionnaire.622. Pour chaque caractéristique, on maintient un taux d'appréciation63   **lissé (Laplace)** : `(👍 + 1) / (👍 + 👎 + 2)`, pondéré par la confiance64   `1 + log(1 + n)`.653. Le score d'une annonce = moyenne pondérée des taux de ses caractéristiques.66   La pile est **reclassée toutes les 8 décisions**, et ~1 carte sur 6 vient du67   reste du bassin (exploration) pour éviter la bulle de filtre.684. Tout est persisté localement (`UserDefaults`) — **aucune donnée ne quitte69   l'appareil**. Les coups de cœur se retrouvent sous le ♥ en haut à droite.7071Après 4 likes de studios à ~900 $, l'en-tête affiche déjà72« *Vos goûts : Studio · ~900 $* » et la pile s'adapte.7374## Architecture7576```77ios/78├── project.yml               # définition XcodeGen (cible, Info.plist, polices)79├── ExportOptions.plist       # upload App Store Connect (méthode + team)80└── LouKa/81    ├── App.swift             # point d'entrée, onglets, apparence nav, thème clair forcé82    ├── API.swift             # client HTTPS → www.lou-ka.com (filtres complets)83    ├── Models.swift          # décodage tolérant (un champ inattendu ≠ annonce perdue)84    ├── Reco.swift            # moteur de recommandation du mode Découverte85    ├── Theme.swift           # design system : palette, ombres décalées, typo, fr-CA86    ├── Fonts/                # Space Grotesk (instances statiques) + JetBrains Mono87    └── Views/88        ├── HomeView.swift          # accueil + feuille de filtres89        ├── DiscoverView.swift      # swipe plein écran + coups de cœur90        ├── ListingCardView.swift   # carte d'annonce91        ├── ListingDetailView.swift # fiche complète92        ├── MapTabView.swift        # carte province93        ├── StatsView.swift         # portrait du marché94        └── SourcesView.swift       # registre des gestionnaires95```9697**Design « éditorial sharp »** — porté du site : papier `#f5f3ee`, encre98`#141814`, vert profond `#1c5c41`, lime électrique `#d9f26b`, bordures encre et99ombres décalées, Space Grotesk pour les titres et les prix, JetBrains Mono pour100les micro-étiquettes. Thème clair **forcé** (comme le site) pour que le mode101sombre du téléphone ne rende jamais un texte illisible.102103> Détail typo : la Space Grotesk variable de Google Fonts n'expose aucun nom104> PostScript d'instance — iOS ne voyait que « Light ». Les instances statiques105> (Regular/Medium/Bold) sont générées avec fontTools et embarquées.106107## Développer108109```bash110brew install xcodegen111cd ios112xcodegen generate            # (ré)génère LouKa.xcodeproj depuis project.yml113open LouKa.xcodeproj         # ⌘R sur un simulateur iOS 17+114```115116Aucune dépendance externe — SwiftUI, MapKit, Observation, c'est tout.117L'app pointe sur l'API de production ; pour une instance locale, changez118`API.base` dans `LouKa/API.swift`.119120## Publier sur TestFlight121122```bash123# bump MARKETING_VERSION / CURRENT_PROJECT_VERSION dans project.yml, puis :124xcodegen generate125xcodebuild archive -project LouKa.xcodeproj -scheme LouKa \126  -destination 'generic/platform=iOS' -archivePath build/LouKa.xcarchive \127  -allowProvisioningUpdates128xcodebuild -exportArchive -archivePath build/LouKa.xcarchive \129  -exportOptionsPlist ExportOptions.plist -allowProvisioningUpdates130```131132L'export téléverse directement sur App Store Connect (signature automatique,133fiche `com.spboucher.louka` existante) ; la build apparaît dans TestFlight134après le traitement d'Apple.135136## Principes1371381. **Fidélité au web** — mêmes données, même langage visuel, aucun prix inventé.1392. **Robustesse** — décodage champ par champ avec repli : une source mal formée140   ne fait jamais disparaître les autres annonces.1413. **Vie privée** — le profil de goûts reste sur l'appareil, point.1424. **Zéro dépendance** — pas de SPM, pas de Pods : le SDK Apple suffit.143144---145146<div align="center">147148## Auteur149150**Simon-Pierre Boucher**151152[![Email](https://img.shields.io/badge/contact@spboucher.ai-141814?style=for-the-badge&logo=minutemailer&logoColor=d9f26b)](mailto:contact@spboucher.ai)153[![Git](https://img.shields.io/badge/git.spboucher.ai-141814?style=for-the-badge&logo=git&logoColor=d9f26b)](https://git.spboucher.ai)154155© 2026 Simon-Pierre Boucher — tous droits réservés.156157</div>158