Skip to content

Storage Additions & Refactoring #304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f82b11b
Storage Refactoring
bsneed Mar 4, 2024
2be54a7
Standardized things a little more
bsneed Mar 4, 2024
4a6667a
fixed build issue
bsneed Mar 4, 2024
c26a6cf
updated build steps
bsneed Mar 4, 2024
8bb52ba
another build update
bsneed Mar 4, 2024
bf35fd1
another one
bsneed Mar 4, 2024
af06602
and another
bsneed Mar 4, 2024
258588d
another
bsneed Mar 4, 2024
5cea86e
another
bsneed Mar 4, 2024
e943d15
another.
bsneed Mar 4, 2024
efe28e8
another
bsneed Mar 4, 2024
30541bf
... another
bsneed Mar 5, 2024
a3efb21
another
bsneed Mar 5, 2024
1dd3df3
another
bsneed Mar 5, 2024
3856674
another
bsneed Mar 5, 2024
663ff4a
another
bsneed Mar 5, 2024
84a3b5f
... another
bsneed Mar 5, 2024
15d8443
and another ....
bsneed Mar 5, 2024
cc07f4b
... another
bsneed Mar 5, 2024
c69eee9
one more .. ?
bsneed Mar 5, 2024
439d1ba
i wish ...
bsneed Mar 5, 2024
aaae5a8
help me.
bsneed Mar 5, 2024
9fb3b15
tell my mother; github actions took her son.
bsneed Mar 5, 2024
039e6e5
the light is fading ...
bsneed Mar 5, 2024
44ceea8
add visionOS test
alanjcharles Mar 5, 2024
a95f8c5
another visionOS try
bsneed Mar 5, 2024
f5615da
another one...
bsneed Mar 5, 2024
61b484b
thank you sir, another ...
bsneed Mar 5, 2024
702974d
and another ...
bsneed Mar 5, 2024
76f1a5c
will it blend?
bsneed Mar 5, 2024
8830892
yet another
bsneed Mar 5, 2024
21f3d29
another.
bsneed Mar 5, 2024
acf884b
some more refactoring ... nevermore.
bsneed Mar 5, 2024
d775d42
more refactoring
bsneed Mar 7, 2024
a5f2baa
tweaked some tests
bsneed Mar 7, 2024
e58b540
Ramp up some test values for linux
bsneed Mar 7, 2024
ba42685
Package rename
bsneed Mar 7, 2024
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
170 changes: 93 additions & 77 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,119 +2,135 @@ name: Swift

on:
push:
branches: [ main ]
branches: [main]
pull_request:
branches: [ main ]
branches: [main]

jobs:
cancel_previous:
runs-on: ubuntu-latest
steps:
- uses: styfle/cancel-workflow-action@0.9.1
with:
workflow_id: ${{ github.event.workflow.id }}
- uses: styfle/cancel-workflow-action@0.12.0
with:
workflow_id: ${{ github.event.workflow.id }}

build_and_test_spm_mac:
needs: cancel_previous
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v2
- uses: webfactory/ssh-agent@v0.5.3
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- name: Build
run: swift build
- name: Run tests
run: swift test
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "15.2"
- uses: actions/checkout@v2
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- name: Build
run: swift build
- name: Run tests
run: swift test

build_and_test_spm_linux:
needs: cancel_previous
runs-on: ubuntu-latest
steps:
- uses: fwal/[email protected]
with:
swift-version: "5.7.2"
- uses: actions/checkout@v2
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- name: Build
run: swift build
- name: Run tests
run: swift test --enable-test-discovery
- uses: sersoft-gmbh/swifty-linux-action@v3
with:
release-version: "5.9.2"
github-token: ${{secrets.GITHUB_TOKEN}}
- uses: actions/checkout@v2
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- name: Build
run: swift build
- name: Run tests
run: swift test --enable-test-discovery

