Skip to content

Commit

Permalink
Lower level cache (#34)
Browse files Browse the repository at this point in the history
* Adding default flags, and flag cache.

* Ensuring cache is stored, and updating logic to enable cache and defaults.

* Version bump for release

* Fixing UserDefaults typo calling wrong method.

* Improving getFlagUsingCacheAndDefaults

* Adding skipAPI, TTL and ensuring cache / defaults are only used in the case of failures, not successful calls.

* Finalising TTL logic and adding example code.

* Minor logic correction for skipAPI.

* Moving cache to the networking layer, with ability to customise.

* Fixing import issues.

* Moving cache configuration to a separate class.

* Removing un-necessary method for default flags.

---------

Co-authored-by: Ben Rometsch <[email protected]>
  • Loading branch information
wicheda and dabeeeenster authored Jul 13, 2023
1 parent 03bcb33 commit 6dfeaab
Show file tree
Hide file tree
Showing 9 changed files with 243 additions and 42 deletions.
2 changes: 1 addition & 1 deletion Example/FlagsmithClient.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
DAED1E8E268DBF9100F91DBC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
DAED1E90268DBF9100F91DBC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
DAED1E91268DBF9100F91DBC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
DAED1E92268DBF9100F91DBC /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DAED1E92268DBF9100F91DBC /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; tabWidth = 2; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down
21 changes: 19 additions & 2 deletions Example/FlagsmithClient/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,35 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
Flagsmith.shared.apiKey = "<add your API key from the Flagsmith settings page>"

// set default flags
Flagsmith.shared.defaultFlags = [Flag(featureName: "feature_a", enabled: false),
Flag(featureName: "font_size", intValue:12, enabled: true),
Flag(featureName: "my_name", stringValue:"Testing", enabled: true)]

// set cache on / off (defaults to off)
Flagsmith.shared.cacheConfig.useCache = true

// set custom cache to use (defaults to shared URLCache)
//Flagsmith.shared.cacheConfig.cache = <CUSTOM_CACHE>

// set skip API on / off (defaults to off)
Flagsmith.shared.cacheConfig.skipAPI = false

// set cache TTL in seconds (defaults to 0, i.e. infinite)
Flagsmith.shared.cacheConfig.cacheTTL = 90

// set analytics on or off
Flagsmith.shared.enableAnalytics = true

// set the analytics flush period in seconds
Flagsmith.shared.analyticsFlushPeriod = 10

Flagsmith.shared.getFeatureFlags() { (result) in
print(result)
print(result)
}
Flagsmith.shared.hasFeatureFlag(withID: "freeze_delinquent_accounts") { (result) in
print(result)
print(result)
}
//Flagsmith.shared.setTrait(Trait(key: "<my_key>", value: "<my_value>"), forIdentity: "<my_identity>") { (result) in print(result) }
//Flagsmith.shared.getIdentity("<my_key>") { (result) in print(result) }
Expand Down
14 changes: 11 additions & 3 deletions Example/Pods/Pods.xcodeproj/project.pbxproj

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion FlagsmithClient.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = 'FlagsmithClient'
s.version = '3.2.1'
s.version = '3.3.0'
s.summary = 'iOS Client written in Swift for Flagsmith. Ship features with confidence using feature flags and remote config.'
s.homepage = 'https://github.com/Flagsmith/flagsmith-ios-client'
s.license = { :type => 'MIT', :file => 'LICENSE' }
Expand Down
15 changes: 14 additions & 1 deletion FlagsmithClient/Classes/Feature.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
/**
A Feature represents a flag or remote configuration value on the server.
*/
public struct Feature: Decodable {
public struct Feature: Codable {
enum CodingKeys: String, CodingKey {
case name
case type
Expand All @@ -21,4 +21,17 @@ public struct Feature: Decodable {
public let name: String
public let type: String?
public let description: String?

init(name: String, type: String?, description: String?) {
self.name = name
self.type = type
self.description = description
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.name, forKey: .name)
try container.encodeIfPresent(self.type, forKey: .type)
try container.encodeIfPresent(self.description, forKey: .description)
}
}
35 changes: 34 additions & 1 deletion FlagsmithClient/Classes/Flag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
/**
A Flag represents a feature flag on the server.
*/
public struct Flag: Decodable {
public struct Flag: Codable {
enum CodingKeys: String, CodingKey {
case feature
case value = "feature_state_value"
Expand All @@ -20,4 +20,37 @@ public struct Flag: Decodable {
public let feature: Feature
public let value: TypedValue
public let enabled: Bool

public init(featureName:String, boolValue: Bool, enabled: Bool, featureType:String? = nil, featureDescription:String? = nil) {
self.init(featureName: featureName, value: TypedValue.bool(boolValue), enabled: enabled, featureType: featureType, featureDescription: featureDescription)
}

public init(featureName:String, floatValue: Float, enabled: Bool, featureType:String? = nil, featureDescription:String? = nil) {
self.init(featureName: featureName, value: TypedValue.float(floatValue), enabled: enabled, featureType: featureType, featureDescription: featureDescription)
}

public init(featureName:String, intValue: Int, enabled: Bool, featureType:String? = nil, featureDescription:String? = nil) {
self.init(featureName: featureName, value: TypedValue.int(intValue), enabled: enabled, featureType: featureType, featureDescription: featureDescription)
}

public init(featureName:String, stringValue: String, enabled: Bool, featureType:String? = nil, featureDescription:String? = nil) {
self.init(featureName: featureName, value: TypedValue.string(stringValue), enabled: enabled, featureType: featureType, featureDescription: featureDescription)
}

public init(featureName:String, enabled: Bool, featureType:String? = nil, featureDescription:String? = nil) {
self.init(featureName: featureName, value: TypedValue.null, enabled: enabled, featureType: featureType, featureDescription: featureDescription)
}

public init(featureName:String, value: TypedValue, enabled: Bool, featureType:String? = nil, featureDescription:String? = nil) {
self.feature = Feature(name: featureName, type: featureType, description: featureDescription)
self.value = value
self.enabled = enabled
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.feature, forKey: .feature)
try container.encode(self.value, forKey: .value)
try container.encode(self.enabled, forKey: .enabled)
}
}
Loading

0 comments on commit 6dfeaab

Please sign in to comment.