Tracer-iOS 0.1.2

Tracer-iOS 0.1.2

Rob Phillips 维护。



  • 作者
  • Keepsafe

Tracer

CircleCI Apache 2.0 licensed CocoaPods Swift 4+ iOS

它做什么

Tracer扮演了一个内存日志的角色,它可以进行时间范围追踪,以验证用户体验流程、分析事件或其他任何类型的串行事件总线。

例如,如果您期望在注册流程中触发EventOneEventTwoEventThree,Tracer可以帮助您的发展或QA团队验证这些分析在某些点是否损坏。

任何可以被表示为Equatable的都可以在追踪期间进行记录和验证。常见的例子包括字符串、数组或字典(尤其是在Swift 4.1中的条件一致性),但您也可以传递您自己的自定义结构体或类,只要它们是Equatable

您可以选择手动运行追踪,使用悬停在上面的内置UI,或者使重要的追踪在单元或UI测试期间自动运行。

示例UI使用

请参阅以下示例GIF或查看示例文件夹来了解使用方法。

API 使用

或者如果您准备好实施,可以跳转到以下API 部分

安装

使用 CocoaPods 快速安装

pod 'Tracer/UI'

# or optionally don't include the UI component
pod 'Tracer/Core'

或者 Carthage

github "KeepSafe/Tracer-iOS"

或者手动安装

示例

运行跟踪

在您告知跟踪工具您的跟踪后,它会列出所有跟踪,并允许您或您的 QA 团队手动开始一个。

这里有一个简单的示例,其中顺序很重要

passinginorder

还有相同的跟踪,由于事件被次序错误地触发而失败(在这种情况下,它将失败所有尚未匹配的事件,因为它们也会被认为是有序错误的)。

failingoutoforder

移动它

您可以在任何时候展开或折叠 UI,甚至可以将它移动到屏幕上的任何位置,或者拉动它的顶部来调整展开时覆盖的屏幕区域大小。

moveitaround

记录器

记录使用每个项目的 debugDescription 来在屏幕上显示它,因此请确保您的更复杂的数据结构实现此功能以显示您希望的方式。

tracetool

追踪

追踪具有多种选项,例如enforceOrderallowDuplicatesassertOnFailure,您可以根据特定场景进行配置。您甚至可以在开始追踪之前执行程序化设置步骤(例如将您的应用程序重置到某个配置),或者列出可选的手动设置步骤。

示例 1:顺序很重要,重复不要紧

configone

(此追踪的通过/失败在上述第一个示例部分中所示)

示例 2:没有重复,顺序不重要

configtwo

此追踪的顺序不重要,所以通过它会看起来像

passingoutoforder

但是,重复很重要,所以如果在追踪期间发生任何重复,它将会失败

failingduplicate

自定义设置

可选的,您还可以向追踪工具添加自己的自定义设置(甚至为日志项显示自定义表情符号)

customsettings

API

UI

如果您使用UI前端,您将直接通过TraceUI.swift进行交互。请参阅TraceUIExample

let traceUI = TraceUI()
traceUI.show()

您也可以通过调试设置将其切换到.hide()

注意:如果您在该工具的AppDelegate中启动,应该在您的应用窗口加载后懒加载它,以确保工具正确启动。最好是监听.UIWindowDidBecomeKey事件,然后在发生之后才显示。

配置

使用以下方法将跟踪加载到UI中

traceUI.add(traces: [MyTraces.traceOne, MyTraces.traceTwo])

日志与验证

如果您要将特定项记录下来以便于与跟踪进行比较验证,请使用

traceUI.log(traceItem: Event.three.toTraceItem)

在这里,我们只是创建一个Event枚举,列出了我们在应用程序中触发的事件,然后使用.toTraceItem属性进行转换

enum Event: String {
    case one
    case two
    case three
    
    var uxFlowHint: String {
        switch self {
        case .one: return "Press the 'Fire event 1' button"
        case .two: return "Press the 'Fire event 2' button"
        case .three: return "Press the 'Fire event 3' button"
        }
    }
    
    var toTraceItem: TraceItem {
        return TraceItem(type: "event", itemToMatch: AnyTraceEquatable(self), uxFlowHint: uxFlowHint)
    }
}