build_and_test_ios:
needs: cancel_previous
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v2
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- run: xcodebuild -scheme Segment test -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 13'

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "15.2"
- uses: actions/checkout@v2
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- run: xcodebuild -scheme Segment test -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15'

build_and_test_tvos:
needs: cancel_previous
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v2
- uses: webfactory/ssh-agent@v0.5.3
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- run: xcodebuild -scheme Segment test -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV'
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "15.2"
- uses: actions/checkout@v2
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- run: xcodebuild -scheme Segment test -sdk appletvsimulator -destination 'platform=tvOS Simulator,name=Apple TV'

build_and_test_watchos:
needs: cancel_previous
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "15.2"
- uses: actions/checkout@v2
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- run: xcodebuild -scheme Segment test -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch Series 9 (45mm)'

build_and_test_visionos:
needs: cancel_previous
runs-on: macos-14
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v2
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- run: xcodebuild -scheme Segment test -sdk watchsimulator -destination 'platform=watchOS Simulator,name=Apple Watch Series 8 (45mm)'

- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "15.2"
- uses: actions/checkout@v2
- uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- run: defaults write com.apple.dt.Xcode AllowUnsupportedVisionOSHost -bool YES
- run: defaults write com.apple.CoreSimulator AllowUnsupportedVisionOSHost -bool YES
- run: xcodebuild -downloadPlatform visionOS
- run: echo - skip until apple fixes this - xcodebuild -scheme Segment test -sdk xrsimulator -destination 'platform=visionOS Simulator,name=Apple Vision Pro'
- run: xcodebuild -scheme Segment -sdk xrsimulator -destination 'platform=visionOS Simulator,name=Apple Vision Pro'

build_and_test_examples:
needs: cancel_previous
runs-on: macos-latest
runs-on: macos-14
steps:
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: latest-stable
- uses: actions/checkout@v2
- uses: webfactory/ssh-agent@v0.5.3
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- name: build for ios simulator
run: |
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: "15.2"
- uses: actions/checkout@v2
- uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.SOVRAN_SSH_KEY }}
- name: build for ios simulator
run: |
cd Examples/apps/BasicExample
xcodebuild -workspace "BasicExample.xcworkspace" -scheme "BasicExample" -sdk iphonesimulator
- name: build for ios simulator
run: |
- name: build for ios simulator
run: |
cd Examples/apps/ObjCExample
xcodebuild -workspace "ObjCExample.xcworkspace" -scheme "ObjCExample" -sdk iphonesimulator
- name: build for ios simulator
run: |
- name: build for ios simulator
run: |
cd Examples/apps/SegmentUIKitExample
xcodebuild -workspace "SegmentUIKitExample.xcworkspace" -scheme "SegmentUIKitExample" -sdk iphonesimulator
- name: build for ios simulator
run: |
- name: build for ios simulator
run: |
cd Examples/apps/SegmentWeatherWidget
xcodebuild -workspace "SegmentWeatherWidget.xcworkspace" -scheme "SegmentWeatherWidget" -sdk iphonesimulator
- name: build for mac catalyst
run: |
- name: build for mac catalyst
run: |
cd Examples/apps/SegmentUIKitExample
xcodebuild -workspace "SegmentUIKitExample.xcworkspace" -scheme "SegmentUIKitExample" -destination 'platform=macOS,variant=Mac Catalyst'

