Tracer
它做什么
Tracer扮演了一个内存日志的角色,它可以进行时间范围追踪,以验证用户体验流程、分析事件或其他任何类型的串行事件总线。
例如,如果您期望在注册流程中触发EventOne
、EventTwo
和EventThree
,Tracer可以帮助您的发展或QA团队验证这些分析在某些点是否损坏。
任何可以被表示为Equatable
的都可以在追踪期间进行记录和验证。常见的例子包括字符串、数组或字典(尤其是在Swift 4.1中的条件一致性),但您也可以传递您自己的自定义结构体或类,只要它们是Equatable
。
您可以选择手动运行追踪,使用悬停在上面的内置UI,或者使重要的追踪在单元或UI测试期间自动运行。
示例UI使用
API 使用
或者如果您准备好实施,可以跳转到以下API 部分。
安装
使用 CocoaPods 快速安装
pod 'Tracer/UI'
# or optionally don't include the UI component
pod 'Tracer/Core'
或者 Carthage
github "KeepSafe/Tracer-iOS"
或者手动安装
示例
运行跟踪
在您告知跟踪工具您的跟踪后,它会列出所有跟踪,并允许您或您的 QA 团队手动开始一个。
这里有一个简单的示例,其中顺序很重要
还有相同的跟踪,由于事件被次序错误地触发而失败(在这种情况下,它将失败所有尚未匹配的事件,因为它们也会被认为是有序错误的)。
移动它
您可以在任何时候展开或折叠 UI,甚至可以将它移动到屏幕上的任何位置,或者拉动它的顶部来调整展开时覆盖的屏幕区域大小。
记录器
记录使用每个项目的 debugDescription
来在屏幕上显示它,因此请确保您的更复杂的数据结构实现此功能以显示您希望的方式。
追踪
追踪具有多种选项,例如enforceOrder
、allowDuplicates
或assertOnFailure
,您可以根据特定场景进行配置。您甚至可以在开始追踪之前执行程序化设置步骤(例如将您的应用程序重置到某个配置),或者列出可选的手动设置步骤。
示例 1:顺序很重要,重复不要紧
(此追踪的通过/失败在上述第一个示例部分中所示)
示例 2:没有重复,顺序不重要
此追踪的顺序不重要,所以通过它会看起来像
但是,重复很重要,所以如果在追踪期间发生任何重复,它将会失败
自定义设置
可选的,您还可以向追踪工具添加自己的自定义设置(甚至为日志项显示自定义表情符号)
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
手动安装
- 克隆此存储库并将
Tracer.xcodeproj
拖拽到您的应用程序的 Xcode 项目导航器中。
- 它应该出现在您的应用程序蓝色项目图标下面。它是在所有其他 Xcode 组之上还是之下无关紧要。
- 在项目导航器中选择
Tracer.xcodeproj
并验证部署目标与您的应用程序目标的部署目标相匹配。 - 在项目导航器中选择您的应用程序项目(蓝色项目图标)以进入目标配置窗口,然后在侧边栏的
Targets
标题下选择应用程序目标。 - 在窗口顶部的标签栏中,打开
General
(一般)面板。 - 在
Embedded Binaries
(嵌入式二进制)部分的下方的+
按钮上点击。 - 搜索并选择顶部的
Tracer.framework
。
就这样!
Tracer.framework
会自动作为目标依赖项、链接框架和嵌入框架添加到复制文件构建阶段,这是您在模拟器和设备上构建所需的所有内容。
问题和错误
请使用Github issue tracker告诉我们您可能遇到的问题。
授权
Tracer for iOS遵循Apache Software License, 2.0 ("Apache 2.0")
作者
Tracer for iOS由Rob Phillips及其余Keepsafe团队成员共同制作。我们非常欢迎您贡献或加入我们。