Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SwiftUI screen size handling on iOS #238

Merged
merged 1 commit into from
Nov 8, 2024
Merged

Conversation

terabyte128
Copy link
Contributor

UIScreen.main is deprecated and calling it appears to reset the accent color of the UI.

💡 Motivation and Context

See #237

💚 How did you test it?

I verified that the change fixes the accent color issue. I further verified that calling UIScreen.main actually causes the issue in the first place, by inserting the following into my code and observing the accent color change:

let x = UIScreen.main.bounds.width

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

UIScreen.main is deprecated and calling it appears to reset
the accent color of the UI.

Fixes PostHog#237
Copy link
Contributor

@ioannisj ioannisj left a comment

Choose a reason for hiding this comment

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

Hey @terabyte128! Thanx for this. I was not aware of this scenario. Of course I'd be happy to move away from a deprecated call.

I replicated locally as well and here’s what I observed for some more context:

  • This issue only appears when accessing UIScreen.main within the app's init() method. However, if I use a UIApplicationDelegateAdaptor and access UIScreen.main from a delegate, it doesn’t seem to trigger the issue. This could be due to differences in the SwiftUI and UIKit lifecycles.
  • Likewise, since PH only accesses UIScreen.main when building event properties, the issue only surfaces when capturing an event directly in the app's init(). Capturing an event in AppDelegate doesn’t trigger it.

@ioannisj ioannisj merged commit 22d9eb1 into PostHog:main Nov 8, 2024
4 of 5 checks passed
@@ -123,8 +123,10 @@ class PostHogContext {
var properties: [String: Any] = [:]

#if os(iOS) || os(tvOS)
properties["$screen_width"] = Float(UIScreen.main.bounds.width)
properties["$screen_height"] = Float(UIScreen.main.bounds.height)
if let screen = UIApplication.shared.windows.first?.screen {
Copy link

Choose a reason for hiding this comment

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

This change means that all iOS/tvOS consumers receive a warning unless we're only calling into PostHog from the main thread. If a client's logging system runs off of main, accessing UIApplication.shared will cause warnings in Xcode. Not sure if that's a priority for y'all, but figured I'd raise.

Copy link
Contributor

Choose a reason for hiding this comment

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

hey @dfed, yeah that is indeed true. Hopping and blocking to main thread for every single event is not realistic so we should probably promote these to static properties. NSScreen.main will probably need to stay as dynamic context since it represents the screen of the currently focused window which can change, but I think for iOS/tvOS it's probably safe to calculate this once. Let me think about it a bit and I'll get back soon

Copy link
Member

Choose a reason for hiding this comment

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

We can check if the captured event is on the main thread and only do the thread jumping if needed to reduce the perf impact as well.
UIApplication.shared.windows is also deprecated so the change from A to B didn't make sense IMO.

Copy link
Member

Choose a reason for hiding this comment

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

PostHogReplayIntegration.getCurrentWindow() is likely the correct way right now, we should move getCurrentWindow() out of PostHogReplayIntegration and reuse across the SDK, I see more places using UIApplication.shared that is just trying to find the active window, eg UIViewController.activeController and UIApplication.ph_currentWindow

Copy link
Contributor

Choose a reason for hiding this comment

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

PostHogReplayIntegration.getCurrentWindow() is likely the correct way right now, we should move getCurrentWindow() out of PostHogReplayIntegration and reuse across the SDK, I see more places using UIApplication.shared that is just trying to find the active window, eg UIViewController.activeController and UIApplication.ph_currentWindow

Agreed. For capturing events we probably want to skip scene state checks

Copy link
Contributor

Choose a reason for hiding this comment

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

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.

4 participants