-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
33 changed files
with
3,284 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
// | ||
// AmplitudeService.swift | ||
// Beam | ||
// | ||
// Created by Rens Verhoeven on 18-04-16. | ||
// Copyright © 2016 Awkward. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import Trekker | ||
import Amplitude | ||
|
||
/** | ||
Adding a service requires to first implement the Amplitude SDK. See these steps: https://github.com/amplitude/Amplitude-iOS#swift | ||
*/ | ||
|
||
/// An example implementation of Amplitude as an TrekkerService. | ||
/// Supports: | ||
/// - Event analytics | ||
/// - User profiles | ||
/// - Timed analytics (custom implementation) | ||
/// - Super properties (as user properties, see `userPropertiesAsEventSuperProperties` to disable this) | ||
class AmplitudeService: TrekkerService { | ||
|
||
var serviceName = "Amplitude" | ||
|
||
var versionString: String { | ||
return kAMPVersion | ||
} | ||
|
||
let tracker: Amplitude | ||
|
||
/// If the amplitude service should use the user properties as event super properties. User properties are still available on every event in the Amplitude web UI. | ||
var userPropertiesAsEventSuperProperties = true | ||
|
||
/// The start date by the name of an event. If the same name starts timing again, it will be overwritten. | ||
fileprivate var startDatesByEvent: [String: Date] = [String: Date]() | ||
|
||
/// Creates the Amplitude analytice service with the given API key. | ||
/// | ||
/// - Parameter apiKey: The API key to use for amplitude. | ||
init(apiKey: String) { | ||
let amplitude = Amplitude.instance()! | ||
amplitude.initializeApiKey(apiKey) | ||
self.tracker = amplitude | ||
} | ||
|
||
} | ||
|
||
/// MARK: - TrekkerEventAnalytics | ||
extension AmplitudeService: TrekkerEventAnalytics { | ||
|
||
func trackEvent(_ event: String, withProperties properties: [String : Any]?) { | ||
if let properties = properties { | ||
self.tracker.logEvent(event, withEventProperties: properties) | ||
} else { | ||
self.tracker.logEvent(event) | ||
} | ||
} | ||
|
||
} | ||
|
||
/// MARK: - TrekkerTimedEventAnalytics | ||
extension AmplitudeService: TrekkerTimedEventAnalytics { | ||
|
||
func startTimingEvent(_ event: String) { | ||
self.startDatesByEvent[event] = Date() | ||
} | ||
|
||
func stopTimingEvent(_ event: String, withProperties properties: [String : Any]?) { | ||
if let properties = properties { | ||
var allProperties = properties | ||
if let startDate = self.startDatesByEvent[event] { | ||
allProperties["Duration"] = Date().timeIntervalSince(startDate) | ||
} | ||
|
||
self.tracker.logEvent(event, withEventProperties: properties) | ||
} else { | ||
var allProperties = [String: Any]() | ||
if let startDate = self.startDatesByEvent[event] { | ||
allProperties["Duration"] = Date().timeIntervalSince(startDate) | ||
} | ||
self.tracker.logEvent(event, withEventProperties: allProperties) | ||
} | ||
if let index = self.startDatesByEvent.index(forKey: event) { | ||
self.startDatesByEvent.remove(at: index) | ||
} | ||
} | ||
} | ||
|
||
/// MARK: - TrekkerUserProfileAnalytics | ||
extension AmplitudeService: TrekkerUserProfileAnalytics { | ||
|
||
func identify(using profile: TrekkerUserProfile) { | ||
self.tracker.setUserId(profile.identifier) | ||
let identify = AMPIdentify() | ||
if let value = profile.fullName { | ||
identify.set("Full name", value: value as NSString) | ||
} | ||
if let value = profile.firstname { | ||
identify.set("First name", value: value as NSString) | ||
} | ||
if let value = profile.lastname { | ||
identify.set("Last name", value: value as NSString) | ||
} | ||
if let value = profile.gender?.rawValue { | ||
identify.set("Gender", value: value as NSString) | ||
} | ||
if let value = profile.email { | ||
identify.set("Email", value: value as NSString) | ||
} | ||
for (key, value) in profile.customProperties { | ||
if let object = value as? NSObject { | ||
identify.set(key, value: object) | ||
} else { | ||
NSLog("User property can not be sent to Amplitude because it can not be converted to an NSObject \(key)") | ||
} | ||
|
||
} | ||
|
||
self.tracker.identify(identify) | ||
} | ||
} | ||
|
||
// MARK: - TrekkerEventSuperPropertiesAnalytics | ||
extension AmplitudeService: TrekkerEventSuperPropertiesAnalytics { | ||
|
||
func registerEventSuperProperties(_ properties: [String : Any]) { | ||
guard self.userPropertiesAsEventSuperProperties else { | ||
return | ||
} | ||
self.tracker.setUserProperties(properties) | ||
} | ||
|
||
func clearEventSuperProperties() { | ||
guard self.userPropertiesAsEventSuperProperties else { | ||
return | ||
} | ||
self.tracker.clearUserProperties() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
// | ||
// FirebaseService.swift | ||
// ExampleAnalyticsServices | ||
// | ||
// Created by Rens Verhoeven on 22/03/2017. | ||
// Copyright © 2017 awkward. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import Trekker | ||
import Firebase | ||
|
||
/** | ||
Adding a service requires to first implement the Firebase SDK. See these steps: https://firebase.google.com/docs/analytics/ios/start | ||
**Important Note: ** Firebase requires all event and property names to be lowercase without spaces. | ||
*/ | ||
|
||
/// An example implementation of Firebase as an TrekkerService. | ||
/// **Important Note: ** Firebase requires all event and property names to be lowercase without spaces. | ||
/// | ||
/// Supports: | ||
/// - Event analytics | ||
/// - User profiles (requires pre-registration on Firebase console) | ||
/// - Timed analytics (custom implementation) | ||
class FirebaseService: TrekkerService { | ||
|
||
var serviceName = "Firebase" | ||
|
||
var versionString: String { | ||
return "1.0" | ||
} | ||
|
||
/// The start date by the name of an event. If the same name starts timing again, it will be overwritten. | ||
fileprivate var startDatesByEvent: [String: Date] = [String: Date]() | ||
|
||
/// Creates the Firebase analytice service. | ||
init() { | ||
|
||
} | ||
|
||
/// Converts the property from [String: Any] to [String: NSObject]. | ||
/// Also turns the keys into lowercase without spaces. This is required by firebase. | ||
/// | ||
/// - Parameter properties: The properties that should be converted. | ||
/// - Returns: The properties converted to [String: NSObject] with lowercase keys. | ||
fileprivate func convertProperties(_ properties: [String: Any]?) -> [String: NSObject]? { | ||
guard let properties = properties else { | ||
return nil | ||
} | ||
var newProperties = [String: NSObject]() | ||
for (key, value) in properties { | ||
let newKey = key.lowercased().replacingOccurrences(of: " ", with: "_") | ||
if let newValue = value as? NSObject { | ||
newProperties[newKey] = newValue | ||
} else { | ||
NSLog("Property for key \(key) could not be sent to firebase because the value type is not supported") | ||
} | ||
} | ||
return newProperties | ||
} | ||
|
||
|
||
/// Converts the event name to lower case without spaces. | ||
/// | ||
/// - Parameter event: The evenr name to convert. | ||
/// - Returns: The converted event name. | ||
fileprivate func convertEventName(_ event: String) -> String { | ||
return event.lowercased().replacingOccurrences(of: " ", with: "_") | ||
} | ||
|
||
} | ||
|
||
/// MARK: - TrekkerEventAnalytics | ||
extension FirebaseService: TrekkerEventAnalytics { | ||
|
||
func trackEvent(_ event: String, withProperties properties: [String : Any]?) { | ||
FIRAnalytics.logEvent(withName: self.convertEventName(event), parameters: self.convertProperties(properties)) | ||
} | ||
|
||
} | ||
|
||
/// MARK: - TrekkerTimedEventAnalytics | ||
extension FirebaseService: TrekkerTimedEventAnalytics { | ||
|
||
func startTimingEvent(_ event: String) { | ||
self.startDatesByEvent[event] = Date() | ||
} | ||
|
||
func stopTimingEvent(_ event: String, withProperties properties: [String : Any]?) { | ||
if let properties = properties { | ||
var allProperties = properties | ||
if let startDate = self.startDatesByEvent[event] { | ||
allProperties["Duration"] = Date().timeIntervalSince(startDate) | ||
} | ||
FIRAnalytics.logEvent(withName: self.convertEventName(event), parameters: self.convertProperties(properties)) | ||
} else { | ||
var allProperties = [String: Any]() | ||
if let startDate = self.startDatesByEvent[event] { | ||
allProperties["Duration"] = Date().timeIntervalSince(startDate) | ||
} | ||
FIRAnalytics.logEvent(withName: self.convertEventName(event), parameters: self.convertProperties(properties)) | ||
} | ||
if let index = self.startDatesByEvent.index(forKey: event) { | ||
self.startDatesByEvent.remove(at: index) | ||
} | ||
} | ||
} | ||
|
||
/// MARK: - TrekkerUserProfileAnalytics | ||
extension FirebaseService: TrekkerUserProfileAnalytics { | ||
|
||
func identify(using profile: TrekkerUserProfile) { | ||
FIRAnalytics.setUserID(profile.identifier) | ||
if let value = profile.fullName { | ||
FIRAnalytics.setUserPropertyString(value, forName: "full_name") | ||
} | ||
if let value = profile.firstname { | ||
FIRAnalytics.setUserPropertyString(value, forName: "first_name") | ||
} | ||
if let value = profile.lastname { | ||
FIRAnalytics.setUserPropertyString(value, forName: "last_name") | ||
} | ||
if let value = profile.gender?.rawValue { | ||
FIRAnalytics.setUserPropertyString(value, forName: "gender") | ||
} | ||
if let value = profile.email { | ||
FIRAnalytics.setUserPropertyString(value, forName: "email") | ||
} | ||
if let properties = self.convertProperties(profile.customProperties) { | ||
for (key, value) in properties { | ||
if let string = value as? String { | ||
FIRAnalytics.setUserPropertyString(string, forName: key) | ||
} else { | ||
NSLog("User property can not be sent to firebase because it can not be converted to a string \(key)") | ||
} | ||
|
||
} | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.