diff --git a/CHANGELOG.md b/CHANGELOG.md index b06e64be..7fe6cce4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to the LaunchDarkly iOS SDK will be documented in this file. ### Multiple Environment clients Version 4.0.0 does not support multiple environments. If you use version `2.14.0` or later and set `LDConfig`'s `secondaryMobileKeys` you will not be able to migrate to version `4.0.0`. Multiple Environments will be added in a future release to the Swift SDK. +## [4.1.0] - 2019-06-19 +### Change +- Installs new `deviceModel` into `EnvironmentReporter` and renames old `deviceModel` to `deviceType`. +- Updated MacOS model detection to use `CwSysCtl`. + +### Fixed +- Fixed a concurrency bug that caused crashes in FlagStore.swift. This bug could surface during rapid updates to local flags. + ## [4.0.0] - 2019-04-18 This is the non-beta first release of the Swift SDK. It follows the beta.3 release from 2019-03-07. Unlike previous Swift SDK releases, this release does not have a `3.0.0` companion tag. ### Changed diff --git a/LaunchDarkly.podspec b/LaunchDarkly.podspec index 6b1ee8a9..46bb1188 100644 --- a/LaunchDarkly.podspec +++ b/LaunchDarkly.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |ld| ld.name = "LaunchDarkly" - ld.version = "4.0.0" + ld.version = "4.1.0" ld.summary = "iOS SDK for LaunchDarkly" ld.description = <<-DESC @@ -25,7 +25,7 @@ Pod::Spec.new do |ld| ld.tvos.deployment_target = "9.0" ld.osx.deployment_target = "10.10" - ld.source = { :git => "https://github.com/launchdarkly/ios-client-sdk.git", :tag => '4.0.0'} + ld.source = { :git => "https://github.com/launchdarkly/ios-client-sdk.git", :tag => '4.1.0'} ld.source_files = "LaunchDarkly/LaunchDarkly/**/*.{h,m,swift}" diff --git a/LaunchDarkly.xcodeproj/project.pbxproj b/LaunchDarkly.xcodeproj/project.pbxproj index b67748c1..1d284a34 100644 --- a/LaunchDarkly.xcodeproj/project.pbxproj +++ b/LaunchDarkly.xcodeproj/project.pbxproj @@ -1056,12 +1056,12 @@ TargetAttributes = { 831188372113A16900D77CB5 = { CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1010; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; 831EF33A20655D700001C643 = { CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1010; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; 8354EFC11F22491C00C05156 = { @@ -1076,7 +1076,7 @@ }; 83D9EC6A2062DBB7004D7FA6 = { CreatedOnToolsVersion = 9.2; - LastSwiftMigration = 1010; + LastSwiftMigration = 1020; ProvisioningStyle = Automatic; }; }; @@ -1696,7 +1696,7 @@ PRODUCT_NAME = LaunchDarkly_tvOS; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1729,7 +1729,7 @@ PRODUCT_NAME = LaunchDarkly_tvOS; SDKROOT = appletvos; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1762,7 +1762,7 @@ PRODUCT_NAME = LaunchDarkly_macOS; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -1793,7 +1793,7 @@ PRODUCT_NAME = LaunchDarkly_macOS; SDKROOT = macosx; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; }; name = Release; }; @@ -2056,7 +2056,7 @@ PRODUCT_NAME = LaunchDarkly_watchOS; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; @@ -2093,7 +2093,7 @@ PRODUCT_NAME = LaunchDarkly_watchOS; SDKROOT = watchos; SKIP_INSTALL = YES; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 4; WATCHOS_DEPLOYMENT_TARGET = 2.0; }; diff --git a/LaunchDarkly/LaunchDarkly/Service Objects/EnvironmentReporter.swift b/LaunchDarkly/LaunchDarkly/Service Objects/EnvironmentReporter.swift index 1cc7b37d..b913f1d3 100644 --- a/LaunchDarkly/LaunchDarkly/Service Objects/EnvironmentReporter.swift +++ b/LaunchDarkly/LaunchDarkly/Service Objects/EnvironmentReporter.swift @@ -74,8 +74,31 @@ struct EnvironmentReporter: EnvironmentReporting { } #endif - #if os(iOS) + struct Constants { + fileprivate static let simulatorModelIdentifier = "SIMULATOR_MODEL_IDENTIFIER" + } + var deviceModel: String { + #if os(OSX) + return Sysctl.model + #else + //Obtaining the device model from https://stackoverflow.com/questions/26028918/how-to-determine-the-current-iphone-device-model answer by Jens Schwarzer + if let simulatorModelIdentifier = ProcessInfo().environment[Constants.simulatorModelIdentifier] { + return simulatorModelIdentifier + } + //the physical device code here is not automatically testable. Manual testing on physical devices is required. + var systemInfo = utsname() + _ = uname(&systemInfo) + guard let deviceModel = String(bytes: Data(bytes: &systemInfo.machine, count: Int(_SYS_NAMELEN)), encoding: .ascii) + else { + return deviceType + } + return deviceModel.trimmingCharacters(in: .controlCharacters) + #endif + } + + #if os(iOS) + var deviceType: String { return UIDevice.current.model } var systemVersion: String { @@ -97,7 +120,7 @@ struct EnvironmentReporter: EnvironmentReporting { return UIDevice.current.identifierForVendor?.uuidString } #elseif os(watchOS) - var deviceModel: String { + var deviceType: String { return WKInterfaceDevice.current().model } var systemVersion: String { @@ -119,7 +142,7 @@ struct EnvironmentReporter: EnvironmentReporting { return nil } #elseif os(OSX) - var deviceModel: String { + var deviceType: String { return Sysctl.modelWithoutVersion } var systemVersion: String { @@ -141,7 +164,7 @@ struct EnvironmentReporter: EnvironmentReporting { return nil } #elseif os(tvOS) - var deviceModel: String { + var deviceType: String { return UIDevice.current.model } var systemVersion: String { diff --git a/LaunchDarkly/LaunchDarkly/Service Objects/FlagStore.swift b/LaunchDarkly/LaunchDarkly/Service Objects/FlagStore.swift index 6a1eded4..b8517ce2 100644 --- a/LaunchDarkly/LaunchDarkly/Service Objects/FlagStore.swift +++ b/LaunchDarkly/LaunchDarkly/Service Objects/FlagStore.swift @@ -100,8 +100,12 @@ final class FlagStore: FlagMaintaining { } Log.debug(self.typeName(and: #function) + "succeeded. new flag: \(newFlag), " + "prior flag: \(String(describing: self.featureFlags[flagKey]))") - self.featureFlags[flagKey] = newFlag - + var localFeatureFlags: [LDFlagKey: FeatureFlag] = [:] + self.featureFlags.forEach { key, value in + localFeatureFlags[key] = value + } + localFeatureFlags[flagKey] = newFlag + self.featureFlags = localFeatureFlags } } @@ -136,7 +140,12 @@ final class FlagStore: FlagMaintaining { } Log.debug(self.typeName(and: #function) + "deleted flag with key: " + flagKey) - self.featureFlags.removeValue(forKey: flagKey) + var localFeatureFlags: [LDFlagKey: FeatureFlag] = [:] + self.featureFlags.forEach { key, value in + localFeatureFlags[key] = value + } + localFeatureFlags.removeValue(forKey: flagKey) + self.featureFlags = localFeatureFlags } } diff --git a/README.md b/README.md index 6a9504c7..fc533040 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ $ gem install cocoapods ```ruby use_frameworks! target 'YourTargetName' do - pod 'LaunchDarkly', '4.0.0' + pod 'LaunchDarkly', '4.1.0' end ``` @@ -70,7 +70,7 @@ $ brew install carthage To integrate LaunchDarkly into your Xcode project using Carthage, specify it in your `Cartfile`: ```ogdl -github "launchdarkly/ios-client-sdk" "4.0.0" +github "launchdarkly/ios-client-sdk" "4.1.0" ``` Run `carthage update` to build the framework. Optionally, specify the `--platform` to build only the frameworks that support your platform(s).