5 changes: 3 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.7
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand All @@ -9,7 +9,8 @@ let package = Package(
.macOS("10.15"),
.iOS("13.0"),
.tvOS("11.0"),
.watchOS("7.1")
.watchOS("7.1"),
.visionOS("1.0")
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
Expand Down
41 changes: 0 additions & 41 deletions [email protected]

This file was deleted.

30 changes: 15 additions & 15 deletions Sources/Segment/Analytics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,20 @@ public class Analytics {
/// - configuration: The configuration to use
public init(configuration: Configuration) {
if Self.isActiveWriteKey(configuration.values.writeKey) {
// If you're hitting this in testing, it could be a memory leak, or something async is still running
// and holding a reference. You can use XCTest.waitUntilFinished(...) to wait for things to complete.
fatalError("Cannot initialize multiple instances of Analytics with the same write key")
} else {
Self.addActiveWriteKey(configuration.values.writeKey)
}

store = Store()
storage = Storage(store: self.store, writeKey: configuration.values.writeKey)
storage = Storage(
store: self.store,
writeKey: configuration.values.writeKey,
storageMode: configuration.values.storageMode,
operatingMode: configuration.values.operatingMode
)
timeline = Timeline()

// provide our default state
Expand Down Expand Up @@ -325,32 +332,25 @@ extension Analytics {
}
}

if let files = storage.read(Storage.Constants.events) {
if files.count > 0 {
return true
}
}

return false
return storage.dataStore.hasData
}

/// Provides a list of finished, but unsent events.
public var pendingUploads: [URL]? {
return storage.read(Storage.Constants.events)
return storage.read(Storage.Constants.events)?.dataFiles
}

/// Purge all pending event upload files.
public func purgeStorage() {
if let files = pendingUploads {
for file in files {
purgeStorage(fileURL: file)
}
}
storage.dataStore.reset()
}

/// Purge a single event upload file.
public func purgeStorage(fileURL: URL) {
try? FileManager.default.removeItem(at: fileURL)
guard let dataFiles = storage.read(Storage.Constants.events)?.dataFiles else { return }
if dataFiles.contains(fileURL) {
try? FileManager.default.removeItem(at: fileURL)
}
}

/// Wait until the Analytics object has completed startup.
Expand Down
20 changes: 20 additions & 0 deletions Sources/Segment/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ public enum OperatingMode {
static internal let defaultQueue = DispatchQueue(label: "com.segment.operatingModeQueue", qos: .utility)
}

// MARK: - Storage Mode
/// Specifies the storage mode to be used for events
public enum StorageMode {
/// Store events to disk (default).
case disk
/// Store events to disk in the given a directory URL.
case diskAtURL(URL)
/// Store events to memory and specify a max count before they roll off.
case memory(Int)
/// Some custom, user-defined storage mechanism conforming to `DataStore`.
case custom(any DataStore)
}

// MARK: - Internal Configuration

public class Configuration {
Expand All @@ -42,6 +55,7 @@ public class Configuration {
var flushQueue: DispatchQueue = OperatingMode.defaultQueue
var userAgent: String? = nil
var jsonNonConformingNumberStrategy: JSONSafeEncoder.NonConformingFloatEncodingStrategy = .zero
var storageMode: StorageMode = .disk
}

internal var values: Values
Expand Down Expand Up @@ -233,6 +247,12 @@ public extension Configuration {
JSON.jsonNonConformingNumberStrategy = values.jsonNonConformingNumberStrategy
return self
}

@discardableResult
func storageMode(_ mode: StorageMode) -> Configuration {
values.storageMode = mode
return self
}
}

extension Analytics {
Expand Down
7 changes: 5 additions & 2 deletions Sources/Segment/Plugins/Platforms/Vendors/AppleUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,11 @@ internal class MacOSVendorSystem: VendorSystem {
// It has to be fetched on the main thread, so we've spun it off
// async and cache it when it comes back.
if Self.asyncUserAgent == nil {
DispatchQueue.main.async {
Self.asyncUserAgent = WKWebView().value(forKey: "userAgent") as? String
// it's failing tests because it never comes back; they get stuck.
if isUnitTesting == false {
DispatchQueue.main.async {
Self.asyncUserAgent = WKWebView().value(forKey: "userAgent") as? String
}
}
}
return Self.asyncUserAgent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,9 @@ extension SegmentDestination: iOSLifecycle {
}

extension SegmentDestination.UploadTaskInfo {
init(url: URL, task: URLSessionDataTask) {
init(url: URL?, data: Data?, task: URLSessionDataTask) {
self.url = url
self.data = data
self.task = task

if let application = UIApplication.safeShared {
Expand Down
Loading