wordpress-mobile / WordPress-iOS

WordPress for iOS - Official repository
http://ios.wordpress.org/
GNU General Public License v2.0
3.69k stars 1.12k forks source link

Blank Me screen when logged in with Self hosted #12809

Closed yaelirub closed 5 years ago

yaelirub commented 5 years ago

Expected behavior

"Me" screen should display App settings , Help & Support and Log In options

Actual behavior

"Me" screen is blank when logged in with self hosted

Steps to reproduce the behavior

  1. Log out of the app
  2. Login with self hosted site
  3. Go to "Me" screen.
  4. See blank screen
  5. move the app to background
  6. Return to the app and see "Me" screen with options
Tested on [device], iOS [version], WPiOS [version]

iPhone 7, iOS 13.2, WPiOS 13.5 20191030_103942

/hat tip @malinajirka

designsimply commented 5 years ago

Tested and confirmed that the profile screen is blank after a self-hosted login using WPiOS 13.5.0.2 beta (TestFlight) on iPhone 6S iOS 13.1.3 and remains blank if you force close and re-open the app but that the screen displays normally if you put the app in the background and then bring it back up again.

I also found this happens with WPiOS 13.4.0.1 (TestFlight) and here are the app logs from that session:

2019-10-30 12:33:55:465 WPAnalytics session started
2019-10-30 12:33:55:469 ===========================================================================
2019-10-30 12:33:55:469 Launching WordPress for iOS 13.4 (13.4.0.1)...
2019-10-30 12:33:55:469 Crash count: 0
2019-10-30 12:33:55:469 Debug mode:  Production
2019-10-30 12:33:55:469 Extra debug: NO
2019-10-30 12:33:55:470 Device model: iPhone 6s (iPhone8,1)
2019-10-30 12:33:55:470 OS:        iOS, 13.1.3
2019-10-30 12:33:55:477 Language:  en-US
2019-10-30 12:33:55:478 APN token: 
2019-10-30 12:33:55:478 Launch options: [:]
2019-10-30 12:33:55:479 wp.com account: <none>
All accounts and blogs:
No account/blogs configured on device
2019-10-30 12:33:55:479 ===========================================================================
2019-10-30 12:33:55:497 Zendesk Enabled: true
2019-10-30 12:33:55:499 User-Agent set to: Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 wp-iphone/13.4
2019-10-30 12:33:55:677 didFinishLaunchingWithOptions state: UIApplicationState
2019-10-30 12:33:55:686 πŸ”΅ Tracked: login_accessed
2019-10-30 12:33:55:859 Error while removing Notification Content Extension OAuth token: Error Domain=SFHFKeychainUtilsErrorDomain Code=-25300 "(null)"
2019-10-30 12:33:55:860 Error while removing Notification Service Extension OAuth token: Error Domain=SFHFKeychainUtilsErrorDomain Code=-25300 "(null)"
2019-10-30 12:33:55:867 Could not sync sites: Optional(Error Domain=WordPressKit.WordPressComRestApiError Code=2 "An active access token must be used to query information about the current user." UserInfo={WordPressComRestApiErrorCodeKey=authorization_required, WordPressComRestApiErrorMessageKey=An active access token must be used to query information about the current user., NSLocalizedDescription=An active access token must be used to query information about the current user.})
2019-10-30 12:33:55:871 <WordPress.WordPressAppDelegate: 0x280997380> applicationDidBecomeActive(_:)
2019-10-30 12:33:55:875 πŸ”΅ Tracked: application_installed
2019-10-30 12:33:55:883 πŸ”΅ Tracked: application_opened
2019-10-30 12:33:55:994 πŸ”΅ Tracked: login_prologue_viewed
2019-10-30 12:33:56:073 <WordPress.WordPressAppDelegate: 0x280997380> applicationWillResignActive(_:)
2019-10-30 12:33:56:248 πŸ”΅ Tracked: searchads_attribution_detail_received <iad_adgroup_id: 1234567890, iad_adgroup_name: AdGroupName, iad_attribution: true, iad_campaign_id: 1234567890, iad_campaign_name: CampaignName, iad_click_date: 2019-10-30T18:33:56Z, iad_conversion_date: 2019-10-30T18:33:56Z, iad_conversion_type: Download, iad_country_or_region: US, iad_creativeset_id: 1234567890, iad_creativeset_name: CreativeSetName, iad_keyword: Keyword, iad_keyword_id: KeywordID, iad_keyword_matchtype: Broad, iad_lineitem_id: 1234567890, iad_lineitem_name: LineName, iad_org_id: 1234567890, iad_org_name: OrgName, iad_purchase_date: 2019-10-30T18:33:56Z>
2019-10-30 12:33:58:211 <WordPress.WordPressAppDelegate: 0x280997380> applicationDidBecomeActive(_:)
2019-10-30 12:34:01:164 πŸ”΅ Tracked: login_url_form_viewed
2019-10-30 12:34:07:736 Assume the given url is the home page and XML-RPC sits at /xmlrpc.php
2019-10-30 12:34:11:651 πŸ”΅ Tracked: login_username_password_form_viewed
2019-10-30 12:34:13:456 TracksService sendQueuedEvents completed. Sent 7 events.
2019-10-30 12:34:14:634 Assume the given url is the home page and XML-RPC sits at /xmlrpc.php
2019-10-30 12:34:15:619 Loading Stats for the following blog: https://honest-spiders.jurassic.ninja
2019-10-30 12:34:15:677 πŸ”΅ Tracked: self_hosted_blog_added
2019-10-30 12:34:15:684 πŸ”΅ Tracked: signed_in <dotcom_user: 0>
2019-10-30 12:34:15:800 Could not sync sites: Optional(Error Domain=WordPressKit.WordPressComRestApiError Code=2 "An active access token must be used to query information about the current user." UserInfo={WordPressComRestApiErrorMessageKey=An active access token must be used to query information about the current user., NSLocalizedDescription=An active access token must be used to query information about the current user., WordPressComRestApiErrorCodeKey=authorization_required})
2019-10-30 12:34:16:306 πŸ”΅ Tracked: login_epilogue_viewed
2019-10-30 12:34:16:973 Failed updating plans: (null)
2019-10-30 12:34:16:973 Failed checking domain credit for site https://honest-spiders.jurassic.ninja: Error Domain=PlanService Code=0 "Unable to update plan prices. There is a problem with the supplied blog." UserInfo={NSLocalizedDescription=Unable to update plan prices. There is a problem with the supplied blog.}
2019-10-30 12:34:17:048 Failed updating plans: (null)
2019-10-30 12:34:17:048 Failed checking domain credit for site https://honest-spiders.jurassic.ninja: Error Domain=PlanService Code=0 "Unable to update plan prices. There is a problem with the supplied blog." UserInfo={NSLocalizedDescription=Unable to update plan prices. There is a problem with the supplied blog.}
2019-10-30 12:34:18:276 Failed checking muti-author status for blog https://honest-spiders.jurassic.ninja: Error Domain=WordPressKit.WordPressOrgXMLRPCApiError Code=0 "(null)" UserInfo={WordPressOrgXMLRPCApiErrorKeyData={length = 190, bytes = 0x3c68746d 6c3e0d0a 3c686561 643e3c74 ... 2f68746d 6c3e0d0a }, WordPressOrgXMLRPCApiErrorKeyStatusCode=503, WordPressOrgXMLRPCApiErrorKeyDataString=<html>

