ios/Classes/ConfidenceFlutterSdkPlugin.swift (207 lines of code) (raw):

import Flutter import UIKit public class ConfidenceFlutterSdkPlugin: NSObject, FlutterPlugin { public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "confidence_flutter_sdk", binaryMessenger: registrar.messenger()) let instance = ConfidenceFlutterSdkPlugin() registrar.addMethodCallDelegate(instance, channel: channel) } var confidence: Confidence? = nil public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { switch call.method { case "flush": guard let confidence = self.confidence else { result("") return } confidence.flush() break; case "readAllFlags": guard let flags = try? readAllFlags() else { result("{}") return } let map = flags.reduce(into: [String: ConfidenceValue]()) { map, flag in map[flag.flag] = flag.value } let networkMessage = TypeMapper.convert(structure: map) let encoder = JSONEncoder() let data = try! encoder.encode(networkMessage) let str = String(decoding: data, as: UTF8.self) result(str) break; case "setup": let apiKey = call.arguments as! String self.confidence = Confidence.Builder(clientSecret: apiKey) .build() result("") break; case "isStorageEmpty": guard let confidence = self.confidence else { result(true) return } result(confidence.isStorageEmpty()) break; case "fetchAndActivate": Task { guard let confidence = self.confidence else { result("") return } try! await confidence.fetchAndActivate() result("") } break; case "activateAndFetchAsync": Task { guard let confidence = self.confidence else { result("") return } try! confidence.activate() confidence.asyncFetch() result("") } break; case "putContext": guard let args = call.arguments as? Dictionary<String, Any> else { result("") return } let key = args["key"] as! String let wrappedValue = args["value"] as! Dictionary<String, Any> let type = wrappedValue["type"] as! String let value = convertValue(type, wrappedValue["value"]!) confidence?.putContext(key: key, value: value) result("") break; case "putAllContext": guard let args = call.arguments as? Dictionary<String, Dictionary<String, Any>> else { result("") return } let context = args["context"] as! Dictionary<String, Dictionary<String, Any>> let map: ConfidenceStruct = context.mapValues { wrappedValue in let type = wrappedValue["type"] as! String return convertValue(type, wrappedValue["value"]!) } confidence?.putContext(context: map) result("") break; case "track": guard let args = call.arguments as? Dictionary<String, Any> else { return } let eventName = args["eventName"] as! String let data = args["data"] as! Dictionary<String, Dictionary<String, Any>> let convertedData = data.convert() try? confidence?.track(eventName: eventName, data: convertedData) break; case "getBool": let arguments = call.arguments as! Dictionary<String, Any> let defaultValue = arguments["defaultValue"] as! Bool let key = arguments["key"] as! String guard let confidence = self.confidence else { result(defaultValue) return } let message: Bool = confidence.getValue(key: key, defaultValue: defaultValue) result(message) break; case "getString": let arguments = call.arguments as! Dictionary<String, Any> let defaultValue = arguments["defaultValue"] as! String let key = arguments["key"] as! String guard let confidence = self.confidence else { result(defaultValue) return } let message: String = confidence.getValue(key: key, defaultValue: defaultValue) result(message) break; case "getDouble": let arguments = call.arguments as! Dictionary<String, Any> let defaultValue = arguments["defaultValue"] as! Double let key = arguments["key"] as! String guard let confidence = self.confidence else { result(defaultValue) return } let message: Double = confidence.getValue(key: key, defaultValue: defaultValue) result(message) break; case "getInt": let arguments = call.arguments as! Dictionary<String, Any> let defaultValue = arguments["defaultValue"] as! Int let key = arguments["key"] as! String guard let confidence = self.confidence else { result(defaultValue) return } let message: Int = confidence.getValue(key: key, defaultValue: defaultValue) result(message) break; case "getObject": let arguments = call.arguments as! Dictionary<String, Any> let defaultValueWrapped = arguments["defaultValue"] as! Dictionary<String, Dictionary<String, Any>> let defaultValue = defaultValueWrapped.convert() let key = arguments["key"] as! String guard let confidence = self.confidence else { result([:]) return } let message: ConfidenceStruct = confidence.getValue(key: key, defaultValue: defaultValue) let networkMessage = TypeMapper.convert(structure: message) let encoder = JSONEncoder() let data = try! encoder.encode(networkMessage) let str = String(decoding: data, as: UTF8.self) result(str) break; default: result(FlutterMethodNotImplemented) } } } func readAllFlags() throws -> [ResolvedValue] { let storage = DefaultStorage(filePath: "confidence.flags.resolve") let savedFlags = try storage.load(defaultValue: FlagResolution.EMPTY) return savedFlags.flags } extension Dictionary<String, Dictionary<String, Any>> { func convert() -> ConfidenceStruct { var map: ConfidenceStruct = [:] for (key, wrappedValue) in self { let type = wrappedValue["type"] as! String map[key] = convertValue(type, wrappedValue["value"]!) } return map } } func convertValue(_ type: String, _ value: Any) -> ConfidenceValue { switch type { case "bool": return ConfidenceValue.init(boolean: value as! Bool) case "double": return ConfidenceValue.init(double: value as! Double) case "int": return ConfidenceValue.init(integer: value as! Int) case "map": let dataMap = value as! Dictionary<String, Dictionary<String, Any>> let map: ConfidenceStruct = dataMap.mapValues { wrappedValue in let type = wrappedValue["type"] as! String return convertValue(type, wrappedValue["value"]!) } return ConfidenceValue.init(structure: map) case "list": let list = value as! [Dictionary<String, Any>] return ConfidenceValue.init(list: list.map { wrappedValue in let type = wrappedValue["type"] as! String return convertValue(type, wrappedValue["value"]!) }) case "string": return ConfidenceValue.init(string: value as! String) default: return ConfidenceValue.init(integer: 0) } }