microsoft / appcenter-sdk-apple

Development repository for the App Center SDK for iOS, macOS and tvOS.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to force flushing analytics events _right now_?

MrMage opened this issue · comments

Is your feature request related to a problem? Please describe.
I'd like to know how many of our users abandon our Mac app during onboarding. But if they simply quit the app with Cmd-Q and never relaunch it, App Center doesn't have an opportunity to upload the analytics event that indicates this case to the server, even when the event has the .critical flag attached.

Describe the solution you'd like
Something akin to a forceFlush method on MSACAnalytics.

Describe alternatives you've considered
It might be possible to avoid this by delaying quitting of the app for ~6-10 seconds, but that's unexpected to the user and thus bad UX.

Note: this might be related to microsoft/appcenter#1745.

Hey @MrMage , thank you for proposing this feature request!
This request applies to many platforms, so I'm closing this issue as a duplicate and reopening the related one from the main repository where you can track updates.

FYI, this is the workaround I am using on the Apple version of the framework now:

	private func forceAppCenterCriticalFlush() {
		// Try ensuring that App Center uploads its logs before the application terminates.
		// App Center does not provide a public API for this, so we have to use private APIs.
		// Tracking issues:
		//
		//  - https://github.com/microsoft/appcenter/issues/1745
		//  - https://github.com/microsoft/appcenter-sdk-apple/issues/2479
		let sharedInstanceSelector = NSSelectorFromString("sharedInstance")
		if Analytics.responds(to: sharedInstanceSelector) {
			let criticalChannelUnitSelector = NSSelectorFromString("criticalChannelUnit")
			if let analyticsSharedInstance = Analytics.perform(sharedInstanceSelector)?.takeUnretainedValue(),
			   analyticsSharedInstance.responds(to: criticalChannelUnitSelector) {
				let flushQueueSelector = NSSelectorFromString("flushQueue")
				if let criticalChannelUnit = analyticsSharedInstance.perform(criticalChannelUnitSelector)?.takeUnretainedValue(),
				   criticalChannelUnit.responds(to: flushQueueSelector) {
					_ = criticalChannelUnit.perform(flushQueueSelector)
				}
			}
		}
	}