feat: anonymous analytics with PostHog (#3)
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
CC5718382E2020490042BA88 /* OpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = CC5718372E2020490042BA88 /* OpenAI */; };
|
CC5718382E2020490042BA88 /* OpenAI in Frameworks */ = {isa = PBXBuildFile; productRef = CC5718372E2020490042BA88 /* OpenAI */; };
|
||||||
CCBA53E72E212F1C00469D84 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = CCBA53E62E212F1C00469D84 /* Sparkle */; };
|
CCBA53E72E212F1C00469D84 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = CCBA53E62E212F1C00469D84 /* Sparkle */; };
|
||||||
|
CCC33F812E236B6F00EDE382 /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = CCC33F802E236B6F00EDE382 /* PostHog */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@@ -28,6 +29,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
CCC33F812E236B6F00EDE382 /* PostHog in Frameworks */,
|
||||||
CC5718382E2020490042BA88 /* OpenAI in Frameworks */,
|
CC5718382E2020490042BA88 /* OpenAI in Frameworks */,
|
||||||
CCBA53E72E212F1C00469D84 /* Sparkle in Frameworks */,
|
CCBA53E72E212F1C00469D84 /* Sparkle in Frameworks */,
|
||||||
);
|
);
|
||||||
@@ -82,6 +84,7 @@
|
|||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
CC5718372E2020490042BA88 /* OpenAI */,
|
CC5718372E2020490042BA88 /* OpenAI */,
|
||||||
CCBA53E62E212F1C00469D84 /* Sparkle */,
|
CCBA53E62E212F1C00469D84 /* Sparkle */,
|
||||||
|
CCC33F802E236B6F00EDE382 /* PostHog */,
|
||||||
);
|
);
|
||||||
productName = Meetingnotes;
|
productName = Meetingnotes;
|
||||||
productReference = CC5718182E201D8D0042BA88 /* Meetingnotes.app */;
|
productReference = CC5718182E201D8D0042BA88 /* Meetingnotes.app */;
|
||||||
@@ -114,6 +117,7 @@
|
|||||||
packageReferences = (
|
packageReferences = (
|
||||||
CC5718362E2020490042BA88 /* XCRemoteSwiftPackageReference "OpenAI" */,
|
CC5718362E2020490042BA88 /* XCRemoteSwiftPackageReference "OpenAI" */,
|
||||||
CCBA53E52E212F1C00469D84 /* XCRemoteSwiftPackageReference "Sparkle" */,
|
CCBA53E52E212F1C00469D84 /* XCRemoteSwiftPackageReference "Sparkle" */,
|
||||||
|
CCC33F7F2E236B6F00EDE382 /* XCRemoteSwiftPackageReference "posthog-ios" */,
|
||||||
);
|
);
|
||||||
preferredProjectObjectVersion = 77;
|
preferredProjectObjectVersion = 77;
|
||||||
productRefGroup = CC5718192E201D8D0042BA88 /* Products */;
|
productRefGroup = CC5718192E201D8D0042BA88 /* Products */;
|
||||||
@@ -373,6 +377,14 @@
|
|||||||
minimumVersion = 2.7.1;
|
minimumVersion = 2.7.1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
CCC33F7F2E236B6F00EDE382 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/PostHog/posthog-ios.git";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 3.28.2;
|
||||||
|
};
|
||||||
|
};
|
||||||
/* End XCRemoteSwiftPackageReference section */
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
@@ -386,6 +398,11 @@
|
|||||||
package = CCBA53E52E212F1C00469D84 /* XCRemoteSwiftPackageReference "Sparkle" */;
|
package = CCBA53E52E212F1C00469D84 /* XCRemoteSwiftPackageReference "Sparkle" */;
|
||||||
productName = Sparkle;
|
productName = Sparkle;
|
||||||
};
|
};
|
||||||
|
CCC33F802E236B6F00EDE382 /* PostHog */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = CCC33F7F2E236B6F00EDE382 /* XCRemoteSwiftPackageReference "posthog-ios" */;
|
||||||
|
productName = PostHog;
|
||||||
|
};
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = CC5718102E201D8D0042BA88 /* Project object */;
|
rootObject = CC5718102E201D8D0042BA88 /* Project object */;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"originHash" : "e8774f1c4a54f0b9bb959e13d276fae95c54472a479606f1fd28800bfbcb6da5",
|
"originHash" : "55d8e28deb3208ddf2aa2ec08d05566b9cae31d15d7c0ac6f9194b6eea1a9a74",
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "openai",
|
"identity" : "openai",
|
||||||
@@ -10,6 +10,15 @@
|
|||||||
"version" : "0.4.4"
|
"version" : "0.4.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "posthog-ios",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/PostHog/posthog-ios.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "784145ddd2f7de3a6d6fcce0e50c04f29d33b338",
|
||||||
|
"version" : "3.28.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "sparkle",
|
"identity" : "sparkle",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|||||||
@@ -20,10 +20,11 @@ Implemented:
|
|||||||
- Auto updates
|
- Auto updates
|
||||||
- Text formatting
|
- Text formatting
|
||||||
- Different note templates
|
- Different note templates
|
||||||
|
- Integrate with Posthog for anonymous analytics (installs, opens, meetings created)
|
||||||
|
|
||||||
Todo:
|
Todo:
|
||||||
|
|
||||||
- Integrate with Posthog for anonymous analytics
|
- Onboarding screen to enable settings and set API key
|
||||||
|
|
||||||
Later:
|
Later:
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Sparkle
|
import Sparkle
|
||||||
|
import PostHog
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct MeetingnotesApp: App {
|
struct MeetingnotesApp: App {
|
||||||
@@ -14,6 +15,22 @@ struct MeetingnotesApp: App {
|
|||||||
|
|
||||||
init() {
|
init() {
|
||||||
updaterController = SPUStandardUpdaterController(updaterDelegate: nil, userDriverDelegate: nil)
|
updaterController = SPUStandardUpdaterController(updaterDelegate: nil, userDriverDelegate: nil)
|
||||||
|
// Setup PostHog analytics for anonymous tracking
|
||||||
|
let posthogAPIKey = "phc_Wt8sWUzUF7YPF50aQ0B1qbfA5SJWWR341zmXCaIaIRJ"
|
||||||
|
let posthogHost = "https://us.i.posthog.com"
|
||||||
|
let config = PostHogConfig(apiKey: posthogAPIKey, host: posthogHost)
|
||||||
|
// Only capture anonymous events
|
||||||
|
config.personProfiles = .never
|
||||||
|
// Enable lifecycle and screen view autocapture
|
||||||
|
config.captureApplicationLifecycleEvents = true
|
||||||
|
config.captureScreenViews = true
|
||||||
|
PostHogSDK.shared.setup(config)
|
||||||
|
// Register environment as a super property
|
||||||
|
#if DEBUG
|
||||||
|
PostHogSDK.shared.register(["environment": "dev"] )
|
||||||
|
#else
|
||||||
|
PostHogSDK.shared.register(["environment": "prod"] )
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
import PostHog
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class MeetingListViewModel: ObservableObject {
|
class MeetingListViewModel: ObservableObject {
|
||||||
@@ -69,6 +70,8 @@ class MeetingListViewModel: ObservableObject {
|
|||||||
let newMeeting = Meeting()
|
let newMeeting = Meeting()
|
||||||
meetings.insert(newMeeting, at: 0)
|
meetings.insert(newMeeting, at: 0)
|
||||||
_ = LocalStorageManager.shared.saveMeeting(newMeeting)
|
_ = LocalStorageManager.shared.saveMeeting(newMeeting)
|
||||||
|
// Track meeting creation event
|
||||||
|
PostHogSDK.shared.capture("meeting_created")
|
||||||
return newMeeting
|
return newMeeting
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
import PostHog
|
||||||
|
|
||||||
// Add notification name for meeting saved events
|
// Add notification name for meeting saved events
|
||||||
extension Notification.Name {
|
extension Notification.Name {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ struct OnboardingView: View {
|
|||||||
.font(.title2)
|
.font(.title2)
|
||||||
.fontWeight(.semibold)
|
.fontWeight(.semibold)
|
||||||
|
|
||||||
Text("Please review and accept the terms of service and privacy policy.")
|
Text("Of note, I am tracking a few basic anonymous metrics (installs, opens, meetings created) using PostHog, because I'm trying to gauge interest in the app and whether it's worth it to pay for an Apple Developer License & domain name. Everything is completely anonymous (feel free to check the source code). If you have any concerns, please reach out.")
|
||||||
.font(.body)
|
.font(.body)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user