amplitude / Amplitude-Swift

Native iOS/tvOS/macOS/watchOS SDK
MIT License
26 stars 20 forks source link

fix: set application as a computed property #189

Closed PouriaAmini closed 2 months ago

PouriaAmini commented 2 months ago

Summary

This PR fixes the issue with the application instance being nil if Amplitude is initialized before the app starts.

Checklist

crleona commented 2 months ago

We generally only will initialize Amplitude in didFinishLaunching where the previous logic has not had issues. Accessing Amplitude before that is an error. What specifically does this solve?

PouriaAmini commented 2 months ago

We generally only will initialize Amplitude in didFinishLaunching where the previous logic has not had issues. Accessing Amplitude before that is an error. What specifically does this solve?

In the sample AmplitudeSwiftUIExample app in the SDK, Amplitude.testInstance is configured and plugins are added within the init() method. This happens before the App's body is created and the UI starts running, which results in application = nil. Is this a bug in the sample app? I'm suspecting that some customers might take the same approach as well.

@main
struct AmplitudeSwiftUIExampleApp: App {
    let persistenceController = PersistenceController.shared

    // Overriding the initializer in the App in order to config amplitude
    init() {
        Amplitude.testInstance.add(plugin: IDFACollectionPlugin())
        Amplitude.testInstance.add(plugin: LocationPlugin())
        // add the trouble shooting plugin for debugging
        Amplitude.testInstance.add(plugin: TroubleShootingPlugin())
        Amplitude.testInstance.add(plugin: FilterPlugin())

        Amplitude.experimentClient.fetch(user: nil, completion: nil)
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.managedObjectContext, persistenceController.container.viewContext)
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
                    let status = ATTrackingManager.trackingAuthorizationStatus
                    if status == .notDetermined {
                        askForPermission()
                    }
                }
        }
    }
...
extension Amplitude {
    static var testInstance = Amplitude(
        configuration: Configuration(
            apiKey: "API-KEY",
            logLevel: LogLevelEnum.DEBUG,
            callback: { (event: BaseEvent, code: Int, message: String) -> Void in
                print("eventcallback: \(event), code: \(code), message: \(message)")
            },
            trackingOptions: TrackingOptions().disableTrackCarrier().disableTrackDMA(),
            flushEventsOnClose: true,
            minTimeBetweenSessionsMillis: 15000,
            defaultTracking: DefaultTrackingOptions(userInteractions:true)
        )
    )
...