Skip to content

[Bug?] .tellerConnect SwiftUI view modifier does not support multiple enrollments in one app session #2

@adboio

Description

@adboio

Issue

Summary

When using the .tellerConnect SwiftUI view modifier, it seems like some data is persisted after the Teller sheet closes for the first time, preventing future enrollments from succeeding.

Issue screen recording

Expected behavior

I am able to launch Teller Connect via the .tellerConnect view modifier any number of times within the same app session, without institution login failures.

Testing Environment

  • Teller Sandbox
  • iPhone 16 simulator on iOS 18.0

Sample implementation

@State var showTellerFlow: Bool = false

VStack {
    Text("Hello, world!")
    Button(action: {
        showTellerFlow = true
    }) {
        Text("Connect an account")
    }
}
.tellerConnect(isPresented: $showTellerFlow, config: Teller.Config(
    appId: "<my_app_id>",
    environment: .sandbox,
    selectAccount: .multiple,
    products: [.transactions]
) { reg in
    switch reg {
    case .exit:
        print("exited")

    case .enrollment(let auth):
        print("auth: \(auth)")

    default:
        print("default")
        break
    }
})

This successfully opens the Teller sheet, and allows an enrollment once.

After the first enrollment, the sheet still re-opens and everything seems to be fine, but a variety of errors are shown when attempting to sign in to any institution (see screen recording linked in summary).

❌ Workarounds that did not work

Creating a fresh Teller.Config before launching sheet

I set a state variable in my view (used like .tellerConfig: { config: tellerConfig } and reset it just before setting showTellerFlow = true. I experienced the same behavior as before.

Clearing WebKit data before launching sheet

I tried doing this to clear WebKit data before starting the Connect flow:

let dataStore = WKWebsiteDataStore.default()
let dataTypes = WKWebsiteDataStore.allWebsiteDataTypes()
dataStore.fetchDataRecords(ofTypes: dataTypes) { records in
  dataStore.removeData(ofTypes: dataTypes, for: records) {
    print("Cleared WebView data")
  }
}
showTellerFlow = true

This actually gave me a different error - no error messages showed up when trying to log in to any institution, it just didn't work... it seemingly failed silently, and just cleared out the username/password fields.

Screen recording with this different behavior

✅ My working workaround

What finally worked was dropping the SwiftUI modifier altogether and using UIKit instead.

func presentTellerManually(from controller: UIViewController) {
    let config = Teller.Config(
        appId: "<my_app_id>",
        environment: .sandbox,
        selectAccount: .multiple,
        products: [.transactions]
    ) { reg in
        switch reg {
        case .exit:
            print("exit")
            controller.dismiss(animated: true)
        case .enrollment(let auth):
            print("auth: \(auth)")
        default:
            print("default case")
        }
    }

    let tellerVC = Teller.ViewController(configuration: config)
    controller.present(tellerVC, animated: true)
}

Then, any time I need to launch the Connect flow:

import SwiftUI
import WebKit
import TellerKit

public struct MyView: View {
    let presentTeller: (UIViewController) -> Void
    
    public var body: some View {
        VStack {
            Button(action: {
                if let rootVC = UIApplication.shared.connectedScenes
                    .compactMap({ ($0 as? UIWindowScene)?.keyWindow?.rootViewController })
                    .first {
                    presentTeller(rootVC)
                }
            }) {
                Text("Connect an account")
            }
        }
    }
}

This is working totally fine - I'm able to cold-start the app, connect an account, then immediately connect another one.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions