SDKs
iOS / tvOS / macOS
Native Swift SDK for Apple platforms. Works with AVPlayer, AVKit, and any custom player.
Requirements
- iOS 13+ / tvOS 13+ / macOS 11+
- Swift 5.7+, Xcode 14+
Install
Swift Package Manager (recommended)
In Xcode, File → Add Packages… and paste:
https://github.com/tapemetric/analytics-ios.gitPick version 1.0.0 or later.
Or in Package.swift:
dependencies: [
.package(url: "https://github.com/tapemetric/analytics-ios.git", from: "1.0.0")
]CocoaPods
pod 'TapemetricAnalytics', '~> 1.0'Then pod install.
Carthage
github "tapemetric/analytics-ios" ~> 1.0Initialize
Configure once at app launch — typically in your App init (SwiftUI) or application(_:didFinishLaunchingWithOptions:)(UIKit).
import TapemetricAnalytics
@main
struct MyApp: App {
init() {
Tapemetric.configure(
TapemetricConfig(
apiKey: "tm_live_yourkey",
debug: true // remove in production
)
)
}
var body: some Scene { /* ... */ }
}Identify users
// After login
Tapemetric.shared.identify("user_123", plan: .svod, traits: [
"country": "IN",
"signupSource": "instagram",
])
// On logout
Tapemetric.shared.reset()Track playback
let content = TrackContent(
contentId: "aashiqana_s04e12",
contentType: "series",
contentTitle: "Aashiqana",
season: 4,
episode: 12
)
// On play
Tapemetric.shared.trackPlayStart(content, playback: PlaybackState(positionSec: 0))
// On pause / resume
Tapemetric.shared.trackPause(PlaybackState(positionSec: 124.5))
Tapemetric.shared.trackResume(PlaybackState(positionSec: 124.5))
// On bitrate change
Tapemetric.shared.trackBitrateChange(2400, playback: PlaybackState(
positionSec: 200, bitrateKbps: 2400
))
// On end
Tapemetric.shared.trackComplete(playback: PlaybackState(
positionSec: 1320, durationSec: 1320
))
// On error
Tapemetric.shared.trackError(code: "NETWORK_ERROR", message: "Failed to load playlist", fatal: true)Track revenue
Tapemetric.shared.trackPurchase(
amountInr: 199,
plan: .svod,
orderId: "order_xyz",
contentId: "pvr_premiere_2026" // optional, for TVOD
)AVPlayer integration
import AVKit
import TapemetricAnalytics
class PlayerViewController: AVPlayerViewController {
var content: TrackContent!
private var bufferStartedAt: Date?
override func viewDidLoad() {
super.viewDidLoad()
// Track play_start when ready
player?.currentItem?.addObserver(
self, forKeyPath: #keyPath(AVPlayerItem.status),
options: [.new], context: nil
)
NotificationCenter.default.addObserver(
self, selector: #selector(itemEnded),
name: .AVPlayerItemDidPlayToEndTime, object: nil
)
}
@objc private func itemEnded() {
let pos = player?.currentTime().seconds ?? 0
Tapemetric.shared.trackComplete(
playback: PlaybackState(positionSec: pos)
)
}
override func observeValue(
forKeyPath keyPath: String?, of object: Any?,
change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?
) {
if keyPath == #keyPath(AVPlayerItem.status),
player?.currentItem?.status == .readyToPlay {
Tapemetric.shared.trackPlayStart(content)
}
}
}Lifecycle handling
The SDK automatically flushes pending events when your app goes to the background (UIApplication.didEnterBackgroundNotification on iOS, equivalent on tvOS/macOS). You don’t need to call flush() manually unless you’ve set flushInterval very high.
os(tvOS) and sets device_type to tv on every event.Privacy
The SDK doesn’t use IDFA, doesn’t access location, and doesn’t require any privacy manifest entries beyond network access. The anonymous ID is stored in UserDefaults only.
Source and issues
SDK source: github.com/tapemetric/analytics-ios. Bug reports and feature requests welcome — please file an issue or email sdk@tapemetric.com.