<head><title>503 Service Temporarily Unavailable</title></head>

<body>

<center><h1>503 Service Temporarily Unavailable</h1></center>

<hr><center>nginx</center>

</body>

</html>

}
2019-10-30 12:34:19:066 πŸ”΅ Tracked: me_tab_accessed
2019-10-30 12:34:25:364 <WordPress.WordPressAppDelegate: 0x280997380> applicationWillResignActive(_:)
2019-10-30 12:34:25:702 <WordPress.WordPressAppDelegate: 0x280997380> applicationDidEnterBackground(_:)
2019-10-30 12:34:25:720 πŸ”΅ Tracked: application_closed <last_visible_screen: Me, time_in_app: 30>
2019-10-30 12:34:25:955 TracksService sendQueuedEvents completed. Sent 4 events.
2019-10-30 12:34:27:435 <WordPress.WordPressAppDelegate: 0x280997380> applicationWillEnterForeground(_:)
2019-10-30 12:34:27:754 <WordPress.WordPressAppDelegate: 0x280997380> applicationDidBecomeActive(_:)
2019-10-30 12:34:27:772 πŸ”΅ Tracked: application_opened
2019-10-30 12:34:27:783 πŸ”΅ Tracked: me_tab_accessed
2019-10-30 12:34:27:809 checkAppleIDCredentialState: Apple ID state: 1
2019-10-30 12:34:29:981 πŸ”΅ Tracked: support_opened

@ScoutHarris could you look into this?

ScoutHarris commented 5 years ago

@aerych would this possibly be related to the token changes you made recently? I did see you fixed some on https://github.com/wordpress-mobile/WordPress-iOS/pull/12546. I wasn't sure if this is somehow related or not.

