Skip to content

[CI] (0ae2102) swift/hackers-ios#1247

Closed
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-0ae2102-swift-hackers-ios
Closed

[CI] (0ae2102) swift/hackers-ios#1247
wizard-ci-bot[bot] wants to merge 1 commit into
mainfrom
wizard-ci-0ae2102-swift-hackers-ios

Conversation

@wizard-ci-bot
Copy link
Copy Markdown

@wizard-ci-bot wizard-ci-bot Bot commented Apr 15, 2026

Automated wizard CI run

Source: wizard-pr
Trigger ID: 0ae2102
App: swift/hackers-ios
App directory: apps/swift/hackers-ios
Workbench branch: wizard-ci-0ae2102-swift-hackers-ios
Wizard branch: release-please--branches--main--components--wizard
Context Mill branch: main
PostHog (MCP) branch: master
Timestamp: 2026-04-15T19:50:23.354Z
Duration: 504.7s

@wizard-ci-bot
Copy link
Copy Markdown
Author

wizard-ci-bot Bot commented Apr 15, 2026

I wasn't able to verify the exact latest version of posthog-ios from external sources, but version 3.50.0 appears to be a reasonable recent version. Let me now complete the full evaluation based on the diff.

Let me also check a critical detail - whether the API key in the scheme file looks like a real key that should be flagged.

Looking at the scheme file, the API key value is sTMFPsFhdP1Ssg — this is set in the Xcode scheme's environment variables, which is the framework-prescribed pattern. However, this appears to be a hardcoded value in the scheme file rather than truly being loaded from an external source at runtime. The PostHogEnv enum reads from ProcessInfo.processInfo.environment, which does get the value from the scheme's environment variables, so this is the correct iOS pattern.

Now let me check a few more things about the identify call:

Looking at LoginViewModel.swift:

PostHogSDK.shared.identify(username, userProperties: ["username": username])
PostHogSDK.shared.capture("user_logged_in", properties: ["username": username])

