Camji55
2/27/2019 - 5:38 PM

FeatureFlagClient.swift

private struct Flags: Decodable {
  let flags: [Flag]
}

private struct Flag: Decodable {
  let key: String
  let enabled: Bool
}

public class FeatureFlagClient {
    private static var endpoint: URL?
    private static var flags: Flags?
    
    public static func configure(withEndpoint endpoint: String, refreshRate: TimeInterval = 300) {
        guard let endpointURL = URL(string: endpoint) else {
            print("Endoint: \(endpoint) is invalid.")
            return
        }
        
        self.endpoint = endpointURL
        
        self.fetchAllFlags()
        
        Timer.scheduledTimer(withTimeInterval: refreshRate, repeats: true) { _ in
            self.fetchAllFlags()
        }
    }
    
    private static func fetchAllFlags() {
        guard let endpoint = self.endpoint else {
            print("Unable to fetch feature flags. Error: Unknown reason.")
            return
        }
        
        var urlRequest = URLRequest(url: endpoint)
        urlRequest.httpMethod = "GET"
        
        let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            if let error = error {
                print("Unable to fetch feature flags. Error: \(error.localizedDescription)")
                return
            }
            
            guard let data = data else {
                print("Unable to fetch feature flags. Error: Unknown reason.")
                return
            }
            
            let decoder = JSONDecoder()
            
            do {
                flags = try decoder.decode(Flags.self, from: data)
                NotificationCenter.default.post(Notification(name: Notification.Name.FeatureFlagsUpdated))
            } catch {
                print("Unable to fetch feature flags. Error: \(error.localizedDescription).")
                return
            }
        }
        
        dataTask.resume()
    }
    
    public static func isFlagEnabled(_ key: String) -> Bool {
        let flag = self.flags?.flags.first(where: {$0.key == key})
        return flag?.enabled ?? false
    }
}

public extension Notification.Name {
    static let FeatureFlagsUpdated = Notification.Name("featureFlagsUpdated")
}