ScoutHarris commented 5 years ago

Also, I did confirm it happens in release/13.5 and develop, so it's still an issue.

aerych commented 5 years ago

would this possibly be related to the token changes you made recently? I did see you fixed some on #12546. I wasn't sure if this is somehow related or not

It shouldn't be related. Self-hosted signups don't create accounts or interact with auth tokens. For a quick sanity check I reproduced the glitch in the develop branch, then rolled back the changes in #12546 and could still reproduce the blank screen.

aerych commented 5 years ago

Rotating a device when the MeViewController is blank will cause it to refresh and you'll see the correct content.

yaelirub commented 5 years ago

Rotating a device when the MeViewController is blank will cause it to refresh and you'll see the correct content.

In that case my guess would be that it's due to the changes in timing of traitCollectionDidChange call since iOS 13.0. (used to be called after adding the view to the hierarchy and now its called before). Maybe moving the reloadViewModel() from traitCollectionDidChange to viewWillLayoutSubviews will fix this. wdyt, @ScoutHarris ?

aerych commented 5 years ago

In that case my guess would be that it's due to the changes in timing of traitCollectionDidChange call since iOS 13.0. (used to be called after adding the view to the hierarchy and now its called before).

Interesting!

Maybe moving the reloadViewModel() from traitCollectionDidChange to viewWillLayoutSubviews will fix this

Should it remain in traitCollectionDidChange in case there was a reason to refresh during rotation, or split screen multitasking adjustment, etc. but call reloadViewModel from viewWillAppear? Wondering if willLayoutSubviews might be a tad aggressive?

aerych commented 5 years ago

Tested on iOS 11.4 and I was unable to reproduce the blank screen on that OS version.

yaelirub commented 5 years ago

From Apple:

Trait environments, such as views and view controllers, now have their traitCollection property populated with traits during initialization. These initial traits represent a prediction of the ultimate traits that the trait environment will receive when it gets added to the hierarchy. Because the traits that are populated during initialization are just a prediction, they might differ from the traits that are received once actually in the hierarchy. Therefore, when possible you should wait to perform work that uses the traitCollection until the view, or view controller’s view, has moved into the hierarchy β€” meaning window returns a non-nil value β€” so that you don’t have to throw away any work done using the predicted traits if the actual traits are different. The best time to use the traitCollection is during layout, such as inside layoutSubviews(), viewWillLayoutSubviews(), or viewDidLayoutSubviews().

ScoutHarris commented 5 years ago

Thanks @aerych @yaelirub ! I'll take a look at the traitCollection business.

aerych commented 5 years ago

@yaelirub Hmm... That sounds like it's specific to using the traitCollection? (Is there a link to the doc?) Doesn't seem like we're doing that. Rather, just refreshing the tableView when the collection changed (which I guess still happens).

Either way, my only real concern was whether calling reloadViewModel from within willLayoutSubviews could somehow spam the refresh calls. I'm good as long as we avoid that. :)

yaelirub commented 5 years ago

@aerych

That sounds like it's specific to using the traitCollection? (Is there a link to the doc?)

https://developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes

Either way, my only real concern was whether calling reloadViewModel from within willLayoutSubviews could somehow spam the refresh calls.

I'm sorry, I didn't look into reloadViewModel but if it draws data or does some other heavy lifting, a different method would be better.

ScoutHarris commented 5 years ago

@aerych you have a point. On rotation, viewWillLayoutSubviews is being called multiple times. I'll see if I can find a more appropriate time/place to update the view.

ScoutHarris commented 5 years ago

call reloadViewModel from viewWillAppear?

FWIW, reloadViewModel is being called in viewWillAppear, but via the updateUserDetails completion block.

    service.updateUserDetails(for: account, success: { [weak self] in
        self?.reloadViewModel()
    }, failure: { error in
        DDLogError(error.localizedDescription)
    })
ScoutHarris commented 5 years ago

Turns out, it was a pesky guard returning before reloadViewModel was called:

    fileprivate func refreshAccountDetails() {
        guard let account = defaultAccount() else { return }
        let context = ContextManager.sharedInstance().mainContext
        let service = AccountService(managedObjectContext: context)
        service.updateUserDetails(for: account, success: { [weak self] in
            self?.reloadViewModel()
        }, failure: { error in
            DDLogError(error.localizedDescription)
        })
    }

Throw in a reloadViewModel before the return and magic happens.

That was done 4 years ago. I'm not sure why this is problematic now, (well, besides everything @yaelirub said) but this should do the trick.