☂️ Umbrella
Swift的监控抽象层。受Moya启发。
目录
为什么?
目前有许多移动应用监控工具,如Firebase、Google Analytics、Fabric Answers、Flurry、Mixpanel等。你可能会在应用程序中使用一个或多个这些工具。但大多数这些SDK存在一些问题:如果你使用多个监控工具,你的代码将会一团糟。并且SDK使用事件名作为字符串,参数作为字典,这并不能得到Swift编译器的保障。这意味着如果你改变了事件定义,你应该手动找到所有相关的代码。这存在人为错误的机会。Umbrella使用Swift枚举和相关值来解决这些问题。
特性
💪 利用枚举和关联值的优势使用 Swift 编译器。🎯 一次性向多个分析提供商记录事件。🎨 创建自定义分析提供商。
概览
之前
FIRAnalytics.logEvent(withName: kFIREventEcommercePurchase, parameters: [
kFIRParameterCurrency: "USD" as NSObject,
kFIRParameterValue: 9.99 as NSNumber,
kFIRParameterTransactionID: "20170709123456" as NSObject,
])
Flurry.logEvent("purchase", withParameters: [
"Currency": "USD",
"Price": 9.99,
"Transaction ID": "20170709123456"
])
MyCustomAnalytics.logEvent("purchase", withParameters: [
"currency": "USD",
"price": 9.99,
"transaction_id": "20170709123456"
])
之后
let analytics = Analytics<MyAppEvent>()
analytics.register(provider: FirebaseProvider())
analytics.register(provider: FlurryProvider())
analytics.register(provider: MyCustomProvider())
analytics.log(.purchase(currency: "USD", price: 9.99, transactionID: "20170709123456"))
入门
定义事件
首先,您应该在单个枚举中定义所有事件。假设我们有三个事件,它们具有关联参数。
enum MyAppEvent {
case signup(username: String)
case viewContent(productID: Int)
case purchase(productID: Int, price: Float)
}
然后将枚举使符合协议 EventType
。它需要两个函数:name(for:)
和 parameters(for:)
。
extension MyAppEvent: EventType {
/// An event name to be logged
func name(for provider: ProviderType) -> String? {
switch self {
case .signup: return "signup"
case .viewContent: return "view_content"
case .purchase: return "purchase"
}
}
/// Parameters to be logged
func parameters(for provider: ProviderType) -> [String: Any]? {
switch self {
case let .signup(username):
return ["username": username]
case let .viewContent(productID):
return ["product_id": productID]
case let .purchase(productID, price):
return ["product_id": productID, "price": price]
}
}
}
您甚至可以通过 provider
提供不同的事件名称和参数。
使用分析
您可以在任何地方定义一个 Analytics
实例,但建议在全局范围定义。
let analytics = Analytics<MyAppEvent>()
然后您应该注册提供商。提供商是对真实分析服务(如 Firebase 和 Fabric Answers)的包装。建议在 application(_:didFinishLaunchingWithOptions:)
中注册提供商。
analytics.register(provider: AnswersProvider())
analytics.register(provider: FirebaseProvider())
analytics.register(provider: FlurryProvider())
analytics.register(provider: MyAwesomeProvider())
完成这些步骤后,您现在可以记录事件了
analytics.log(.signup(username: "devxoul"))
内置提供商
存在几个内置提供者。
- AmplitudeProvider (Amplitude-iOS)
- AnswersProvider (Answers)
- AppboyProvider (Appboy-iOS-SDK)
- AppsFlyerProvider (AppsFlyerFramework)
- FacebookProvider (FBSDKCoreKit)
- FirebaseProvider (Firebase/Analytics)
- FlurryProvider (Flurry-iOS-SDK/FabricSDK)
- IntercomProvider (Intercom)
- LocalyticsProvider (Localytics)
- MixpanelProvider (Mixpanel)
- SegmentProvider (Analytics)
如果没有你需要的提供者,你可以 创建一个 Issue 或者 创建自定义提供者。对于缺失的服务,欢迎创建 pull request。
创建自定义提供者
如果你使用的服务没有内置提供者,你也可以创建自己的。创建提供者很简单:只需创建一个类并符合 ProviderType
协议。
final class MyAwesomeProvider: ProviderType {
func log(_ eventName: String, parameters: [String: Any]?) {
AwesomeAnalytics.logEvent(withName: eventName, parameters: parameters)
}
}
安装
Umbrella 目前仅支持 CocoaPods。
pod 'Umbrella'
pod 'Umbrella/Firebase' # using with built-in FirebaseProvider
pod 'Umbrella/...'
贡献
任何讨论和 pull request 都受欢迎
生成 Xcode Workspace
$ make project
这将自动生成 Umbrella.xcworkspace
并执行 pod install
。
创建新的供应商
例如,假设我们将为分析服务'Raincoat'创建一个新的供应商。
-
在
Package.swift
中添加一个库和目标定义。let package = Package( name: "Umbrella", products: [ .library(name: "Umbrella", targets: ["Umbrella"]), .library(name: "UmbrellaFirebase", targets: ["UmbrellaFirebase"]), .library(name: "UmbrellaMixpanel", targets: ["UmbrellaMixpanel"]), + .library(name: "UmbrellaRaincoat", targets: ["UmbrellaRaincoat"]), ], targets: [ .target(name: "Umbrella"), .target(name: "UmbrellaFirebase", dependencies: ["Umbrella"]), .target(name: "UmbrellaMixpanel", dependencies: ["Umbrella"]), + .target(name: "UmbrellaRaincoat", dependencies: ["Umbrella"]), .testTarget(name: "UmbrellaTests", dependencies: ["Umbrella"]), .testTarget(name: "UmbrellaFirebaseTests", dependencies: ["UmbrellaFirebase"]), .testTarget(name: "UmbrellaMixpanelTests", dependencies: ["UmbrellaMixpanel"]), + .testTarget(name: "UmbrellaRaincoat", dependencies: ["UmbrellaRaincoat"]), ] )
-
添加一个源文件和一个测试文件。
... ├── Sources │ ├── UmbrellaFirebase │ │ └── FirebaseProvider.swift │ ├── UmbrellaMixpanel │ │ └── MixpanelProvider.swift + │ ├── UmbrellaRaincoat + │ │ └── RaincoatProvider.swift | ... ├── Tests │ ├── UmbrellaFirebaseTests │ │ └── FirebaseProviderTests.swift │ ├── UmbrellaMixpanelTests │ │ └── MixpanelProviderTests.swift + │ ├── UmbrellaRaincoatTests + │ │ └── RaincoatProviderTests.swift ... ...
-
在
Podfile
中添加 CocoaPods 依赖。target 'UmbrellaFirebaseTests' do platform :ios, '8.0' pod 'Firebase/Analytics' end target 'UmbrellaMixpanelTests' do platform :ios, '8.0' pod 'Mixpanel' end + target 'UmbrellaRaincoatTests' do + platform :ios, '8.0' + pod 'Raincoat' + end
-
在
Umbrella.podspec
中添加 CocoaPods subspec。s.subspec "Firebase" do |ss| ss.source_files = "Sources/UmbrellaFirebase/*.swift" ss.dependency "Umbrella/Core" end s.subspec "Mixpanel" do |ss| ss.source_files = "Sources/UmbrellaMixpanel/*.swift" ss.dependency "Umbrella/Core" end + s.subspec "Raincoat" do |ss| + ss.source_files = "Sources/UmbrellaRaincoat/*.swift" + ss.dependency "Umbrella/Core" + end
-
创建 Xcode 工作空间并运行测试。别忘了检查代码覆盖率,以确保测试可以覆盖新供应商。
$ make project
许可协议
Umbrella 采用 MIT 许可协议。有关更多信息,请参阅 LICENSE 文件。