Skip to content

Commit

Permalink
Formatting (#16)
Browse files Browse the repository at this point in the history
Formatting changes to better follow recommended/common ways to format
Swift. For example avoid ";" and "()" when not needed, usage of "self"
when not needed for clarity, and some other things.

Also removes some redundant whitespace/new-lines.
  • Loading branch information
manucheri committed Oct 15, 2023
1 parent 5226af5 commit b9540f0
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 71 deletions.
48 changes: 24 additions & 24 deletions Sources/Aptabase/Aptabase.swift
Expand Up @@ -17,7 +17,7 @@ public class Aptabase: NSObject {

/// The shared client instance.
@objc public static let shared = Aptabase()

/// Initializes the client with given App Key.
/// - Parameters:
/// - appKey: The App Key to use.
Expand All @@ -28,13 +28,13 @@ public class Aptabase: NSObject {
debugPrint("The Aptabase App Key \(appKey) is invalid. Tracking will be disabled.")
return
}
guard let baseUrl = self.getBaseUrl(parts[1], options?.host) else {

guard let baseUrl = getBaseUrl(parts[1], options?.host) else {
return
}
self.client = AptabaseClient(appKey: appKey, baseUrl: baseUrl, env: env, options: options)

client = AptabaseClient(appKey: appKey, baseUrl: baseUrl, env: env, options: options)

let notifications = NotificationCenter.default
#if os(tvOS) || os(iOS)
notifications.addObserver(self, selector: #selector(startPolling), name: UIApplication.willEnterForegroundNotification, object: nil)
Expand All @@ -49,7 +49,7 @@ public class Aptabase: NSObject {
}
#endif
}

/// Track an event using given properties.
/// - Parameters:
/// - eventName: The name of the event to track.
Expand All @@ -58,10 +58,10 @@ public class Aptabase: NSObject {
guard let codable = toCodableProps(from: props) else {
return
}

enqueueEvent(eventName, with: codable)
}

/// Initializes the client with given App Key.
/// - Parameter appKey: The App Key to use.
@objc public func initialize(appKey: String) {
Expand All @@ -75,7 +75,7 @@ public class Aptabase: NSObject {
@objc public func initialize(appKey: String, options: InitOptions?) {
initialize(appKey: appKey, with: options)
}

/// Track an event using given properties.
/// - Parameters:
/// - eventName: The name of the event to track.
Expand All @@ -84,53 +84,53 @@ public class Aptabase: NSObject {
guard let codable = toCodableProps(from: props) else {
return
}

enqueueEvent(eventName, with: codable)
}

/// Forces all queued events to be sent to the server
@objc public func flush() {
Task {
await self.client?.flush()
}
}

private func enqueueEvent(_ eventName: String, with props: [String: AnyCodableValue] = [:]) {
guard let client = self.client else {
guard let client else {
return
}

client.trackEvent(eventName, with: props)
}

@objc private func startPolling() {
self.client?.startPolling()
client?.startPolling()
}

@objc private func stopPolling() {
self.client?.stopPolling()
client?.stopPolling()
}

private var hosts = [
"US": "https://us.aptabase.com",
"EU": "https://eu.aptabase.com",
"DEV": "http://localhost:3000",
"SH": ""
]

private func getBaseUrl(_ region: String, _ host: String?) -> String? {
guard var baseURL = hosts[region] else { return nil }
if region == "SH" {
guard let host = host else {
guard let host else {
debugPrint("Aptabase: Host parameter must be defined when using Self-Hosted App Key. Tracking will be disabled.")
return nil
}
baseURL = host
}

return baseURL
}

private func toCodableProps(from props: [String: Any]) -> [String: AnyCodableValue]? {
var codableProps: [String: AnyCodableValue] = [:]
for (key, value) in props {
Expand Down
34 changes: 17 additions & 17 deletions Sources/Aptabase/AptabaseClient.swift
@@ -1,31 +1,31 @@
import Foundation

internal class AptabaseClient {
private static let sdkVersion = "aptabase-swift@0.3.3";
class AptabaseClient {
private static let sdkVersion = "aptabase-swift@0.3.3"
// Session expires after 1 hour of inactivity
private static let sessionTimeout: TimeInterval = 1 * 60 * 60

private var sessionId = UUID()
private var lastTouched = Date()
private var flushTimer: Timer?
private let dispatcher: EventDispatcher
private let env: EnvironmentInfo
private let flushInterval: Double

init(appKey: String, baseUrl: String, env: EnvironmentInfo, options: InitOptions?) {
self.flushInterval = options?.flushInterval ?? (env.isDebug ? 2.0 : 60.0)
flushInterval = options?.flushInterval ?? (env.isDebug ? 2.0 : 60.0)
self.env = env
self.dispatcher = EventDispatcher(appKey: appKey, baseUrl: baseUrl, env: env)

dispatcher = EventDispatcher(appKey: appKey, baseUrl: baseUrl, env: env)
}

public func trackEvent(_ eventName: String, with props: [String: AnyCodableValue] = [:]) {
let now = Date()
if lastTouched.distance(to: now) > AptabaseClient.sessionTimeout {
sessionId = UUID()
}
lastTouched = now

let evt = Event(timestamp: Date(),
sessionId: sessionId,
eventName: eventName,
Expand All @@ -41,24 +41,24 @@ internal class AptabaseClient {
props: props)
dispatcher.enqueue(evt)
}

public func startPolling() {
stopPolling();
flushTimer = Timer.scheduledTimer(timeInterval: self.flushInterval, target: self, selector: #selector(flushSync), userInfo: nil, repeats: true)
stopPolling()

flushTimer = Timer.scheduledTimer(timeInterval: flushInterval, target: self, selector: #selector(flushSync), userInfo: nil, repeats: true)
}

public func stopPolling() {
flushTimer?.invalidate()
flushTimer = nil

flushSync()
}

public func flush() async {
await dispatcher.flush()
}

@objc private func flushSync() {
let semaphore = DispatchSemaphore(value: 0)
Task {
Expand Down
2 changes: 1 addition & 1 deletion Sources/Aptabase/ConcurrentQueue.swift
Expand Up @@ -29,7 +29,7 @@ class ConcurrentQueue<T> {
func dequeue(count: Int) -> [T] {
var dequeuedElements = [T]()
queue.sync {
for _ in 0..<min(count, self.elements.count) {
for _ in 0 ..< min(count, self.elements.count) {
dequeuedElements.append(self.elements.removeFirst())
}
}
Expand Down
10 changes: 5 additions & 5 deletions Sources/Aptabase/EnvironmentInfo.swift
Expand Up @@ -15,11 +15,11 @@ struct EnvironmentInfo {
var locale = ""
var appVersion = ""
var appBuildNumber = ""

static func current() -> EnvironmentInfo {
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
let appBuildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String

return EnvironmentInfo(
isDebug: isDebug,
osName: osName,
Expand All @@ -29,15 +29,15 @@ struct EnvironmentInfo {
appBuildNumber: appBuildNumber ?? ""
)
}

private static var isDebug: Bool {
#if DEBUG
true
#else
false
#endif
}

private static var osName: String {
#if os(macOS) || targetEnvironment(macCatalyst)
"macOS"
Expand All @@ -54,7 +54,7 @@ struct EnvironmentInfo {
""
#endif
}

private static var osVersion: String {
#if os(macOS) || targetEnvironment(macCatalyst)
let os = ProcessInfo.processInfo.operatingSystemVersion
Expand Down
27 changes: 13 additions & 14 deletions Sources/Aptabase/EventDispatcher.swift
Expand Up @@ -26,15 +26,15 @@ extension URLSession: URLSessionProtocol {}

public class EventDispatcher {
private var events = ConcurrentQueue<Event>()
private let MAX_BATCH_SIZE = 25
private let maximumBatchSize = 25
private let headers: [String: String]
private let apiUrl: URL
private let session: URLSessionProtocol

init(appKey: String, baseUrl: String, env: EnvironmentInfo, session: URLSessionProtocol = URLSession.shared) {
self.session = session
self.apiUrl = URL(string: "\(baseUrl)/api/v0/events")!
self.headers = [
apiUrl = URL(string: "\(baseUrl)/api/v0/events")!
headers = [
"Content-Type": "application/json",
"App-Key": appKey,
"User-Agent": "\(env.osName)/\(env.osVersion) \(env.locale)"
Expand All @@ -55,9 +55,8 @@ public class EventDispatcher {
}

var failedEvents: [Event] = []
while (!events.isEmpty)
{
let eventsToSend = events.dequeue(count: MAX_BATCH_SIZE)
while !events.isEmpty {
let eventsToSend = events.dequeue(count: maximumBatchSize)
do {
try await sendEvents(eventsToSend)
} catch {
Expand All @@ -74,24 +73,24 @@ public class EventDispatcher {
if events.isEmpty {
return
}

do {
let body = try encoder.encode(events)

var request = URLRequest(url: apiUrl)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = body

let (data, response) = try await session.data(for: request)
let statusCode = (response as? HTTPURLResponse)?.statusCode ?? 0
if (statusCode < 300) {
if statusCode < 300 {
return
}
let responseText = String(data: data , encoding: .utf8) ?? ""

let responseText = String(data: data, encoding: .utf8) ?? ""
let reason = "\(statusCode) \(responseText)"

if statusCode < 500 {
debugPrint("Aptabase: Failed to send \(events.count) events because of \(reason). Will not retry.")
return
Expand All @@ -103,7 +102,7 @@ public class EventDispatcher {
throw error
}
}

private var encoder: JSONEncoder = {
let encoder = JSONEncoder()
let formatter = DateFormatter()
Expand Down
2 changes: 1 addition & 1 deletion Sources/Aptabase/InitOptions.swift
Expand Up @@ -4,7 +4,7 @@ import Foundation
public final class InitOptions: NSObject {
let host: String?
let flushInterval: Double?

/// - Parameters:
/// - host: The custom host to use. If none provided will use Aptabase's servers.
/// - flushInterval: Defines a custom interval for flushing events.
Expand Down
15 changes: 6 additions & 9 deletions Sources/Aptabase/Value.swift
Expand Up @@ -8,32 +8,29 @@ extension String: Value {}
extension Float: Value {}
extension Bool: Value {}


enum AnyCodableValue: Encodable {
case integer(Int)
case string(String)
case float(Float)
case double(Double)
case boolean(Bool)
case null



func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .integer(let x):
case let .integer(x):
try container.encode(x)
case .string(let x):
case let .string(x):
try container.encode(x)
case .float(let x):
case let .float(x):
try container.encode(x)
case .double(let x):
case let .double(x):
try container.encode(x)
case .boolean(let x):
case let .boolean(x):
try container.encode(x)
case .null:
try container.encode(self)
break
}
}
}

0 comments on commit b9540f0

Please sign in to comment.