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%
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)89101112-141814?style=for-the-badge&logoColor=d9f26b)13141516171819*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|  |  |  |4950| Carte province | Le marché en chiffres | Registre des sources |51|:---:|:---:|:---:|52|  |  |  |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[](mailto:contact@spboucher.ai)153[](https://git.spboucher.ai)154155© 2026 Simon-Pierre Boucher — tous droits réservés.156157</div>158