Until recently we've only needed to report analytics events for Venmo, to Amplitude, via mParticle.
To that end, iOS uses the following abstraction for tracking analytics events in feature code.
protocol AnalyticsEventTracker {| final class Controller: A { | |
| var property: String = "" { | |
| didSet { | |
| for a in collectionOfA { | |
| // Cannot assign to property: 'a' is a 'let' constant | |
| a.property = property | |
| } | |
| } | |
| } |
| struct AttributedStringBuilder { | |
| // MARK: - Types | |
| enum Attribute { | |
| case Font(UIFont) | |
| case ParagraphStyle(NSParagraphStyle) | |
| case ForegroundColor(UIColor) | |
| case BackgroundColor(UIColor) | |
| case Ligature(UInt) |
| [Xcode.app/Contents] ag -g icns$ | ag "framework" | |
| Developer/Library/Xcode/Templates/Project Templates/Mac/Framework & Library/Bundle.xctemplate/TemplateIcon.icns | |
| Developer/Library/Xcode/Templates/Project Templates/Mac/Framework & Library/Cocoa Framework.xctemplate/TemplateIcon.icns | |
| Developer/Library/Xcode/Templates/Project Templates/Mac/Framework & Library/XPC Service.xctemplate/TemplateIcon.icns | |
| Developer/Platforms/AppleTVOS.platform/Developer/Library/Xcode/Templates/Project Templates/AppleTVOS/Framework & Library/TV Framework.xctemplate/TemplateIcon.icns | |
| Developer/Platforms/AppleTVOS.platform/Developer/Library/Xcode/Templates/Project Templates/AppleTVOS/Framework & Library/TV Static Library.xctemplate/TemplateIcon.icns | |
| Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates/iOS/Framework & Library/Cocoa Touch Framework.xctemplate/TemplateIcon.icns | |
| Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Templates/Project Templates/iOS/Framework & Library/Cocoa Touch St |
| /// Defines an interface for objects that can be collated. | |
| protocol Collatable: Hashable { | |
| /// The string value that will be used to collate objects. | |
| var collationString: String { get } | |
| } | |
| final class LocalizedIndexedCollation<T: Collatable> { | |
| // MARK: Properties |
| private func loadCFunction<Function>(named name: String, ofType _: Function.Type = Function.self) -> Function { | |
| let sym = dlsym(UnsafeMutablePointer<Void>(bitPattern: -2), name) // RTLD_DEFAULT | |
| return unsafeBitCast(sym, Function.self) | |
| } | |
| private let CC_SHA1_DIGEST_LENGTH = 20 | |
| private let CC_SHA1: @convention(c) (UnsafePointer<Void>, Int32, UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> = loadCFunction(named: "CC_SHA1") | |
| extension String { |