Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6628d30
Add xcode compatibility information to readme (#93)
bwoskow-ld Apr 24, 2020
f2fc6e8
Merge branch 'v4' of https://github.com/launchdarkly/ios-client-sdk
torchhound May 27, 2020
e3fe153
Merge branch 'v4' of https://github.com/launchdarkly/ios-client-sdk
torchhound Jun 4, 2020
0391739
Merge branch 'v5'
gwhelanLD Jul 23, 2020
9e0a614
Merge branch 'v5'
gwhelanLD Jul 23, 2020
c7f03af
Merge branch 'v5'
gwhelanLD Aug 4, 2020
d02a80d
Merge branch 'v5' of github.com:launchdarkly/ios-client-sdk
gwhelanLD Oct 9, 2020
bf3f8ac
Merge branch 'v5'
gwhelanLD Nov 6, 2020
988bcfc
Merge branch 'v5'
gwhelanLD Dec 17, 2020
7deb14a
Removed the guides link
bwoskow-ld Feb 3, 2021
35cbb28
Merge branch 'v5'
gwhelanLD Feb 11, 2021
f9c62c0
Merge branch 'v5'
gwhelanLD Feb 26, 2021
6cd5eec
Merge branch 'v5' of https://github.com/launchdarkly/ios-client-sdk i…
torchhound Apr 7, 2021
503cb8e
[ch110317] Replace `class` with equivalent `AnyObject` as the prior i…
gwhelanLD Jun 11, 2021
f544bff
Merge remote-tracking branch 'public/v5'
gwhelanLD Jun 11, 2021
2d9acce
Update dependencies. (#155)
gwhelanLD Jun 17, 2021
2dd2aa5
Merge branch 'v5'
gwhelanLD Jun 17, 2021
bb22146
Restore compatibility with Swift 5.2 (#156)
gwhelanLD Jun 17, 2021
54aef07
Merge branch 'v5'
gwhelanLD Jun 18, 2021
5de6afc
Merge branch 'v5'
gwhelanLD Jun 18, 2021
b9d04c6
Update Sourcery and SwiftLint. (#157)
gwhelanLD Jun 22, 2021
8ea40ad
[ch115624] Fixes for polling mode (#158)
gwhelanLD Aug 9, 2021
f4a74cc
Merge branch 'v5'
gwhelanLD Aug 13, 2021
5c04f08
[ch115552] Filter deep nulls in flag data. (#159)
gwhelanLD Aug 13, 2021
2c8db33
Merge branch 'v5'
gwhelanLD Aug 13, 2021
a2bf12b
Add CI job for Xcode 13. (#160)
gwhelanLD Oct 1, 2021
d2e99bd
Remove Cartfile that specifies redundant framework dependency on LDSw…
gwhelanLD Nov 19, 2021
be3ff00
Fix CircleCI and improve build time of documentation step (#163)
gwhelanLD Dec 8, 2021
bfe48df
Permit additional fields on delete dictionary. (#164)
gwhelanLD Dec 28, 2021
22f1aff
Cleanup error notifier (#165)
gwhelanLD Dec 28, 2021
000ca61
Improvements to LDTimer and Throttler cleanup. (#170)
gwhelanLD Jan 12, 2022
b732e7a
Update LDSwiftEventSource version and test dependencies. (#172)
gwhelanLD Jan 19, 2022
cbe3897
Release iOS swift client SDK 5.4.4
louis-launchdarkly Jan 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 30 additions & 16 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
type: string
ssh-fix:
type: boolean
default: true
default: false
build-doc:
type: boolean
default: false
Expand All @@ -24,19 +24,15 @@ jobs:
steps:
- checkout

# This hack shouldn't be necessary, as we don't actually use SSH
# to get any dependencies, but for some reason starting in the
# '12.0.0' Xcode image it's become necessary.
# There's an XCode bug present in the 12.0.1 CircleCI image that prevents fetching SSH
# dependencies from working in some cases, so we disable CircleCI's rewriting of the HTTPS
# GitHub URLs to SSH.
- when:
condition: <<parameters.ssh-fix>>
steps:
- run:
name: SSH fingerprint fix
command: |
sudo defaults write com.apple.dt.Xcode IDEPackageSupportUseBuiltinSCM YES
rm ~/.ssh/id_rsa || true
for ip in $(dig @8.8.8.8 bitbucket.org +short); do ssh-keyscan bitbucket.org,$ip; ssh-keyscan $ip; done 2>/dev/null >> ~/.ssh/known_hosts || true
for ip in $(dig @8.8.8.8 github.com +short); do ssh-keyscan github.com,$ip; ssh-keyscan $ip; done 2>/dev/null >> ~/.ssh/known_hosts || true
name: SSH fix
command: git config --global --unset url.ssh://git@github.com.insteadof

- run:
name: Setup for builds
Expand Down Expand Up @@ -87,11 +83,25 @@ jobs:
- when:
condition: <<parameters.build-doc>>
steps:
- restore_cache:
key: v1-gem-cache-<<parameters.xcode-version>>-

- run:
name: Build Documentation
name: Install jazzy gem
command: |
sudo gem install jazzy
jazzy -o artifacts/docs
gem install jazzy
gem cleanup
# Used as cache key to prevent storing redundant caches
gem list > /tmp/cache-key.txt

- save_cache:
key: v1-gem-cache-<<parameters.xcode-version>>-{{ checksum "/tmp/cache-key.txt" }}
paths:
- ~/.gem

- run:
name: Build Documentation
command: jazzy -o artifacts/docs

- when:
condition: <<parameters.run-lint>>
Expand All @@ -116,18 +126,22 @@ workflows:

build:
jobs:
- build:
name: Xcode 13.1 - Swift 5.5
xcode-version: '13.1.0'
ios-sim: 'platform=iOS Simulator,name=iPhone 11,OS=15.0'
build-doc: true
run-lint: true
- build:
name: Xcode 12.5 - Swift 5.4
xcode-version: '12.5.0'
ios-sim: 'platform=iOS Simulator,name=iPhone 8,OS=14.5'
build-doc: true
run-lint: true
- build:
name: Xcode 12.0 - Swift 5.3
xcode-version: '12.0.1'
ios-sim: 'platform=iOS Simulator,name=iPhone 8,OS=14.0'
ssh-fix: true
- build:
name: Xcode 11.4 - Swift 5.2
xcode-version: '11.4.1'
ios-sim: 'platform=iOS Simulator,name=iPhone 8,OS=12.2'
ssh-fix: false
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to the LaunchDarkly iOS SDK will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org).

## [5.4.4] - 2022-01-19
### Fixed
- Fixed memory leak when stream connections are terminated by updating `LDSwiftEventSource` dependency to [1.3.0](https://github.com/launchdarkly/swift-eventsource/releases/tag/1.3.0).
- The SDK would not allow additional fields on `delete` flag stream events. This has been updated to allow additional fields for improved future compatibility.
- Improved internal `Throttler` implementation to reduce concurrency concerns.
- Removed unneeded `Cartfile` definining `LDSwiftEventSource` dependency, which when bundled could lead to warning messages that `LDSwiftEventSource` definitions are implemented in multiple frameworks.

## [5.4.3] - 2021-08-13
### Fixed
- Fixed an issue where `304 NOT_MODIFIED` responses to SDK polling mode requests would be considered error responses. This could cause the completion on a `identify` request to not complete, and gave erroneous connection information data and logging output.
Expand Down
1 change: 0 additions & 1 deletion Cartfile

This file was deleted.

4 changes: 2 additions & 2 deletions LaunchDarkly.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Pod::Spec.new do |ld|

ld.name = "LaunchDarkly"
ld.version = "5.4.3"
ld.version = "5.4.4"
ld.summary = "iOS SDK for LaunchDarkly"

ld.description = <<-DESC
Expand Down Expand Up @@ -35,6 +35,6 @@ Pod::Spec.new do |ld|
ld.swift_version = '5.0'

ld.subspec 'Core' do |es|
es.dependency 'LDSwiftEventSource', '1.2.1'
es.dependency 'LDSwiftEventSource', '1.3.0'
end
end
26 changes: 13 additions & 13 deletions LaunchDarkly.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
MODULEMAP_FILE = "";
PRODUCT_BUNDLE_IDENTIFIER = "com.launchdarkly.Darkly-tvOS";
PRODUCT_NAME = LaunchDarkly_tvOS;
Expand All @@ -1606,7 +1606,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
MODULEMAP_FILE = "";
PRODUCT_BUNDLE_IDENTIFIER = "com.launchdarkly.Darkly-tvOS";
PRODUCT_NAME = LaunchDarkly_tvOS;
Expand All @@ -1629,7 +1629,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
PRODUCT_BUNDLE_IDENTIFIER = "com.launchdarkly.Darkly-macOS";
PRODUCT_NAME = LaunchDarkly_macOS;
SDKROOT = macosx;
Expand All @@ -1650,7 +1650,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
PRODUCT_BUNDLE_IDENTIFIER = "com.launchdarkly.Darkly-macOS";
PRODUCT_NAME = LaunchDarkly_macOS;
SDKROOT = macosx;
Expand Down Expand Up @@ -1694,7 +1694,7 @@
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DYLIB_COMPATIBILITY_VERSION = 5.4.0;
DYLIB_CURRENT_VERSION = 5.4.3;
DYLIB_CURRENT_VERSION = 5.4.4;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
FRAMEWORK_VERSION = B;
Expand Down Expand Up @@ -1765,7 +1765,7 @@
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 5.4.0;
DYLIB_CURRENT_VERSION = 5.4.3;
DYLIB_CURRENT_VERSION = 5.4.4;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
FRAMEWORK_VERSION = B;
Expand Down Expand Up @@ -1804,7 +1804,7 @@
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
MODULEMAP_FILE = "$(PROJECT_DIR)/Framework/module.modulemap";
PRODUCT_BUNDLE_IDENTIFIER = com.launchdarkly.Darkly;
PRODUCT_NAME = LaunchDarkly;
Expand All @@ -1824,7 +1824,7 @@
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
MODULEMAP_FILE = "$(PROJECT_DIR)/Framework/module.modulemap";
PRODUCT_BUNDLE_IDENTIFIER = com.launchdarkly.Darkly;
PRODUCT_NAME = LaunchDarkly;
Expand Down Expand Up @@ -1866,7 +1866,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
PRODUCT_BUNDLE_IDENTIFIER = "com.launchdarkly.Darkly-watchOS";
PRODUCT_NAME = LaunchDarkly_watchOS;
SDKROOT = watchos;
Expand All @@ -1888,7 +1888,7 @@
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = "$(PROJECT_DIR)/LaunchDarkly/LaunchDarkly/Support/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
MARKETING_VERSION = 5.4.3;
MARKETING_VERSION = 5.4.4;
PRODUCT_BUNDLE_IDENTIFIER = "com.launchdarkly.Darkly-watchOS";
PRODUCT_NAME = LaunchDarkly_watchOS;
SDKROOT = watchos;
Expand Down Expand Up @@ -1962,7 +1962,7 @@
repositoryURL = "https://github.com/LaunchDarkly/swift-eventsource.git";
requirement = {
kind = exactVersion;
version = 1.2.1;
version = 1.3.0;
};
};
B4903D9624BD61B200F087C4 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */ = {
Expand All @@ -1978,15 +1978,15 @@
repositoryURL = "https://github.com/Quick/Nimble.git";
requirement = {
kind = exactVersion;
version = 9.2.0;
version = 9.2.1;
};
};
B4903D9C24BD61EF00F087C4 /* XCRemoteSwiftPackageReference "Quick" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Quick/Quick.git";
requirement = {
kind = exactVersion;
version = 3.1.2;
version = 4.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
Expand Down
2 changes: 1 addition & 1 deletion LaunchDarkly/LaunchDarkly/Models/ErrorObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation

struct ErrorObserver {
weak var owner: LDObserverOwner?
var errorHandler: LDErrorHandler?
let errorHandler: LDErrorHandler

init(owner: LDObserverOwner, errorHandler: @escaping LDErrorHandler) {
self.owner = owner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class DiagnosticReporter: DiagnosticReporting {
sendDiagnosticEventAsync(diagnosticEvent: initEvent)
}

timer = LDTimer(withTimeInterval: service.config.diagnosticRecordingInterval, repeats: true, fireQueue: workQueue) {
timer = LDTimer(withTimeInterval: service.config.diagnosticRecordingInterval, fireQueue: workQueue) {
self.sendDiagnosticEventSync(diagnosticEvent: cache.getCurrentStatsAndReset())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ struct EnvironmentReporter: EnvironmentReporting {
var shouldThrottleOnlineCalls: Bool { true }
#endif

let sdkVersion = "5.4.3"
let sdkVersion = "5.4.4"
// Unfortunately, the following does not function in certain configurations, such as when included through SPM
// var sdkVersion: String {
// Bundle(for: LDClient.self).infoDictionary?["CFBundleShortVersionString"] as? String ?? "5.x"
Expand Down
16 changes: 2 additions & 14 deletions LaunchDarkly/LaunchDarkly/ServiceObjects/ErrorNotifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,15 @@ final class ErrorNotifier: ErrorNotifying {
}

func removeObservers(for owner: LDObserverOwner) {
errorObservers = errorObservers.filter { $0.owner !== owner }
errorObservers.removeAll { $0.owner === owner }
}

func notifyObservers(of error: Error) {
removeOldObservers()
errorObservers.forEach { $0.errorHandler?(error) }
errorObservers.forEach { $0.errorHandler(error) }
}

private func removeOldObservers() {
errorObservers = errorObservers.filter { $0.owner != nil }
}
}

#if DEBUG
extension ErrorNotifier {
func erase(owner: LDObserverOwner) {
for index in 0..<errorObservers.count {
guard errorObservers[index].owner === owner
else { continue }
errorObservers[index].owner = nil
}
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ class EventReporter: EventReporting {
private func startReporting(isOnline: Bool) {
guard isOnline && !isReportingActive
else { return }
eventReportTimer = LDTimer(withTimeInterval: service.config.eventFlushInterval, repeats: true, fireQueue: eventQueue, execute: reportEvents)
eventReportTimer = LDTimer(withTimeInterval: service.config.eventFlushInterval, fireQueue: eventQueue, execute: reportEvents)
}

private func stopReporting() {
Expand Down
3 changes: 1 addition & 2 deletions LaunchDarkly/LaunchDarkly/ServiceObjects/FlagStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,7 @@ final class FlagStore: FlagMaintaining {
}
}
}
guard deleteDictionary.keys.sorted() == [Keys.flagKey, FeatureFlag.CodingKeys.version.rawValue],
let flagKey = deleteDictionary[Keys.flagKey] as? String,
guard let flagKey = deleteDictionary[Keys.flagKey] as? String,
let newVersion = deleteDictionary[FeatureFlag.CodingKeys.version.rawValue] as? Int
else {
Log.debug(self.typeName(and: #function) + "aborted. Malformed delete dictionary. deleteDictionary: \(String(describing: deleteDictionary))")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class FlagSynchronizer: LDFlagSynchronizing, EventHandler {
return
}
Log.debug(typeName(and: #function))
flagRequestTimer = LDTimer(withTimeInterval: pollingInterval, repeats: true, fireQueue: syncQueue, execute: processTimer)
flagRequestTimer = LDTimer(withTimeInterval: pollingInterval, fireQueue: syncQueue, execute: processTimer)
makeFlagRequest(isOnline: isOnline)
}

Expand Down
22 changes: 3 additions & 19 deletions LaunchDarkly/LaunchDarkly/ServiceObjects/LDTimer.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
//
// LDTimer.swift
// LaunchDarkly
//
// Copyright © 2019 Catamorphic Co. All rights reserved.
//

import Foundation

protocol TimeResponding {
var isRepeating: Bool { get }
var fireDate: Date? { get }

init(withTimeInterval: TimeInterval, repeats: Bool, fireQueue: DispatchQueue, execute: @escaping () -> Void)
init(withTimeInterval: TimeInterval, fireQueue: DispatchQueue, execute: @escaping () -> Void)
func cancel()
}

Expand All @@ -20,17 +12,15 @@ final class LDTimer: TimeResponding {
private (set) weak var timer: Timer?
private let fireQueue: DispatchQueue
private let execute: () -> Void
private (set) var isRepeating: Bool
private (set) var isCancelled: Bool = false
var fireDate: Date? { timer?.fireDate }

init(withTimeInterval timeInterval: TimeInterval, repeats: Bool, fireQueue: DispatchQueue = DispatchQueue.main, execute: @escaping () -> Void) {
isRepeating = repeats
init(withTimeInterval timeInterval: TimeInterval, fireQueue: DispatchQueue = DispatchQueue.main, execute: @escaping () -> Void) {
self.fireQueue = fireQueue
self.execute = execute

// the run loop retains the timer, so the property is weak to avoid a retain cycle. Setting the timer to a strong reference is important so that the timer doesn't get nil'd before it's added to the run loop.
let timer = Timer(timeInterval: timeInterval, target: self, selector: #selector(timerFired), userInfo: nil, repeats: repeats)
let timer = Timer(timeInterval: timeInterval, target: self, selector: #selector(timerFired), userInfo: nil, repeats: true)
self.timer = timer
RunLoop.main.add(timer, forMode: RunLoop.Mode.default)
}
Expand All @@ -52,9 +42,3 @@ final class LDTimer: TimeResponding {
isCancelled = true
}
}

#if DEBUG
extension LDTimer {
var testFireQueue: DispatchQueue { fireQueue }
}
#endif
Loading