Skip to content

Commit

Permalink
Release 1.1.0 (#9)
Browse files Browse the repository at this point in the history
## [1.1.0] - 2020-07-20
### Added
- Support `arm64e` on `appletvos`, `iphoneos`, and `macosx` SDKs by extending valid architectures.
- Support for building LDSwiftEventSource on Linux. Currently this library will not generate log messages on Linux, and may not behave correctly on Linux due to Foundation being [incomplete](https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/Status.md).
  • Loading branch information
gwhelanLD authored Jul 20, 2020
1 parent ac1f0e0 commit 4f817e1
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 65 deletions.
59 changes: 58 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
version: 2.1
jobs:
# TODO (gwhelanld): Consider adding linux CI job for swiftpm linux build/test
build:
shell: /bin/bash --login -eo pipefail

Expand Down Expand Up @@ -63,3 +62,61 @@ jobs:

- store_artifacts:
path: artifacts

build_macos_universal:
macos:
xcode: '12.0.0-UA'

steps:
- checkout

- run:
name: Setup for builds
command: |
mkdir -p 'test-results'
mkdir -p 'artifacts'
- run:
name: Build for ARM64 macOS
command: xcodebuild build -scheme 'LDSwiftEventSource' -arch arm64e -sdk macosx | tee 'artifacts/raw-logs-macosx-arm64e.txt' | xcpretty
when: always

- run:
name: Build & Test on x86_64 macOS Simulator
command: xcodebuild test -scheme 'LDSwiftEventSource' -sdk macosx -destination 'platform=macOS' | tee 'artifacts/raw-logs-macosx-x86_64.txt' | xcpretty -r junit -o 'test-results/platform-macosx-x86_64/junit.xml'
when: always

- store_test_results:
path: test-results

- store_artifacts:
path: artifacts

build_linux:
shell: /bin/bash --login -eo pipefail

docker:
- image: norionomura/swift:latest

steps:
- checkout

- run:
name: Setup for builds
command: mkdir -p 'artifacts'

- run:
name: Build & Test with swiftpm
command: swift test -v | tee 'artifacts/raw-logs-swiftpm-linux.txt'

- store_artifacts:
path: artifacts

workflows:
version: 2

build:
jobs:
- build
- build_linux
- build_macos_universal
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

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

## [1.1.0] - 2020-07-20
### Added
- Support `arm64e` on `appletvos`, `iphoneos`, and `macosx` SDKs by extending valid architectures.
- Support for building LDSwiftEventSource on Linux. Currently this library will not generate log messages on Linux, and may not behave correctly on Linux due to Foundation being [incomplete](https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/Status.md).

## [1.0.0] - 2020-07-16
This is the first public release of the LDSwiftEventSource library. The following notes are what changed since the previous pre-release version.
### Changed
Expand Down
2 changes: 1 addition & 1 deletion LDSwiftEventSource.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "LDSwiftEventSource"
s.version = "1.0.0"
s.version = "1.1.0"
s.summary = "Swift EventSource library"
s.homepage = "https://github.com/launchdarkly/swift-eventsource"
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE.txt" }
Expand Down
18 changes: 10 additions & 8 deletions LDSwiftEventSource.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -330,11 +331,11 @@
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TVOS_DEPLOYMENT_TARGET = 10.0;
"VALID_ARCHS[sdk=appletvos*]" = arm64;
"VALID_ARCHS[sdk=appletvos*]" = "arm64 arm64e";
"VALID_ARCHS[sdk=appletvsimulator*]" = x86_64;
"VALID_ARCHS[sdk=iphoneos*]" = "arm64 armv7 armv7s";
"VALID_ARCHS[sdk=iphoneos*]" = "arm64 arm64e armv7 armv7s";
"VALID_ARCHS[sdk=iphonesimulator*]" = "i386 x86_64";
"VALID_ARCHS[sdk=macosx*]" = "x86_64 arm64";
"VALID_ARCHS[sdk=macosx*]" = "x86_64 arm64 arm64e";
"VALID_ARCHS[sdk=watchos*]" = "armv7k arm64_32";
"VALID_ARCHS[sdk=watchsimulator*]" = "x86_64 i386";
VERSIONING_SYSTEM = "apple-generic";
Expand Down Expand Up @@ -369,6 +370,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
Expand Down Expand Up @@ -403,11 +405,11 @@
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TVOS_DEPLOYMENT_TARGET = 10.0;
"VALID_ARCHS[sdk=appletvos*]" = arm64;
"VALID_ARCHS[sdk=appletvos*]" = "arm64 arm64e";
"VALID_ARCHS[sdk=appletvsimulator*]" = x86_64;
"VALID_ARCHS[sdk=iphoneos*]" = "arm64 armv7 armv7s";
"VALID_ARCHS[sdk=iphoneos*]" = "arm64 arm64e armv7 armv7s";
"VALID_ARCHS[sdk=iphonesimulator*]" = "i386 x86_64";
"VALID_ARCHS[sdk=macosx*]" = "x86_64 arm64";
"VALID_ARCHS[sdk=macosx*]" = "x86_64 arm64 arm64e";
"VALID_ARCHS[sdk=watchos*]" = "armv7k arm64_32";
"VALID_ARCHS[sdk=watchsimulator*]" = "x86_64 i386";
VERSIONING_SYSTEM = "apple-generic";
Expand Down Expand Up @@ -439,7 +441,7 @@
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
MARKETING_VERSION = 1.1.0;
SKIP_INSTALL = YES;
"TARGETED_DEVICE_FAMILY[sdk=appletvos*]" = 3;
"TARGETED_DEVICE_FAMILY[sdk=appletvsimulator*]" = 3;
Expand Down Expand Up @@ -473,7 +475,7 @@
"@executable_path/../Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.0.0;
MARKETING_VERSION = 1.1.0;
SKIP_INSTALL = YES;
"TARGETED_DEVICE_FAMILY[sdk=appletvos*]" = 3;
"TARGETED_DEVICE_FAMILY[sdk=appletvsimulator*]" = 3;
Expand Down
8 changes: 8 additions & 0 deletions LinuxMain.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import XCTest

import LDSwiftEventSourceTests

var tests = [XCTestCaseEntry]()
tests += LDSwiftEventSourceTests.__allTests()

XCTMain(tests)
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ pod 'LDSwiftEventSource', '~> 1.0'

### Carthage

To use the [Carthage](https://github.com/Carthage/Carthage) dependency manager to integrate LDSwiftEventSource into your Xcode project, specify it in your `Cartfile` :
To use the [Carthage](https://github.com/Carthage/Carthage) dependency manager to integrate LDSwiftEventSource into your Xcode project, specify it in your `Cartfile`:

```ogdl
github "LaunchDarkly/swift-eventsource" ~> 1.0
```

### Swift Package Manager

The [Swift Package Manager](https://swift.org/package-manager/) is a dependency manager integrated into the `swift` compiler and XCode. Note that the LDSwiftEventSource Swift package provides both a `LDSwiftEventSource` product, which is explicitely dynamic, and a `LDSwiftEventSourceStatic` product which is explicitely static.
The [Swift Package Manager](https://swift.org/package-manager/) is a dependency manager integrated into the `swift` compiler and Xcode. Note that the LDSwiftEventSource Swift package provides both a `LDSwiftEventSource` product, which is explicitely dynamic, and a `LDSwiftEventSourceStatic` product which is explicitely static.

To integrate LDSwiftEventSource into an XCode project, go to the project editor, and select `Swift Packages`. From here hit the `+` button and follow the prompts using `https://github.com/LaunchDarkly/swift-eventsource.git` as the URL.
To integrate LDSwiftEventSource into an Xcode project, go to the project editor, and select `Swift Packages`. From here hit the `+` button and follow the prompts using `https://github.com/LaunchDarkly/swift-eventsource.git` as the URL.

To include LDSwiftEventSource in a Swift package, simply add it to the dependencies section of your `Package.swift` file. And add the desired product as a dependency for your targets.

Expand Down
31 changes: 29 additions & 2 deletions Source/LDSwiftEventSource.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import Foundation

#if os(Linux)
import FoundationNetworking
#endif

#if !os(Linux)
import os.log
#endif

public class EventSource {
private let esDelegate: EventSourceDelegate
Expand Down Expand Up @@ -69,10 +76,13 @@ public class EventSource {

class EventSourceDelegate: NSObject, URLSessionDataDelegate {

#if !os(Linux)
private let logger: OSLog = OSLog(subsystem: "com.launchdarkly.swift-eventsource", category: "LDEventSource")
#endif

private let config: EventSource.Config

private let delegateQueue: DispatchQueue = DispatchQueue(label: "ESDelegateQueue")
private let logger: OSLog

private var readyState: ReadyState = .raw

Expand All @@ -90,14 +100,15 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {
self.config = config
self.lastEventId = config.lastEventId
self.reconnectTime = config.reconnectTime
self.logger = OSLog(subsystem: "com.launchdarkly.swift-eventsource", category: "LDEventSource")
}

func start() {
delegateQueue.async {
guard self.readyState == .raw
else {
#if !os(Linux)
os_log("Start method called on this already-started EventSource object. Doing nothing", log: self.logger, type: .info)
#endif
return
}
self.connect()
Expand All @@ -115,7 +126,9 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {
func getLastEventId() -> String? { lastEventId }

private func connect() {
#if !os(Linux)
os_log("Starting EventSource client", log: logger, type: .info)
#endif
let connectionHandler: ConnectionHandler = (
setReconnectionTime: { reconnectionTime in self.reconnectTime = reconnectionTime },
setLastEventId: { eventId in self.lastEventId = eventId }
Expand Down Expand Up @@ -149,11 +162,15 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {
var nextState: ReadyState = .closed
let currentState: ReadyState = readyState
if errorHandlerAction == .shutdown {
#if !os(Linux)
os_log("Connection has been explicitly shut down by error handler", log: logger, type: .info)
#endif
nextState = .shutdown
}
readyState = nextState
#if !os(Linux)
os_log("State: %@ -> %@", log: logger, type: .debug, currentState.rawValue, nextState.rawValue)
#endif

if currentState == .open {
config.handler.onClosed()
Expand All @@ -174,7 +191,9 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {
let maxSleep = min(config.maxReconnectTime, reconnectTime * pow(2.0, Double(reconnectionAttempts)))
let sleep = maxSleep / 2 + Double.random(in: 0...(maxSleep/2))

#if !os(Linux)
os_log("Waiting %.3f seconds before reconnecting...", log: logger, type: .info, sleep)
#endif
delegateQueue.asyncAfter(deadline: .now() + sleep) {
self.connect()
}
Expand All @@ -190,13 +209,17 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {

if let error = error {
if readyState != .shutdown {
#if !os(Linux)
os_log("Connection error: %@", log: logger, type: .info, error.localizedDescription)
#endif
errorHandlerAction = dispatchError(error: error)
} else {
errorHandlerAction = .shutdown
}
} else {
#if !os(Linux)
os_log("Connection unexpectedly closed.", log: logger, type: .info)
#endif
}

afterComplete()
Expand All @@ -207,7 +230,9 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {
dataTask: URLSessionDataTask,
didReceive response: URLResponse,
completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
#if !os(Linux)
os_log("initial reply received", log: logger, type: .debug)
#endif

let httpResponse = response as! HTTPURLResponse
if (200..<300).contains(httpResponse.statusCode) {
Expand All @@ -216,7 +241,9 @@ class EventSourceDelegate: NSObject, URLSessionDataDelegate {
config.handler.onOpened()
completionHandler(.allow)
} else {
#if !os(Linux)
os_log("Unsuccessful response: %d", log: logger, type: .info, httpResponse.statusCode)
#endif
errorHandlerAction = dispatchError(error: UnsuccessfulResponseError(responseCode: httpResponse.statusCode))
completionHandler(.cancel)
}
Expand Down
21 changes: 0 additions & 21 deletions Tests/EventParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -173,25 +173,4 @@ final class EventParserTests: XCTestCase {
XCTAssertEqual(eventHandler.received, [.message("msg", MessageEvent(data: "foo", lastEventId: nil)),
.message("message", MessageEvent(data: "bar", lastEventId: nil))])
}

static var allTests = [
("testDispatchesSingleLineMessage", testDispatchesSingleLineMessage),
("testDoesNotFireMultipleTimesIfSeveralEmptyLines", testDoesNotFireMultipleTimesIfSeveralEmptyLines),
("testDispatchesSingleLineMessageWIthId", testDispatchesSingleLineMessageWIthId),
("testDispatchesSingleLineMessageWithCustomEvent", testDispatchesSingleLineMessageWithCustomEvent),
("testSendsCommentsForLinesStartingWithColon", testSendsCommentsForLinesStartingWithColon),
("testSetsRetryTimeToSevenSeconds", testSetsRetryTimeToSevenSeconds),
("testDoesNotSetRetryTimeUnlessEntireValueIsNumeric", testDoesNotSetRetryTimeUnlessEntireValueIsNumeric),
("testReusesEventIdIfNotSet", testReusesEventIdIfNotSet),
("testRemovesOnlyFirstSpace", testRemovesOnlyFirstSpace),
("testAllowsNoLeadingSpace", testAllowsNoLeadingSpace),
("testDoesNotDispatchEmptyData", testDoesNotDispatchEmptyData),
("testOnlyLeadingSpaceTreatedAsEmpty", testOnlyLeadingSpaceTreatedAsEmpty),
("testLineWithoutColonTreatedAsFieldNameWithEmptyData", testLineWithoutColonTreatedAsFieldNameWithEmptyData),
("testMultipleDataDispatch", testMultipleDataDispatch),
("testEmptyDataWithBufferedDataAppendsNewline", testEmptyDataWithBufferedDataAppendsNewline),
("testCommentCanContainColon", testCommentCanContainColon),
("testInvalidFieldNameIgnoredInEvent", testInvalidFieldNameIgnoredInEvent),
("testEventNameResetAfterDispatch", testEventNameResetAfterDispatch)
]
}
7 changes: 0 additions & 7 deletions Tests/LDSwiftEventSourceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,6 @@ final class LDSwiftEventSourceTests: XCTestCase {
XCTAssertEqual(config.backoffResetThreshold, 120.0)
XCTAssertEqual(config.idleTimeout, 180.0)
}

static var allTests = [
("testConfigDefaults", testConfigDefaults),
("testConfigModification", testConfigModification)
]
}

private class MockHandler: EventHandler {
Expand All @@ -71,6 +66,4 @@ private class MockHandler: EventHandler {
func onError(error: Error) {

}


}
17 changes: 0 additions & 17 deletions Tests/UTF8LineParserTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,4 @@ final class UTF8LineParserTests: XCTestCase {
XCTAssertEqual(parser.append(data), expected)
XCTAssertEqual(parser.closeAndReset(), [])
}

static var allTests = [
("testNoData", testNoData),
("testEmptyData", testEmptyData),
("testEmptyCrLine", testEmptyCrLine),
("testBasicLine", testBasicLine),
("testBasicLineCr", testBasicLineCr),
("testBasicLineLf", testBasicLineLf),
("testBasicLineCrLf", testBasicLineCrLf),
("testBasicSplit", testBasicSplit),
("testUnicodeString", testUnicodeString),
("testInvalidCharacterReplaced", testInvalidCharacterReplaced),
("testCodePointSplitNotReplaced", testCodePointSplitNotReplaced),
("testPartialReplacedOnClose", testPartialReplacedOnClose),
("testInvalidCharacterReplacedOnNextLineAfterCr", testInvalidCharacterReplacedOnNextLineAfterCr),
("testMultiLineDataMixedLineEnding", testMultiLineDataMixedLineEnding)
]
}
Loading

0 comments on commit 4f817e1

Please sign in to comment.