Rate Limiting en Swift : Guide complet pour les applications iOS et macOS
\n\nLe rate limiting (limitation du taux de requêtes) est un mécanisme essentiel pour le fonctionnement stable des applications mobiles et de bureau. Dans l'écosystème Swift (iOS/macOS), cette approche permet de contrôler le nombre d'appels API, d'opérations d'entrée/sortie ou de toute action répétée par unité de temps. Sans rate limiting, votre application risque d'être bloquée par le serveur, de gaspiller la batterie avec des tentatives infinies ou de créer une charge réseau excessive.
\n\nPourquoi limiter le taux de requêtes en Swift ?
\n\n- \n
- Protection contre le dépassement des limites API — de nombreux serveurs (par exemple, GitHub, Twitter, Stripe) imposent des quotas stricts sur le nombre de requêtes par minute/heure. \n
- Optimisation des performances — prévention d'une "tempête" d'appels lors d'un défilement rapide ou d'animations. \n
- Économie de trafic et de batterie — particulièrement important pour les appareils mobiles. \n
- Respect des politiques de l'App Store — des requêtes en arrière-plan excessives peuvent entraîner le rejet de l'application. \n
Approches principales pour implémenter le Rate Limiting en Swift
\n\nExaminons trois modèles de base que vous pouvez implémenter sans bibliothèques tierces :
\n\n1. Seau à jetons (Token Bucket)
\nAlgorithme classique où des "jetons" sont ajoutés à une vitesse fixe. Chaque requête consomme un jeton. S'il n'y a plus de jetons, la requête est rejetée.
\n\nimport Foundation\n\nfinal class TokenBucket {\n private let capacity: Int\n private var tokens: Int\n private let refillRate: Double // jetons par seconde\n private var lastRefill: Date\n private let queue = DispatchQueue(label: "token.bucket.queue")\n \n init(capacity: Int, refillRate: Double) {\n self.capacity = capacity\n self.tokens = capacity\n self.refillRate = refillRate\n self.lastRefill = Date()\n }\n \n func tryConsume() -> Bool {\n queue.sync {\n refill()\n if tokens > 0 {\n tokens -= 1\n return true\n }\n return false\n }\n }\n \n private func refill() {\n let now = Date()\n let elapsed = now.timeIntervalSince(lastRefill)\n let newTokens = Int(elapsed * refillRate)\n if newTokens > 0 {\n tokens = min(capacity, tokens + newTokens)\n lastRefill = now\n }\n }\n}\n\n// Exemple d'utilisation\nlet limiter = TokenBucket(capacity: 10, refillRate: 2.0) // 10 requêtes, 2 par seconde\nif limiter.tryConsume() {\n print("✅ Requête autorisée")\n} else {\n print("⛔️ Limite dépassée, veuillez patienter")\n}\n\n2. Algorithme à fenêtre glissante (Sliding Window)
\nMémorise les horodatages des N dernières requêtes réussies. Si la fenêtre est pleine, il bloque les nouveaux appels.
\n\nfinal class SlidingWindowLimiter {\n private let maxRequests: Int\n private let windowDuration: TimeInterval\n private var timestamps: [Date] = []\n private let queue = DispatchQueue(label: "sliding.window.queue")\n \n init(maxRequests: Int, windowDuration: TimeInterval = 60) {\n self.maxRequests = maxRequests\n self.windowDuration = windowDuration\n }\n \n func canProceed() -> Bool {\n queue.sync {\n let now = Date()\n // Supprimer les horodatages obsolètes\n timestamps.removeAll { now.timeIntervalSince($0) > windowDuration }\n \n if timestamps.count < maxRequests {\n timestamps.append(now)\n return true\n }\n return false\n }\n }\n}\n\n// Exemple : pas plus de 5 requêtes en 10 secondes\nlet windowLimiter = SlidingWindowLimiter(maxRequests: 5, windowDuration: 10)\n\n3. Throttling avec DispatchQueue
\nUtilise les mécanismes intégrés de GCD pour forcer un délai
Aussi dans la bibliothèque
Moment.js / Day.js pour JavaScript (Node.js) : guide complet avec exemples
Bibliothèque standard Go (Golang) : aperçu complet
Swagger/OpenAPI pour C# (.NET) : Génération et documentation d'API
Internationalisation (i18n) en C# (.NET) : guide complet