From 695bcdd3933e10db0090df0e43b9c49e37af921c Mon Sep 17 00:00:00 2001 From: Gareth Reese <8297652+gazreese@users.noreply.github.com> Date: Mon, 11 Mar 2024 09:39:39 +0000 Subject: [PATCH] Better concurrency support in iOS API Manager (#45) * Add a unit test that fails during concurrent usage * Ensure that the unsafe operations are executed concurrently, while also ensuring completions go back to the main thread * Add tests to the test app to show the getFeatureFlags() working concurrently and reporting to the main thread * Remove a probable memory leak in the API manager, which was keeping two strong references to each request / response * Convert from NSMutableData to Data class internally * A few small formatting and commenting fixes to finish the PR * Test for API errors in our concurrent test --- Example/FlagsmithClient/AppDelegate.swift | 16 +- Example/Podfile.lock | 6 +- .../FlagsmithClient.podspec.json | 6 +- Example/Pods/Manifest.lock | 6 +- Example/Pods/Pods.xcodeproj/project.pbxproj | 414 +++++++++--------- .../FlagsmithClient-Info.plist | 4 +- .../FlagsmithClient.debug.xcconfig | 3 +- .../FlagsmithClient.release.xcconfig | 3 +- .../Pods-FlagsmithClient_Example-Info.plist | 2 +- ...Pods-FlagsmithClient_Example-frameworks.sh | 4 +- ...ods-FlagsmithClient_Example.debug.xcconfig | 2 +- ...s-FlagsmithClient_Example.release.xcconfig | 2 +- .../Classes/Internal/APIManager.swift | 61 +-- FlagsmithClient/Classes/Internal/Router.swift | 2 +- FlagsmithClient/Tests/APIManagerTests.swift | 28 ++ 15 files changed, 308 insertions(+), 251 deletions(-) diff --git a/Example/FlagsmithClient/AppDelegate.swift b/Example/FlagsmithClient/AppDelegate.swift index a98b03b..a68b1d0 100644 --- a/Example/FlagsmithClient/AppDelegate.swift +++ b/Example/FlagsmithClient/AppDelegate.swift @@ -9,11 +9,15 @@ import UIKit import FlagsmithClient +func isSuccess(_ result: Result) -> Bool { + if case .success = result { return true } else { return false } +} + @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - + let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent) func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. @@ -48,6 +52,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Flagsmith.shared.hasFeatureFlag(withID: "freeze_delinquent_accounts") { (result) in print(result) } + + // Try getting the feature flags concurrently to ensure that this does not cause any issues + // This was originally highlighted in https://github.com/Flagsmith/flagsmith-ios-client/pull/40 + for _ in 1...20 { + concurrentQueue.async { + Flagsmith.shared.getFeatureFlags() { (result) in + } + } + } + //Flagsmith.shared.setTrait(Trait(key: "", value: ""), forIdentity: "") { (result) in print(result) } //Flagsmith.shared.getIdentity("") { (result) in print(result) } return true diff --git a/Example/Podfile.lock b/Example/Podfile.lock index a603eb2..735d4f9 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - FlagsmithClient (1.1.2) + - FlagsmithClient (3.4.0) DEPENDENCIES: - FlagsmithClient (from `../`) @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - FlagsmithClient: dd72c22b356fe008aaec4a7069e88579c3b7d979 + FlagsmithClient: 0f8ed4a38dec385d73cc21a64b791b39bcc8c32b PODFILE CHECKSUM: 9fc876dee0cf031cae843156b0740a94b4994d8c -COCOAPODS: 1.11.2 +COCOAPODS: 1.13.0 diff --git a/Example/Pods/Local Podspecs/FlagsmithClient.podspec.json b/Example/Pods/Local Podspecs/FlagsmithClient.podspec.json index 8e76ae1..3081ee8 100644 --- a/Example/Pods/Local Podspecs/FlagsmithClient.podspec.json +++ b/Example/Pods/Local Podspecs/FlagsmithClient.podspec.json @@ -1,6 +1,6 @@ { "name": "FlagsmithClient", - "version": "1.1.2", + "version": "3.4.0", "summary": "iOS Client written in Swift for Flagsmith. Ship features with confidence using feature flags and remote config.", "homepage": "https://github.com/Flagsmith/flagsmith-ios-client", "license": { @@ -12,11 +12,11 @@ }, "source": { "git": "https://github.com/Flagsmith/flagsmith-ios-client.git", - "tag": "1.1.2" + "tag": "3.4.0" }, "social_media_url": "https://twitter.com/getflagsmith", "platforms": { - "ios": "8.0" + "ios": "12.0" }, "source_files": "FlagsmithClient/Classes/**/*", "swift_versions": "4.0", diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index a603eb2..735d4f9 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -1,5 +1,5 @@ PODS: - - FlagsmithClient (1.1.2) + - FlagsmithClient (3.4.0) DEPENDENCIES: - FlagsmithClient (from `../`) @@ -9,8 +9,8 @@ EXTERNAL SOURCES: :path: "../" SPEC CHECKSUMS: - FlagsmithClient: dd72c22b356fe008aaec4a7069e88579c3b7d979 + FlagsmithClient: 0f8ed4a38dec385d73cc21a64b791b39bcc8c32b PODFILE CHECKSUM: 9fc876dee0cf031cae843156b0740a94b4994d8c -COCOAPODS: 1.11.2 +COCOAPODS: 1.13.0 diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 1e52f60..6909f18 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,30 +7,30 @@ objects = { /* Begin PBXBuildFile section */ - 0A2426C7E3721ED5AEADF4CC344F6642 /* Feature.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8A7BD53895AF16384B78CB7116DEBD7 /* Feature.swift */; }; - 1845D603B597C651F0EE6080EF459DBB /* Flagsmith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 757CB2DED75CA13C202204D5B88B7B9A /* Flagsmith.swift */; }; + 011196679F1DBAD78B3284BB60F1CC7E /* FlagsmithAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77743E9FB921729A0C34B2CBE7A1F4CD /* FlagsmithAnalytics.swift */; }; 1D8CF59EBBFF8148D15D0EFCAAA414A2 /* Pods-FlagsmithClient_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 02E4DC32B2FC713ED935462DA9F1CBF9 /* Pods-FlagsmithClient_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 2C55F74AE43F34E4F3952F5B86AADBF5 /* Flagsmith+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287971AEF04B8BFE50BA6B4E9CB5A76E /* Flagsmith+Concurrency.swift */; }; - 36B29445E454DBDF1CD394B9155A9170 /* Trait.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1CEBBBF5F9F986FB033B56D22422A4A /* Trait.swift */; }; + 28E2C1F327F2FEFC3D6193D0E775DD16 /* Flagsmith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD71DED3359EE67BB9C921E2917DA7A /* Flagsmith.swift */; }; + 361AD17B75FDA9970FF500DEE9B88729 /* APIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7482B233360C108341B85DF6F4F296D2 /* APIManager.swift */; }; 3CB1981582BED249B73F39640A046EC6 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; - 3E267A21653D98B77234CDD42A3A1D59 /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B3C161B19E351C1591E2039D787AD7C /* Identity.swift */; }; - 4A510C0AE712CD782D25F2276904F827 /* Flag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DDEFBF90EE0DCCBEE1F3D989919BC4A /* Flag.swift */; }; - 7219F5929D0335018EE8AB89735695D2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; - 83D44370DA79D1E1C2C20ABD98D13475 /* FlagsmithClient-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2EF53626DB8E67CE608BFEEB08DF2A5C /* FlagsmithClient-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B7C44FEAEB3099494B79EA35B9F71DE0 /* FlagsmithClient-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A4CB83310920D7A2F76B1F4F715BA5 /* FlagsmithClient-dummy.m */; }; + 611EFA95BB13886C84B3692AF65E66F8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */; }; + 6EABC9E673A27FAC4180F2F08C4F2B3D /* CachedURLResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92D88FCDAEE505ABAF4F0C9E59BEBB6A /* CachedURLResponse.swift */; }; + 7296A208906AA3BC74014294652982CA /* FlagsmithClient-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ECFF7C4FBE6AA88F7F7ECDCE6B66EA2 /* FlagsmithClient-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 78FC3BC1E0FADEB53A278A0A4C6DA6E8 /* UnknownTypeValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC513B1FDC4FEFFA6AC514C6DA6E3329 /* UnknownTypeValue.swift */; }; + 82EA3819E558968027E9A21E8E20A4A7 /* Flagsmith+Concurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 919D3C18E297943C015F838AEEAD057F /* Flagsmith+Concurrency.swift */; }; + 90AE5624A1F9C4DAA5ED6ED01FB6AA98 /* Traits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D7B03B15ACDBBDA718D00CF6E18D416 /* Traits.swift */; }; + 95A960387ADF0D89DD60C4E6F563455F /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66035645C7F450B9A20A5AA2F1CC43B6 /* Router.swift */; }; + 97DE10D6905CEF731DD15EB738B843DD /* Trait.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CB810BA1DD243ED447F96C1EC7AD63F /* Trait.swift */; }; + A3EAECF66E99CCF1D3251DB251AE6F9D /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED101D3AAE62D955200E49181AC69EF4 /* Identity.swift */; }; + A9DAAC7965A5F9D409F7335FC223BEE6 /* TypedValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 158A52A6379630867E2111515A492DDE /* TypedValue.swift */; }; + B9ECC98F1865D64AA4B986208D0938C1 /* FlagsmithClient-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B880F3CB2ABE4DB1E22B3CC5541C2D8 /* FlagsmithClient-dummy.m */; }; C5344C505516395035EAB8B9FC111FE2 /* Pods-FlagsmithClient_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0F66D3EFFD8615AE149DCEEE155C049F /* Pods-FlagsmithClient_Example-dummy.m */; }; - DA2D2B182A1BBFF200CD98D9 /* Traits.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2D2B172A1BBFF200CD98D9 /* Traits.swift */; }; - DAB856122A4455B2000520DC /* CachedURLResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB856112A4455B2000520DC /* CachedURLResponse.swift */; }; - E119200D27E4E5CE00820B87 /* FlagsmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E119200827E4E5CE00820B87 /* FlagsmithError.swift */; }; - E119200E27E4E5CE00820B87 /* FlagsmithAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = E119200A27E4E5CE00820B87 /* FlagsmithAnalytics.swift */; }; - E119200F27E4E5CE00820B87 /* APIManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E119200B27E4E5CE00820B87 /* APIManager.swift */; }; - E119201027E4E5CE00820B87 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = E119200C27E4E5CE00820B87 /* Router.swift */; }; - E190202E27E24E7600C5EE2C /* TypedValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = E190202D27E24E7600C5EE2C /* TypedValue.swift */; }; - EE4568DD2E22CD3A570CAB24968F9BE7 /* UnknownTypeValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 772F9BEA66F23FD7DB187ACBEB72BA93 /* UnknownTypeValue.swift */; }; + CFC4FDB2F9D6E43C28FE902C6131C027 /* FlagsmithError.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD829895C1256784784DBBFC3020A222 /* FlagsmithError.swift */; }; + CFFE0F58344636A5789C357F2BE50820 /* Feature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B77E851969A4CF4C7F75194BFC80A5B /* Feature.swift */; }; + F0F13B1D5F547C03C257DF46C49594E4 /* Flag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DC8A87D5B1A7F57E12361CE1D5E95B8 /* Flag.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 0842EB6A5D76A0A91DC6E3D255DAF973 /* PBXContainerItemProxy */ = { + A39FC97A60B4E4EF1C00CDE9EDF2C25D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; proxyType = 1; @@ -41,50 +41,50 @@ /* Begin PBXFileReference section */ 02E4DC32B2FC713ED935462DA9F1CBF9 /* Pods-FlagsmithClient_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-FlagsmithClient_Example-umbrella.h"; sourceTree = ""; }; - 0CDC17B06AEC182F2B61F2F73541EFAF /* FlagsmithClient.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FlagsmithClient.debug.xcconfig; sourceTree = ""; }; + 0CD71DED3359EE67BB9C921E2917DA7A /* Flagsmith.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Flagsmith.swift; path = FlagsmithClient/Classes/Flagsmith.swift; sourceTree = ""; }; 0F66D3EFFD8615AE149DCEEE155C049F /* Pods-FlagsmithClient_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-FlagsmithClient_Example-dummy.m"; sourceTree = ""; }; - 23348535C2523FAC4E5FD55FF5CA18AA /* FlagsmithClient.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FlagsmithClient.release.xcconfig; sourceTree = ""; }; + 0FAC90C1E63439160B035434A1CF25F1 /* FlagsmithClient-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FlagsmithClient-Info.plist"; sourceTree = ""; }; + 158A52A6379630867E2111515A492DDE /* TypedValue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TypedValue.swift; path = FlagsmithClient/Classes/TypedValue.swift; sourceTree = ""; }; 250DE57229233B0BAD273A076F108A0E /* Pods-FlagsmithClient_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-FlagsmithClient_Example.release.xcconfig"; sourceTree = ""; }; - 287971AEF04B8BFE50BA6B4E9CB5A76E /* Flagsmith+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Flagsmith+Concurrency.swift"; path = "FlagsmithClient/Classes/Flagsmith+Concurrency.swift"; sourceTree = ""; }; - 2DDEFBF90EE0DCCBEE1F3D989919BC4A /* Flag.swift */ = {isa = PBXFileReference; includeInIndex = 1; indentWidth = 2; lastKnownFileType = sourcecode.swift; name = Flag.swift; path = FlagsmithClient/Classes/Flag.swift; sourceTree = ""; tabWidth = 2; }; - 2EF53626DB8E67CE608BFEEB08DF2A5C /* FlagsmithClient-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FlagsmithClient-umbrella.h"; sourceTree = ""; }; + 2DC8A87D5B1A7F57E12361CE1D5E95B8 /* Flag.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Flag.swift; path = FlagsmithClient/Classes/Flag.swift; sourceTree = ""; }; 368DFAE2AAAB80524EFAFD71A2C92F84 /* Pods-FlagsmithClient_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-FlagsmithClient_Example-acknowledgements.markdown"; sourceTree = ""; }; 3B040CFA25391975C1615BFB481B68C9 /* Pods-FlagsmithClient_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-FlagsmithClient_Example.debug.xcconfig"; sourceTree = ""; }; - 68DDF334F75630BAA85571DF47D87C89 /* FlagsmithClient.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FlagsmithClient.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 69E74567D7DE2313D6054FA08CFC5940 /* FlagsmithClient-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FlagsmithClient-prefix.pch"; sourceTree = ""; }; + 47EFBF8F57718DBF9FE586CBDB6CC0DC /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; path = LICENSE; sourceTree = ""; }; + 4CB810BA1DD243ED447F96C1EC7AD63F /* Trait.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Trait.swift; path = FlagsmithClient/Classes/Trait.swift; sourceTree = ""; }; + 591BEAEF977192FC1893BEAC10ABB7F0 /* FlagsmithClient.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; path = FlagsmithClient.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 5D7B03B15ACDBBDA718D00CF6E18D416 /* Traits.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Traits.swift; path = FlagsmithClient/Classes/Traits.swift; sourceTree = ""; }; + 66035645C7F450B9A20A5AA2F1CC43B6 /* Router.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; + 68DDF334F75630BAA85571DF47D87C89 /* FlagsmithClient */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FlagsmithClient; path = FlagsmithClient.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6B880F3CB2ABE4DB1E22B3CC5541C2D8 /* FlagsmithClient-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FlagsmithClient-dummy.m"; sourceTree = ""; }; + 6DEAF76385A937740682012C42A3F628 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; path = README.md; sourceTree = ""; }; 73010CC983E3809BECEE5348DA1BB8C6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - 757CB2DED75CA13C202204D5B88B7B9A /* Flagsmith.swift */ = {isa = PBXFileReference; includeInIndex = 1; indentWidth = 2; lastKnownFileType = sourcecode.swift; name = Flagsmith.swift; path = FlagsmithClient/Classes/Flagsmith.swift; sourceTree = ""; tabWidth = 2; }; - 772F9BEA66F23FD7DB187ACBEB72BA93 /* UnknownTypeValue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UnknownTypeValue.swift; path = FlagsmithClient/Classes/UnknownTypeValue.swift; sourceTree = ""; }; - 7CB5FDC929BB21CB23FFC8143AF6322F /* FlagsmithClient.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; path = FlagsmithClient.podspec; sourceTree = ""; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 7482B233360C108341B85DF6F4F296D2 /* APIManager.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = APIManager.swift; sourceTree = ""; }; + 77743E9FB921729A0C34B2CBE7A1F4CD /* FlagsmithAnalytics.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = FlagsmithAnalytics.swift; sourceTree = ""; }; + 7ECFF7C4FBE6AA88F7F7ECDCE6B66EA2 /* FlagsmithClient-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FlagsmithClient-umbrella.h"; sourceTree = ""; }; + 8078BAE70CEB3897642FFDD030790F4B /* FlagsmithClient-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FlagsmithClient-prefix.pch"; sourceTree = ""; }; 81A815D8A0C28062CD4A8224C6883D5D /* Pods-FlagsmithClient_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-FlagsmithClient_Example.modulemap"; sourceTree = ""; }; - 9B3C161B19E351C1591E2039D787AD7C /* Identity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Identity.swift; path = FlagsmithClient/Classes/Identity.swift; sourceTree = ""; }; - 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 8236C25B17E89C77288367CCF5B829A9 /* FlagsmithClient.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FlagsmithClient.debug.xcconfig; sourceTree = ""; }; + 919D3C18E297943C015F838AEEAD057F /* Flagsmith+Concurrency.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Flagsmith+Concurrency.swift"; path = "FlagsmithClient/Classes/Flagsmith+Concurrency.swift"; sourceTree = ""; }; + 92D88FCDAEE505ABAF4F0C9E59BEBB6A /* CachedURLResponse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = CachedURLResponse.swift; sourceTree = ""; }; + 9B77E851969A4CF4C7F75194BFC80A5B /* Feature.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Feature.swift; path = FlagsmithClient/Classes/Feature.swift; sourceTree = ""; }; + 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; A7D159AFD71C50F45CAAD458140D8648 /* Pods-FlagsmithClient_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-FlagsmithClient_Example-acknowledgements.plist"; sourceTree = ""; }; - A8A7BD53895AF16384B78CB7116DEBD7 /* Feature.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Feature.swift; path = FlagsmithClient/Classes/Feature.swift; sourceTree = ""; }; - AD64CA35A3E22216D1D0738A812F312E /* FlagsmithClient.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FlagsmithClient.modulemap; sourceTree = ""; }; - AD917AEBF5902707C06AF63A186D1E24 /* FlagsmithClient-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FlagsmithClient-Info.plist"; sourceTree = ""; }; + B27C6884FC1F031C5CCE03E04DA59B40 /* FlagsmithClient.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FlagsmithClient.release.xcconfig; sourceTree = ""; }; + B4164394D814A1BA2FA6A7C7662493C5 /* FlagsmithClient.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = FlagsmithClient.modulemap; sourceTree = ""; }; B7528E5D2516E37BD5B3A5DC02010477 /* Pods-FlagsmithClient_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-FlagsmithClient_Example-frameworks.sh"; sourceTree = ""; }; - C1817E8624F31BD483479898AD8A9F9C /* Pods_FlagsmithClient_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FlagsmithClient_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - C1CEBBBF5F9F986FB033B56D22422A4A /* Trait.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Trait.swift; path = FlagsmithClient/Classes/Trait.swift; sourceTree = ""; }; - C55271DDAE55BE2BA1AFA657FA24971A /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - C7A4CB83310920D7A2F76B1F4F715BA5 /* FlagsmithClient-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FlagsmithClient-dummy.m"; sourceTree = ""; }; - DA2D2B172A1BBFF200CD98D9 /* Traits.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Traits.swift; path = FlagsmithClient/Classes/Traits.swift; sourceTree = ""; }; - DAB856112A4455B2000520DC /* CachedURLResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CachedURLResponse.swift; sourceTree = ""; }; - E119200827E4E5CE00820B87 /* FlagsmithError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FlagsmithError.swift; path = FlagsmithClient/Classes/FlagsmithError.swift; sourceTree = ""; }; - E119200A27E4E5CE00820B87 /* FlagsmithAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlagsmithAnalytics.swift; sourceTree = ""; }; - E119200B27E4E5CE00820B87 /* APIManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.swift; path = APIManager.swift; sourceTree = ""; tabWidth = 2; }; - E119200C27E4E5CE00820B87 /* Router.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = ""; }; - E190202D27E24E7600C5EE2C /* TypedValue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TypedValue.swift; path = FlagsmithClient/Classes/TypedValue.swift; sourceTree = ""; }; + C1817E8624F31BD483479898AD8A9F9C /* Pods-FlagsmithClient_Example */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "Pods-FlagsmithClient_Example"; path = Pods_FlagsmithClient_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CD829895C1256784784DBBFC3020A222 /* FlagsmithError.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlagsmithError.swift; path = FlagsmithClient/Classes/FlagsmithError.swift; sourceTree = ""; }; + DC513B1FDC4FEFFA6AC514C6DA6E3329 /* UnknownTypeValue.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = UnknownTypeValue.swift; path = FlagsmithClient/Classes/UnknownTypeValue.swift; sourceTree = ""; }; E28010F1C58E656FC37588C8A00FEE38 /* Pods-FlagsmithClient_Example-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-FlagsmithClient_Example-Info.plist"; sourceTree = ""; }; - ED741D6F7C10EB042045149B0E9347C9 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; + ED101D3AAE62D955200E49181AC69EF4 /* Identity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Identity.swift; path = FlagsmithClient/Classes/Identity.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - BB9BF91511BEE5C82B809BC460B4F6FE /* Frameworks */ = { + 5978E19B2CF28713F5F5FAE1384AF5B4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7219F5929D0335018EE8AB89735695D2 /* Foundation.framework in Frameworks */, + 611EFA95BB13886C84B3692AF65E66F8 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -102,56 +102,27 @@ 0A0ADE663140E20C1071E72A619CA4E1 /* Products */ = { isa = PBXGroup; children = ( - 68DDF334F75630BAA85571DF47D87C89 /* FlagsmithClient.framework */, - C1817E8624F31BD483479898AD8A9F9C /* Pods_FlagsmithClient_Example.framework */, + 68DDF334F75630BAA85571DF47D87C89 /* FlagsmithClient */, + C1817E8624F31BD483479898AD8A9F9C /* Pods-FlagsmithClient_Example */, ); name = Products; sourceTree = ""; }; - 126C2805424EF94E7A836D869A03013D /* Support Files */ = { + 27EC56B1B7D07F4EDD85D29A44A2225F /* Support Files */ = { isa = PBXGroup; children = ( - AD64CA35A3E22216D1D0738A812F312E /* FlagsmithClient.modulemap */, - C7A4CB83310920D7A2F76B1F4F715BA5 /* FlagsmithClient-dummy.m */, - AD917AEBF5902707C06AF63A186D1E24 /* FlagsmithClient-Info.plist */, - 69E74567D7DE2313D6054FA08CFC5940 /* FlagsmithClient-prefix.pch */, - 2EF53626DB8E67CE608BFEEB08DF2A5C /* FlagsmithClient-umbrella.h */, - 0CDC17B06AEC182F2B61F2F73541EFAF /* FlagsmithClient.debug.xcconfig */, - 23348535C2523FAC4E5FD55FF5CA18AA /* FlagsmithClient.release.xcconfig */, + B4164394D814A1BA2FA6A7C7662493C5 /* FlagsmithClient.modulemap */, + 6B880F3CB2ABE4DB1E22B3CC5541C2D8 /* FlagsmithClient-dummy.m */, + 0FAC90C1E63439160B035434A1CF25F1 /* FlagsmithClient-Info.plist */, + 8078BAE70CEB3897642FFDD030790F4B /* FlagsmithClient-prefix.pch */, + 7ECFF7C4FBE6AA88F7F7ECDCE6B66EA2 /* FlagsmithClient-umbrella.h */, + 8236C25B17E89C77288367CCF5B829A9 /* FlagsmithClient.debug.xcconfig */, + B27C6884FC1F031C5CCE03E04DA59B40 /* FlagsmithClient.release.xcconfig */, ); name = "Support Files"; path = "Example/Pods/Target Support Files/FlagsmithClient"; sourceTree = ""; }; - 1A94E973B95A4D1E5D88FED450500C7B /* FlagsmithClient */ = { - isa = PBXGroup; - children = ( - DA2D2B172A1BBFF200CD98D9 /* Traits.swift */, - A8A7BD53895AF16384B78CB7116DEBD7 /* Feature.swift */, - 2DDEFBF90EE0DCCBEE1F3D989919BC4A /* Flag.swift */, - 757CB2DED75CA13C202204D5B88B7B9A /* Flagsmith.swift */, - E119200827E4E5CE00820B87 /* FlagsmithError.swift */, - 287971AEF04B8BFE50BA6B4E9CB5A76E /* Flagsmith+Concurrency.swift */, - 9B3C161B19E351C1591E2039D787AD7C /* Identity.swift */, - C1CEBBBF5F9F986FB033B56D22422A4A /* Trait.swift */, - E190202D27E24E7600C5EE2C /* TypedValue.swift */, - 772F9BEA66F23FD7DB187ACBEB72BA93 /* UnknownTypeValue.swift */, - E119200927E4E5CE00820B87 /* Internal */, - 6990B5B456D0DD19FB8DF9BFCBB4A363 /* Pod */, - 126C2805424EF94E7A836D869A03013D /* Support Files */, - ); - name = FlagsmithClient; - path = ../..; - sourceTree = ""; - }; - 3F078EFBAC56829EFCCB88CB8537A1C2 /* Development Pods */ = { - isa = PBXGroup; - children = ( - 1A94E973B95A4D1E5D88FED450500C7B /* FlagsmithClient */, - ); - name = "Development Pods"; - sourceTree = ""; - }; 578452D2E740E91742655AC8F1636D1F /* iOS */ = { isa = PBXGroup; children = ( @@ -160,16 +131,6 @@ name = iOS; sourceTree = ""; }; - 6990B5B456D0DD19FB8DF9BFCBB4A363 /* Pod */ = { - isa = PBXGroup; - children = ( - 7CB5FDC929BB21CB23FFC8143AF6322F /* FlagsmithClient.podspec */, - ED741D6F7C10EB042045149B0E9347C9 /* LICENSE */, - C55271DDAE55BE2BA1AFA657FA24971A /* README.md */, - ); - name = Pod; - sourceTree = ""; - }; 71FEAF6FD2C81B205EDD5BFFCC9A9E66 /* Pods-FlagsmithClient_Example */ = { isa = PBXGroup; children = ( @@ -187,6 +148,35 @@ path = "Target Support Files/Pods-FlagsmithClient_Example"; sourceTree = ""; }; + 743FF37545C268C8B74711C93A390E32 /* FlagsmithClient */ = { + isa = PBXGroup; + children = ( + 9B77E851969A4CF4C7F75194BFC80A5B /* Feature.swift */, + 2DC8A87D5B1A7F57E12361CE1D5E95B8 /* Flag.swift */, + 0CD71DED3359EE67BB9C921E2917DA7A /* Flagsmith.swift */, + 919D3C18E297943C015F838AEEAD057F /* Flagsmith+Concurrency.swift */, + CD829895C1256784784DBBFC3020A222 /* FlagsmithError.swift */, + ED101D3AAE62D955200E49181AC69EF4 /* Identity.swift */, + 4CB810BA1DD243ED447F96C1EC7AD63F /* Trait.swift */, + 5D7B03B15ACDBBDA718D00CF6E18D416 /* Traits.swift */, + 158A52A6379630867E2111515A492DDE /* TypedValue.swift */, + DC513B1FDC4FEFFA6AC514C6DA6E3329 /* UnknownTypeValue.swift */, + CE24075F0AA68AF97EBFE976DF0970CD /* Internal */, + E3A6070C6F3B520898B030B46D84A64C /* Pod */, + 27EC56B1B7D07F4EDD85D29A44A2225F /* Support Files */, + ); + name = FlagsmithClient; + path = ../..; + sourceTree = ""; + }; + 8771110EE67E622B18478ADE12D92BE5 /* Development Pods */ = { + isa = PBXGroup; + children = ( + 743FF37545C268C8B74711C93A390E32 /* FlagsmithClient */, + ); + name = "Development Pods"; + sourceTree = ""; + }; BA8A3B9AA623A3EC5D887B56C04C7D73 /* Targets Support Files */ = { isa = PBXGroup; children = ( @@ -195,11 +185,23 @@ name = "Targets Support Files"; sourceTree = ""; }; + CE24075F0AA68AF97EBFE976DF0970CD /* Internal */ = { + isa = PBXGroup; + children = ( + 7482B233360C108341B85DF6F4F296D2 /* APIManager.swift */, + 92D88FCDAEE505ABAF4F0C9E59BEBB6A /* CachedURLResponse.swift */, + 77743E9FB921729A0C34B2CBE7A1F4CD /* FlagsmithAnalytics.swift */, + 66035645C7F450B9A20A5AA2F1CC43B6 /* Router.swift */, + ); + name = Internal; + path = FlagsmithClient/Classes/Internal; + sourceTree = ""; + }; CF1408CF629C7361332E53B88F7BD30C = { isa = PBXGroup; children = ( 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */, - 3F078EFBAC56829EFCCB88CB8537A1C2 /* Development Pods */, + 8771110EE67E622B18478ADE12D92BE5 /* Development Pods */, D210D550F4EA176C3123ED886F8F87F5 /* Frameworks */, 0A0ADE663140E20C1071E72A619CA4E1 /* Products */, BA8A3B9AA623A3EC5D887B56C04C7D73 /* Targets Support Files */, @@ -214,16 +216,14 @@ name = Frameworks; sourceTree = ""; }; - E119200927E4E5CE00820B87 /* Internal */ = { + E3A6070C6F3B520898B030B46D84A64C /* Pod */ = { isa = PBXGroup; children = ( - DAB856112A4455B2000520DC /* CachedURLResponse.swift */, - E119200A27E4E5CE00820B87 /* FlagsmithAnalytics.swift */, - E119200B27E4E5CE00820B87 /* APIManager.swift */, - E119200C27E4E5CE00820B87 /* Router.swift */, + 591BEAEF977192FC1893BEAC10ABB7F0 /* FlagsmithClient.podspec */, + 47EFBF8F57718DBF9FE586CBDB6CC0DC /* LICENSE */, + 6DEAF76385A937740682012C42A3F628 /* README.md */, ); - name = Internal; - path = FlagsmithClient/Classes/Internal; + name = Pod; sourceTree = ""; }; /* End PBXGroup section */ @@ -237,11 +237,11 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 880AF27981BF6F2975CFD64FC4ED14BC /* Headers */ = { + 98DBC9670D86FAE13772BFFB393D0029 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 83D44370DA79D1E1C2C20ABD98D13475 /* FlagsmithClient-umbrella.h in Headers */, + 7296A208906AA3BC74014294652982CA /* FlagsmithClient-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -250,12 +250,12 @@ /* Begin PBXNativeTarget section */ 11AAFF8883A32F4C9C2E17C1B1AE0614 /* FlagsmithClient */ = { isa = PBXNativeTarget; - buildConfigurationList = 827E42775BC9FA974028F9CBE8961ED2 /* Build configuration list for PBXNativeTarget "FlagsmithClient" */; + buildConfigurationList = CE8A22033473608C91867F497BC5A2CD /* Build configuration list for PBXNativeTarget "FlagsmithClient" */; buildPhases = ( - 880AF27981BF6F2975CFD64FC4ED14BC /* Headers */, - 35A843B908DA8DD05C19E97F5C0C77CC /* Sources */, - BB9BF91511BEE5C82B809BC460B4F6FE /* Frameworks */, - DB88F596983E8BFE16E0C06815FCE4E5 /* Resources */, + 98DBC9670D86FAE13772BFFB393D0029 /* Headers */, + 29A741F17A46BDD22AB2213A04FDE505 /* Sources */, + 5978E19B2CF28713F5F5FAE1384AF5B4 /* Frameworks */, + D0516BC3E528E09D1C43539B158EED35 /* Resources */, ); buildRules = ( ); @@ -263,7 +263,7 @@ ); name = FlagsmithClient; productName = FlagsmithClient; - productReference = 68DDF334F75630BAA85571DF47D87C89 /* FlagsmithClient.framework */; + productReference = 68DDF334F75630BAA85571DF47D87C89 /* FlagsmithClient */; productType = "com.apple.product-type.framework"; }; 770799B5DCFAB0B1BCF1BD365E2C1BC5 /* Pods-FlagsmithClient_Example */ = { @@ -278,11 +278,11 @@ buildRules = ( ); dependencies = ( - 81D0A6A16597797FFFE1A19BABD83D87 /* PBXTargetDependency */, + 6A2A4CDB21FA43CDB219D90367EBBD10 /* PBXTargetDependency */, ); name = "Pods-FlagsmithClient_Example"; productName = Pods_FlagsmithClient_Example; - productReference = C1817E8624F31BD483479898AD8A9F9C /* Pods_FlagsmithClient_Example.framework */; + productReference = C1817E8624F31BD483479898AD8A9F9C /* Pods-FlagsmithClient_Example */; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -291,13 +291,8 @@ BFDFE7DC352907FC980B868725387E98 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1240; - LastUpgradeCheck = 1320; - TargetAttributes = { - 11AAFF8883A32F4C9C2E17C1B1AE0614 = { - LastSwiftMigration = 1320; - }; - }; + LastSwiftUpdateCheck = 1500; + LastUpgradeCheck = 1500; }; buildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -326,7 +321,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DB88F596983E8BFE16E0C06815FCE4E5 /* Resources */ = { + D0516BC3E528E09D1C43539B158EED35 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( @@ -336,25 +331,25 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 35A843B908DA8DD05C19E97F5C0C77CC /* Sources */ = { + 29A741F17A46BDD22AB2213A04FDE505 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0A2426C7E3721ED5AEADF4CC344F6642 /* Feature.swift in Sources */, - 4A510C0AE712CD782D25F2276904F827 /* Flag.swift in Sources */, - E190202E27E24E7600C5EE2C /* TypedValue.swift in Sources */, - 1845D603B597C651F0EE6080EF459DBB /* Flagsmith.swift in Sources */, - DAB856122A4455B2000520DC /* CachedURLResponse.swift in Sources */, - DA2D2B182A1BBFF200CD98D9 /* Traits.swift in Sources */, - 2C55F74AE43F34E4F3952F5B86AADBF5 /* Flagsmith+Concurrency.swift in Sources */, - E119200F27E4E5CE00820B87 /* APIManager.swift in Sources */, - E119201027E4E5CE00820B87 /* Router.swift in Sources */, - B7C44FEAEB3099494B79EA35B9F71DE0 /* FlagsmithClient-dummy.m in Sources */, - E119200E27E4E5CE00820B87 /* FlagsmithAnalytics.swift in Sources */, - E119200D27E4E5CE00820B87 /* FlagsmithError.swift in Sources */, - 3E267A21653D98B77234CDD42A3A1D59 /* Identity.swift in Sources */, - 36B29445E454DBDF1CD394B9155A9170 /* Trait.swift in Sources */, - EE4568DD2E22CD3A570CAB24968F9BE7 /* UnknownTypeValue.swift in Sources */, + 361AD17B75FDA9970FF500DEE9B88729 /* APIManager.swift in Sources */, + 6EABC9E673A27FAC4180F2F08C4F2B3D /* CachedURLResponse.swift in Sources */, + CFFE0F58344636A5789C357F2BE50820 /* Feature.swift in Sources */, + F0F13B1D5F547C03C257DF46C49594E4 /* Flag.swift in Sources */, + 28E2C1F327F2FEFC3D6193D0E775DD16 /* Flagsmith.swift in Sources */, + 82EA3819E558968027E9A21E8E20A4A7 /* Flagsmith+Concurrency.swift in Sources */, + 011196679F1DBAD78B3284BB60F1CC7E /* FlagsmithAnalytics.swift in Sources */, + B9ECC98F1865D64AA4B986208D0938C1 /* FlagsmithClient-dummy.m in Sources */, + CFC4FDB2F9D6E43C28FE902C6131C027 /* FlagsmithError.swift in Sources */, + A3EAECF66E99CCF1D3251DB251AE6F9D /* Identity.swift in Sources */, + 95A960387ADF0D89DD60C4E6F563455F /* Router.swift in Sources */, + 97DE10D6905CEF731DD15EB738B843DD /* Trait.swift in Sources */, + 90AE5624A1F9C4DAA5ED6ED01FB6AA98 /* Traits.swift in Sources */, + A9DAAC7965A5F9D409F7335FC223BEE6 /* TypedValue.swift in Sources */, + 78FC3BC1E0FADEB53A278A0A4C6DA6E8 /* UnknownTypeValue.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -369,19 +364,21 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 81D0A6A16597797FFFE1A19BABD83D87 /* PBXTargetDependency */ = { + 6A2A4CDB21FA43CDB219D90367EBBD10 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FlagsmithClient; target = 11AAFF8883A32F4C9C2E17C1B1AE0614 /* FlagsmithClient */; - targetProxy = 0842EB6A5D76A0A91DC6E3D255DAF973 /* PBXContainerItemProxy */; + targetProxy = A39FC97A60B4E4EF1C00CDE9EDF2C25D /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 2D9A58AB8E62AA54BDD1A368DC580BDF /* Release */ = { + 0B1CDA5D382F4F3C96E9AE205B213EE1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 23348535C2523FAC4E5FD55FF5CA18AA /* FlagsmithClient.release.xcconfig */; + baseConfigurationReference = 8236C25B17E89C77288367CCF5B829A9 /* FlagsmithClient.debug.xcconfig */; buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -401,7 +398,39 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; + SWIFT_VERSION = 4.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 12BB8FAF3E0B6864216E35B141237E9A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B27C6884FC1F031C5CCE03E04DA59B40 /* FlagsmithClient.release.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_WEAK = NO; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FlagsmithClient/FlagsmithClient-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FlagsmithClient/FlagsmithClient-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/FlagsmithClient/FlagsmithClient.modulemap"; + PRODUCT_MODULE_NAME = FlagsmithClient; + PRODUCT_NAME = FlagsmithClient; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -409,7 +438,7 @@ }; name = Release; }; - 431BA2B8298F0EE71735B9E0114E1955 /* Release */ = { + 2B9E26EAE2CD392AD762421F663075A1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -444,13 +473,16 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; + DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_RELEASE=1", + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -460,17 +492,19 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = NO; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; - name = Release; + name = Debug; }; - 79759604D78320E712558F49DF19AA9F /* Debug */ = { + 63FAF33E1C55B71A5F5A8B3CC8749F99 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -505,16 +539,13 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_DEBUG=1", - "DEBUG=1", + "POD_CONFIGURATION_RELEASE=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -524,23 +555,24 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 12.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; STRIP_INSTALLED_PRODUCT = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; SYMROOT = "${SRCROOT}/../build"; }; - name = Debug; + name = Release; }; - 9663D66A429CFA12F6C1580F09274F5E /* Release */ = { + BC7D7AE6AEB2B1C6FA9194A3AB5A0B41 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 250DE57229233B0BAD273A076F108A0E /* Pods-FlagsmithClient_Example.release.xcconfig */; + baseConfigurationReference = 3B040CFA25391975C1615BFB481B68C9 /* Pods-FlagsmithClient_Example.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -563,47 +595,18 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - B0C049799EAA3AD326EABB059C0F2DFC /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 0CDC17B06AEC182F2B61F2F73541EFAF /* FlagsmithClient.debug.xcconfig */; - buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/FlagsmithClient/FlagsmithClient-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/FlagsmithClient/FlagsmithClient-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/FlagsmithClient/FlagsmithClient.modulemap"; - PRODUCT_MODULE_NAME = FlagsmithClient; - PRODUCT_NAME = FlagsmithClient; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - F2620923C4C4A930E68AB6816AFC6CF8 /* Debug */ = { + D22AD683643CD18DDDA1624DDA6590F4 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 3B040CFA25391975C1615BFB481B68C9 /* Pods-FlagsmithClient_Example.debug.xcconfig */; + baseConfigurationReference = 250DE57229233B0BAD273A076F108A0E /* Pods-FlagsmithClient_Example.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -626,10 +629,11 @@ SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; + name = Release; }; /* End XCBuildConfiguration section */ @@ -637,8 +641,8 @@ 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - 79759604D78320E712558F49DF19AA9F /* Debug */, - 431BA2B8298F0EE71735B9E0114E1955 /* Release */, + 2B9E26EAE2CD392AD762421F663075A1 /* Debug */, + 63FAF33E1C55B71A5F5A8B3CC8749F99 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -646,17 +650,17 @@ 4C7C80EB087B80A197C9D65FE3ECC5B0 /* Build configuration list for PBXNativeTarget "Pods-FlagsmithClient_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( - F2620923C4C4A930E68AB6816AFC6CF8 /* Debug */, - 9663D66A429CFA12F6C1580F09274F5E /* Release */, + BC7D7AE6AEB2B1C6FA9194A3AB5A0B41 /* Debug */, + D22AD683643CD18DDDA1624DDA6590F4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 827E42775BC9FA974028F9CBE8961ED2 /* Build configuration list for PBXNativeTarget "FlagsmithClient" */ = { + CE8A22033473608C91867F497BC5A2CD /* Build configuration list for PBXNativeTarget "FlagsmithClient" */ = { isa = XCConfigurationList; buildConfigurations = ( - B0C049799EAA3AD326EABB059C0F2DFC /* Debug */, - 2D9A58AB8E62AA54BDD1A368DC580BDF /* Release */, + 0B1CDA5D382F4F3C96E9AE205B213EE1 /* Debug */, + 12BB8FAF3E0B6864216E35B141237E9A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient-Info.plist b/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient-Info.plist index 7ea8235..4e1b060 100644 --- a/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient-Info.plist +++ b/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.1.2 + 3.4.0 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.debug.xcconfig b/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.debug.xcconfig index 201d332..1cf8144 100644 --- a/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.debug.xcconfig +++ b/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.debug.xcconfig @@ -1,10 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FlagsmithClient GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.release.xcconfig b/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.release.xcconfig index 201d332..1cf8144 100644 --- a/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.release.xcconfig +++ b/Example/Pods/Target Support Files/FlagsmithClient/FlagsmithClient.release.xcconfig @@ -1,10 +1,11 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FlagsmithClient GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_DEVELOPMENT_LANGUAGE = ${DEVELOPMENT_LANGUAGE} PODS_ROOT = ${SRCROOT} PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates diff --git a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-Info.plist b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-Info.plist index 2243fe6..19cf209 100644 --- a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-Info.plist +++ b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + ${PODS_DEVELOPMENT_LANGUAGE} CFBundleExecutable ${EXECUTABLE_NAME} CFBundleIdentifier diff --git a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-frameworks.sh b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-frameworks.sh index b1b4aa2..64b14a5 100755 --- a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-frameworks.sh +++ b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example-frameworks.sh @@ -18,7 +18,7 @@ echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" -SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +SWIFT_STDLIB_PATH="${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" BCSYMBOLMAP_DIR="BCSymbolMaps" @@ -41,7 +41,7 @@ install_framework() if [ -L "${source}" ]; then echo "Symlinked..." - source="$(readlink "${source}")" + source="$(readlink -f "${source}")" fi if [ -d "${source}/${BCSYMBOLMAP_DIR}" ]; then diff --git a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.debug.xcconfig b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.debug.xcconfig index f56d4e6..38be8b5 100644 --- a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.debug.xcconfig +++ b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.debug.xcconfig @@ -4,7 +4,7 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Flagsmith GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FlagsmithClient/FlagsmithClient.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "FlagsmithClient" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} diff --git a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.release.xcconfig b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.release.xcconfig index f56d4e6..38be8b5 100644 --- a/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.release.xcconfig +++ b/Example/Pods/Target Support Files/Pods-FlagsmithClient_Example/Pods-FlagsmithClient_Example.release.xcconfig @@ -4,7 +4,7 @@ FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Flagsmith GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FlagsmithClient/FlagsmithClient.framework/Headers" LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' -LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift +LIBRARY_SEARCH_PATHS = $(inherited) "${TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift OTHER_LDFLAGS = $(inherited) -framework "FlagsmithClient" OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS PODS_BUILD_DIR = ${BUILD_DIR} diff --git a/FlagsmithClient/Classes/Internal/APIManager.swift b/FlagsmithClient/Classes/Internal/APIManager.swift index 2d3626a..b13b898 100644 --- a/FlagsmithClient/Classes/Internal/APIManager.swift +++ b/FlagsmithClient/Classes/Internal/APIManager.swift @@ -21,8 +21,9 @@ class APIManager : NSObject, URLSessionDataDelegate { var apiKey: String? // store the completion handlers and accumulated data for each task - private var tasksToCompletionHandlers:[URLSessionDataTask:(Result) -> Void] = [:] - private var tasksToData:[URLSessionDataTask:NSMutableData] = [:] + private var tasksToCompletionHandlers:[Int:(Result) -> Void] = [:] + private var tasksToData:[Int:Data] = [:] + private let serialAccessQueue = DispatchQueue(label: "flagsmithSerialAccessQueue") override init() { super.init() @@ -31,36 +32,42 @@ class APIManager : NSObject, URLSessionDataDelegate { } func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { - if let dataTask = task as? URLSessionDataTask { - if let completion = tasksToCompletionHandlers[dataTask] { - if let error = error { - completion(.failure(FlagsmithError.unhandled(error))) - } - else { - let data = tasksToData[dataTask] ?? NSMutableData() - completion(.success(data as Data)) + serialAccessQueue.sync { + if let dataTask = task as? URLSessionDataTask { + if let completion = tasksToCompletionHandlers[dataTask.taskIdentifier] { + if let error = error { + DispatchQueue.main.async { completion(.failure(FlagsmithError.unhandled(error))) } + } + else { + let data = tasksToData[dataTask.taskIdentifier] ?? Data() + DispatchQueue.main.async { completion(.success(data)) } + } } + tasksToCompletionHandlers[dataTask.taskIdentifier] = nil + tasksToData[dataTask.taskIdentifier] = nil } - tasksToCompletionHandlers[dataTask] = nil - tasksToData[dataTask] = nil } } - func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, completionHandler: @escaping (CachedURLResponse?) -> Void) { - - // intercept and modify the cache settings for the response - if Flagsmith.shared.cacheConfig.useCache { - let newResponse = proposedResponse.response(withExpirationDuration: Int(Flagsmith.shared.cacheConfig.cacheTTL)) - completionHandler(newResponse) - } else { - completionHandler(proposedResponse) + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, willCacheResponse proposedResponse: CachedURLResponse, + completionHandler: @escaping (CachedURLResponse?) -> Void) { + serialAccessQueue.sync { + // intercept and modify the cache settings for the response + if Flagsmith.shared.cacheConfig.useCache { + let newResponse = proposedResponse.response(withExpirationDuration: Int(Flagsmith.shared.cacheConfig.cacheTTL)) + DispatchQueue.main.async { completionHandler(newResponse) } + } else { + DispatchQueue.main.async { completionHandler(proposedResponse) } + } } } func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { - let existingData = tasksToData[dataTask] ?? NSMutableData() - existingData.append(data) - tasksToData[dataTask] = existingData + serialAccessQueue.sync { + var existingData = tasksToData[dataTask.taskIdentifier] ?? Data() + existingData.append(data) + tasksToData[dataTask.taskIdentifier] = existingData + } } func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { @@ -98,9 +105,11 @@ class APIManager : NSObject, URLSessionDataDelegate { } // we must use the delegate form here, not the completion handler, to be able to modify the cache - let task = session.dataTask(with: request) - tasksToCompletionHandlers[task] = completion - task.resume() + serialAccessQueue.sync { + let task = session.dataTask(with: request) + tasksToCompletionHandlers[task.taskIdentifier] = completion + task.resume() + } } /// Requests a api route and only relays success or failure of the action. diff --git a/FlagsmithClient/Classes/Internal/Router.swift b/FlagsmithClient/Classes/Internal/Router.swift index 3124ee4..639be56 100644 --- a/FlagsmithClient/Classes/Internal/Router.swift +++ b/FlagsmithClient/Classes/Internal/Router.swift @@ -10,7 +10,7 @@ import Foundation import FoundationNetworking #endif -enum Router { +enum Router: Sendable { private enum HTTPMethod: String { case get = "GET" case post = "POST" diff --git a/FlagsmithClient/Tests/APIManagerTests.swift b/FlagsmithClient/Tests/APIManagerTests.swift index 26c3198..43b76be 100644 --- a/FlagsmithClient/Tests/APIManagerTests.swift +++ b/FlagsmithClient/Tests/APIManagerTests.swift @@ -60,4 +60,32 @@ final class APIManagerTests: FlagsmithClientTestCase { return } } + + func testConcurrentRequests() throws { + apiManager.apiKey = "8D5ABC87-6BBF-4AE7-BC05-4DC1AFE770DF" + let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent) + + var expectations:[XCTestExpectation] = []; + let iterations = 1000 + var error: FlagsmithError? + + for concurrentIteration in 1...iterations { + let expectation = XCTestExpectation(description: "Multiple threads can access the APIManager \(concurrentIteration)") + expectations.append(expectation) + concurrentQueue.async { + self.apiManager.request(.getFlags) { (result: Result) in + if case let .failure(e) = result { + error = e as? FlagsmithError + } + expectation.fulfill() + } + } + } + + wait(for: expectations, timeout: 5) + // Ensure that we didn't have any errors during the process + XCTAssertTrue(error == nil) + + print("Finished!") + } }