Rate Limiting en Swift : Limitation du taux de requêtes pour iOS et macOS

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Rate Limiting en Swift : Guide complet pour les applications iOS et macOS

\n\n

Le 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\n

Pourquoi 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
\n\n

Approches principales pour implémenter le Rate Limiting en Swift

\n\n

Examinons trois modèles de base que vous pouvez implémenter sans bibliothèques tierces :

\n\n

1. Seau à jetons (Token Bucket)

\n

Algorithme 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\n
import 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\n

2. Algorithme à fenêtre glissante (Sliding Window)

\n

Mémorise les horodatages des N dernières requêtes réussies. Si la fenêtre est pleine, il bloque les nouveaux appels.

\n\n
final 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\n

3. Throttling avec DispatchQueue

\n

Utilise les mécanismes intégrés de GCD pour forcer un délai

Recommendations