否则,您也可以使用泛型日志记录(无需与正在进行的跟踪进行验证),通过使用

traceUI.log(genericItem: AnyTraceEquatable("Moooooooooo"), emojiToPrepend: "🐄")

所有日志

您可以在TraceUI.swift中查看所有日志函数及其文档。

public func log(traceItem: TraceItem, verboseLog: AnyTraceEquatable? = nil, emojiToPrepend: String? = "⚡️") {}

public func logVerbose(traceItem: TraceItem, emojiToPrepend: String? = "⚡️") { }

public func log(genericItem: AnyTraceEquatable, properties: LoggedItemProperties? = nil, emojiToPrepend: String? = "⚡️") { }

编程API

如果您不想使用内建的UI前端,您可以将跟踪设置为手动运行,例如在单元或UI测试期间。请参阅AnalyticsTraceExample

请随意浏览单元测试以获取示例。

创建并启动跟踪

// This is an individual item to match and could be in multiple traces
let answerTraceItem = TraceItem(type: "The answer to the universe", itemToMatch: AnyTraceEquatable(42))
// This is a trace with an array of items it needs to match in order to pass
let trace = Trace(name: "Find the answer", itemsToMatch: [answerTraceItem])
// And this is the time-scoped tracer that handles logging and creating pass/fail results
let tracer = Tracer(trace: trace)

// Starting a trace returns a tuple with the current state and two signals to listen to
let (currentState, stateChangedSignal, itemLoggedSignal) = tracer.start()

print("\n\n---> TRACE STARTED: \(analyticsTrace.name)")
print("---> Current trace state: \(currentState)")

// Optionally, listen to changes in this trace (and you can remove the listener at any point)
itemLoggedListener = itemLoggedSignal.listen { traceItem in
    print("---> Trace item logged: \(traceItem)")
}
stateChangedListener = stateChangedSignal.listen { traceState in
    print("---> Trace state updated to: \(traceState.rawValue)")
    print("---> Trace state description: \(traceState)")
}

日志记录

在跟踪过程中进行日志记录很简单

tracer.log(item: answerTraceItem)

// After an item is logged, your trace will immediately either be passing or failing.
// Optionally, you can set `assertOnFailure` to `true` on your `Trace` instance to stop 
// app execution as soon as a trace fails so you can debug.

或者,您甚至可以将它挂钩到您的 Analytics 结构中

Analytics.log(event: .thirdViewSeen)

/// See example app for this setup
struct Analytics {
    
    static func log(event: AnalyticsEvent) {
        print("\n\nANALYTICS: \(event.rawValue) logged")
        
        Tracers.analytics.activeTracer?.log(item: event.toTraceItem)
    }
    
}

停止和报告

停止跟踪会返回包含原始或摘要版本的结果的 TraceReport

// FYI: signal listeners are automatically removed when stopped
let report = tracer.stop()
print(report.summary)
print(report.rawLog)

// Or manually parse the results yourself
let results = report.result

手动安装

  1. 克隆此存储库并将 Tracer.xcodeproj 拖拽到您的应用程序的 Xcode 项目导航器中。
  • 它应该出现在您的应用程序蓝色项目图标下面。它是在所有其他 Xcode 组之上还是之下无关紧要。
  1. 在项目导航器中选择 Tracer.xcodeproj 并验证部署目标与您的应用程序目标的部署目标相匹配。
  2. 在项目导航器中选择您的应用程序项目(蓝色项目图标)以进入目标配置窗口,然后在侧边栏的 Targets 标题下选择应用程序目标。
  3. 在窗口顶部的标签栏中,打开 General (一般)面板。
  4. Embedded Binaries (嵌入式二进制)部分的下方的 + 按钮上点击。
  5. 搜索并选择顶部的 Tracer.framework

就这样!

Tracer.framework 会自动作为目标依赖项、链接框架和嵌入框架添加到复制文件构建阶段,这是您在模拟器和设备上构建所需的所有内容。

问题和错误

请使用Github issue tracker告诉我们您可能遇到的问题。

授权

Tracer for iOS遵循Apache Software License, 2.0 ("Apache 2.0")

作者

Tracer for iOS由Rob Phillips及其余Keepsafe团队成员共同制作。我们非常欢迎您贡献或加入我们