Skip to content

Conversation

@huzaifaedhi22
Copy link

This PR

  • adds App Tracking permission on app startup to comply with app store requirements

@dargmuesli dargmuesli changed the title feat(app-tracking): add app tracking permission on startup feat(app-tracking): add permission on startup Apr 3, 2025
@dargmuesli dargmuesli force-pushed the fix/add-apptracking-permission branch from 0c663f1 to 796e58a Compare April 3, 2025 15:04
@huzaifaedhi22 huzaifaedhi22 requested a review from dargmuesli June 10, 2025 02:46
@CLAassistant
Copy link

CLAassistant commented Jun 28, 2025

CLA assistant check
All committers have signed the CLA.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements App Tracking Transparency (ATT) permission handling to comply with App Store requirements. The implementation follows the existing push notification permission pattern by adding WebView message handlers and native iOS tracking authorization using ATTrackingManager. The tracking permission request is automatically triggered when the web content finishes loading.

Key changes:

  • Added ATT framework integration with automatic permission request on app startup
  • Registered WebView message handlers for bidirectional communication about tracking permissions
  • Updated Info.plist with required tracking usage description

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
vibetype/WebView.swift Added AppTrackingTransparency import and registered two new message handlers for tracking permission requests and state queries
vibetype/ViewController.swift Implemented tracking permission logic with handlers, refactored message handler from if-else to switch statement, and added automatic tracking permission request after web content loads
vibetype/Info.plist Added required NSUserTrackingUsageDescription for ATT compliance and updated camera usage description for clarity

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

Comment on lines +281 to 295
func dispatchEventToWebView(name: String, data: String) {
DispatchQueue.main.async {
vibetype.webView.evaluateJavaScript("""
window.dispatchEvent(new CustomEvent('\(name)', { detail: '\(data)' }));
""", completionHandler: nil)
}
}

func handleTrackingState() {
let status = ATTrackingManager.trackingAuthorizationStatus
let isAuthorized = status == .authorized
let state = isAuthorized ? "authorized" : "denied"
returnTrackingPermissionState(state: state)
}
}
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dispatchEventToWebView function is incorrectly placed outside the ViewController extension scope. It should be indented to be a member of the extension. Currently it's defined at the file level which makes it not accessible as an instance method.

Suggested change
func dispatchEventToWebView(name: String, data: String) {
DispatchQueue.main.async {
vibetype.webView.evaluateJavaScript("""
window.dispatchEvent(new CustomEvent('\(name)', { detail: '\(data)' }));
""", completionHandler: nil)
}
}
func handleTrackingState() {
let status = ATTrackingManager.trackingAuthorizationStatus
let isAuthorized = status == .authorized
let state = isAuthorized ? "authorized" : "denied"
returnTrackingPermissionState(state: state)
}
}
func dispatchEventToWebView(name: String, data: String) {
DispatchQueue.main.async {
vibetype.webView.evaluateJavaScript("""
window.dispatchEvent(new CustomEvent('\(name)', { detail: '\(data)' }));
""", completionHandler: nil)
}
}
func handleTrackingState() {
let status = ATTrackingManager.trackingAuthorizationStatus
let isAuthorized = status == .authorized
let state = isAuthorized ? "authorized" : "denied"
returnTrackingPermissionState(state: state)
}
}

Copilot uses AI. Check for mistakes.
Comment on lines +289 to 295
func handleTrackingState() {
let status = ATTrackingManager.trackingAuthorizationStatus
let isAuthorized = status == .authorized
let state = isAuthorized ? "authorized" : "denied"
returnTrackingPermissionState(state: state)
}
}
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The handleTrackingState function is incorrectly placed outside the ViewController extension scope. It should be indented to be a member of the extension. Currently it's defined at the file level which makes it not accessible as an instance method and unable to call returnTrackingPermissionState.

Suggested change
func handleTrackingState() {
let status = ATTrackingManager.trackingAuthorizationStatus
let isAuthorized = status == .authorized
let state = isAuthorized ? "authorized" : "denied"
returnTrackingPermissionState(state: state)
}
}
func handleTrackingState() {
let status = ATTrackingManager.trackingAuthorizationStatus
let isAuthorized = status == .authorized
let state = isAuthorized ? "authorized" : "denied"
returnTrackingPermissionState(state: state)
}
}

Copilot uses AI. Check for mistakes.
ATTrackingManager.requestTrackingAuthorization { [weak self] status in
let isAuthorized = status == .authorized
self?.dispatchEventToWebView(
name: "tracking-permission-result",
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Event name mismatch: handleTrackingPermission() dispatches an event named "tracking-permission-result" (line 275), but the registered message handler is "tracking-permission-request" (WebView.swift line 19). This inconsistency will cause the WebView to not receive the tracking permission response correctly.

Suggested change
name: "tracking-permission-result",
name: "tracking-permission-request",

Copilot uses AI. Check for mistakes.
Comment on lines +241 to +244
func returnTrackingPermissionResult(isAuthorized: Bool) {
let result = isAuthorized ? "authorized" : "denied"
dispatchEventToWebView(name: "tracking-permission-request", data: result)
}
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The returnTrackingPermissionResult function is defined but never called. The handleTrackingPermission function directly calls dispatchEventToWebView instead of using this helper method, making it redundant code.

Suggested change
func returnTrackingPermissionResult(isAuthorized: Bool) {
let result = isAuthorized ? "authorized" : "denied"
dispatchEventToWebView(name: "tracking-permission-request", data: result)
}

Copilot uses AI. Check for mistakes.
<key>NSLocationWhenInUseUsageDescription</key>
<string>Track current location by user request</string>
<key>NSUserTrackingUsageDescription</key>
<string>This app would like to track you across apps and websites to provide personalized experiences and analytics</string>
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The tracking usage description should be more privacy-focused and less intrusive. Apple's App Store guidelines recommend being transparent about tracking purposes. Consider revising to: "We use this to personalize your experience and show relevant content" or similar, avoiding language like "track you across apps and websites" which may concern users.

Suggested change
<string>This app would like to track you across apps and websites to provide personalized experiences and analytics</string>
<string>We use this information to personalize your experience and show relevant content.</string>

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: implement app tracking transparency

4 participants