The identify call uses username as the distinct_id. This is a Hacker News username, which is a legitimate user identifier in the context of this app (it's a real auth credential). However, username as a distinct_id is somewhat fragile — it depends on whether HN usernames are truly unique and stable. Still, since this is literally the authentication credential for HN, it's reasonable.

Also notable: username is passed in both userProperties and as an event property on user_logged_in. The username in event properties could be considered PII leakage into event properties rather than person properties only.

Now let me assess error tracking - I don't see any explicit error tracking setup (like PostHogSDK.shared.captureException or similar). The support_purchase_failed event captures error info, but that's a custom event, not formal error/exception tracking.


PR Evaluation Report

Summary

This PR integrates the PostHog iOS SDK (v3.50.0) into a Hacker News reader iOS app built with SwiftUI and Swift Package Manager. The integration adds SDK initialization in the app entry point, user identification on login, reset on logout, and 11 custom analytics events across authentication, feed, comments, voting, settings/purchases, and onboarding modules.

Files changed Lines added Lines removed
16 +181 -11

Confidence score: 5/5 🧙

  • Username as distinct_id: The identify() call uses the raw HN username as the distinct_id. While this is the app's auth identifier, usernames are PII and using them directly as distinct_ids is not best practice — a hashed or opaque ID would be preferable. [MEDIUM]
  • No error/exception tracking: There is no PostHogSDK.shared.captureException() or equivalent error tracking setup. The support_purchase_failed event is a custom capture, not formal exception tracking. [CRITICAL]
  • Username PII in event properties: user_logged_in event includes username in event properties rather than only in person properties via identify(). [MEDIUM]
  • PostHog dependency duplicated across all SPM packages: The posthog-ios dependency is added to 5 separate Package.swift files. A cleaner architecture would add it only to the Shared package and have other modules access PostHog through Shared. This works but creates unnecessary coupling. [LOW]

File changes

Filename Score Description
App/HackersApp.swift 5/5 Adds PostHogEnv enum and SDK initialization with captureApplicationLifecycleEvents — follows framework rules exactly
App/OnboardingCoordinator.swift 4/5 Captures onboarding_completed event with app version property
Features/Authentication/Package.swift 4/5 Adds posthog-ios SPM dependency
Features/Authentication/.../LoginViewModel.swift 3/5 Identify + capture on login, but uses raw username as distinct_id and leaks username into event properties
Features/Comments/Package.swift 4/5 Adds posthog-ios SPM dependency
Features/Comments/.../CommentsViewModel.swift 4/5 Captures comments_viewed with post_id, title, and count
Features/Feed/Package.swift 4/5 Adds posthog-ios SPM dependency
Features/Feed/.../FeedViewModel.swift 4/5 Captures feed category change, bookmark toggle, and search events with properties
Features/Settings/Package.swift 4/5 Adds posthog-ios SPM dependency
Features/Settings/.../SupportViewModel.swift 4/5 Captures purchase success/failure with product details; minor refactor of existing if-block
Hackers.xcodeproj/project.pbxproj 5/5 Correct three-object SPM dependency wiring (PBXBuildFile, XCSwiftPackageProductDependency, XCRemoteSwiftPackageReference)
Hackers.xcodeproj/.../Hackers.xcscheme 4/5 Adds env vars for API key and host to Run scheme
Shared/Package.swift 4/5 Adds posthog-ios SPM dependency
Shared/.../SessionService.swift 5/5 Captures logout event and calls reset() — follows best practices
Shared/.../VotingViewModel.swift 4/5 Captures post and comment upvote events with IDs
posthog-setup-report.md 3/5 Setup report — not a code file

App sanity check ⚠️

Criteria Result Description
App builds and runs Yes All changes are syntactically valid Swift, SPM dependencies correctly configured, pbxproj has proper UUIDs
Preserves existing env vars & configs Yes Existing scheme settings, build configs, and Package.swift dependencies preserved
No syntax or type errors Yes All Swift code follows correct PostHog iOS SDK API patterns
Correct imports/exports Yes import PostHog added in all files that use PostHogSDK.shared
Minimal, focused changes Yes All changes relate to PostHog integration; the SupportViewModel refactor is minimal and necessary
Pre-existing issues None No pre-existing issues noted

Issues

  • Duplicated SPM dependency: PostHog is added as a dependency in 5 separate Package.swift files. While functional, centralizing through the Shared module would be cleaner. [LOW]

Other completed criteria

  • Environment variables documented in Xcode scheme
  • Build configuration is valid (pbxproj properly structured with three SPM objects)
  • All imports resolve correctly

PostHog implementation ⚠️

Criteria Result Description
PostHog SDKs installed Yes posthog-ios v3.50.0 added via SPM in project.pbxproj and all Package.swift files
PostHog client initialized Yes PostHogSDK.shared.setup(config) in HackersApp.init() with captureApplicationLifecycleEvents = true
capture() Yes 11 meaningful capture calls across authentication, feed, comments, voting, settings, and onboarding
identify() Yes Called on login with username; reset() called on logout. However, raw username used as distinct_id
Error tracking No No PostHogSDK.shared.captureException() or equivalent error tracking setup. support_purchase_failed is a custom event, not formal exception tracking
Reverse proxy N/A iOS native app — reverse proxy is not applicable

Issues

  • No error/exception tracking: The PR does not implement PostHog's error/exception tracking feature (captureException or equivalent). The support_purchase_failed custom event captures one specific failure case but is not a substitute for SDK-level error tracking. [CRITICAL]
  • Username as distinct_id: PostHogSDK.shared.identify(username, ...) uses the raw HN username as the distinct_id. While this is the app's authentication identifier and thus a "real" ID, usernames are PII. A hashed identifier or internal user ID would be more appropriate for analytics. [MEDIUM]
  • Username in event properties: The user_logged_in event passes username in event properties (properties: ["username": username]). The username is already set as a person property via identify() — it should not also be in event-level properties where it constitutes PII leakage. [MEDIUM]

Other completed criteria

  • API key loaded from environment variable via PostHogEnv enum with ProcessInfo.processInfo.environment
  • Host correctly configured as https://us.i.posthog.com via environment variable
  • SDK initialization follows the documented SwiftUI pattern
  • reset() called on logout to unlink future events from the user

PostHog insights and events ⚠️

Filename PostHog events Description
LoginViewModel.swift user_logged_in Captures successful login with username property; also calls identify()
SessionService.swift user_logged_out Captures logout before calling reset()
OnboardingCoordinator.swift onboarding_completed Captures onboarding dismissal with app_version
FeedViewModel.swift feed_category_changed, post_bookmarked, post_unbookmarked, post_searched Feed interactions with category, post_id, post_title, search query, result_count
CommentsViewModel.swift comments_viewed Captures post comment loading with post_id, title, comment_count
VotingViewModel.swift post_upvoted, comment_upvoted Captures upvotes with post_id, post_title, comment_id
SupportViewModel.swift support_purchase_completed, support_purchase_failed IAP success/failure with product_id, product_kind, error_message

Issues

  • PII in event properties: user_logged_in includes username in event properties. Username should only be set via person properties (already done through identify()), not duplicated in event-level properties. [MEDIUM]

Other completed criteria

  • Events represent real user actions (login, logout, upvote, bookmark, search, purchase, onboarding)
  • Events enable product insights (login→engagement funnel, purchase funnel, search analysis, voting trends)
  • Events include relevant contextual properties (post_id, post_title, category, result_count, product_kind)
  • Event names are descriptive and follow consistent snake_case convention

Reviewed by wizard workbench PR evaluator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants