5

I'm trying to make a simple swiftui app using qualtrics and I'm trying to use a uiviewrepresentable to make it work

@main
struct QualtricsPocApp: App {
var body: some Scene {
    WindowGroup {
        ContentView()
    }
}

init() {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            // i have the actual intercept id's here i just removed them
            Qualtrics.shared.initializeProject(brandId: "brand", projectId: "proj", extRefId: "ref", completion: { (myInitializationResult) in print(myInitializationResult);})

            return true

      }
   }
}


struct QualtricsViewRep: UIViewControllerRepresentable {

typealias UIViewControllerType = UIViewController

func makeUIViewController(context: Context) -> UIViewController {
    let vc = UIViewController()
    Qualtrics.shared.evaluateProject { (targetingResults) in
        for (interceptID, result) in targetingResults {
            if result.passed() {
                let displayed = Qualtrics.shared.display(viewController: self, autoCloseSurvey: true)
            }
        }
    }
}

on let displayed = ... I keep getting the error "Cannot convert value of type 'QualtricsViewRep' to expected argument type 'UIViewController'", how can I return this code as a UIViewController to use in a swiftui app, or is there some other way I should be approaching this?

doesntpost
  • 81
  • 3

2 Answers2

1

Sample Qualtrics SwiftUI App

I had to implement this for work so I decided to share my solution.

QualtricsDemoApp

import SwiftUI
import Qualtrics

@main
struct QualtricsDemoApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .task {
                    Qualtrics.shared.initializeProject(brandId: "BRAND_ID", projectId: "PROJECT_ID", extRefId: "EXT_REF_ID") { myInitializationResult in
                        print(myInitializationResult)
                    }
                }
        }
    }
}

ContentView

import SwiftUI
import Qualtrics

struct ContentView: View {
    @State private var showFeedback = false
    var body: some View {
        VStack {
            Button("Show Qualtrics Feedback") {
                showFeedback.toggle()
            }
            
            if showFeedback {
                QualtricsFeedbackRepresentable()
            }
        }
        .font(.title)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct QualtricsFeedbackRepresentable: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIViewController {
        let vc = UIViewController()
        Qualtrics.shared.evaluateProject { (targetingResults) in
            for (_, result) in targetingResults {
                if result.passed() {
                    Qualtrics.shared.display(viewController: vc)
                }
            }
        }
        return vc
    }
    
    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
    }
}

Showing Qualtrics Feedback form

Now I just have to figure out why it's not in English.

Mark Moeykens
  • 15,915
  • 6
  • 63
  • 62
0

Unfortunately I don't have Qualtrics installed, but I have worked with it within UIKit. My assumption here is that you will need to create an instance of a UIViewController. This view controller is what the qualtrics view will present itself over.

Ultimately, you will return the view controller which contains the qualtrics view presented over it.

struct QualtricsViewRep: UIViewControllerRepresentable {
     typealias UIViewControllerType = UIViewController

     func makeUIViewController(context: Context) -> UIViewController {
         let vc = UIViewController()
            Qualtrics.shared.evaluateProject { (targetingResults) in
                for (interceptID, result) in targetingResults {
                    if result.passed() {
                         DispatchQueue.main.async {
                            let vc = UIViewController()
                            let displayed = Qualtrics.shared.display(viewController: vc, autoCloseSurvey: true)
                         }
                    }
                }
            }
         return vc
     }

     func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
         // your code here
     }
}
nickreps
  • 903
  • 8
  • 20
  • this compiles but it doesnt actually open the qualtrics webview – doesntpost Sep 23 '22 at 14:17
  • @davisdoesntpost There are a handful of other factors that could be playing into this. Is the qualtrics project initializing successfully? When calling the evaluate intercept method, are all criteria met for presentation of qualtrics to occur? Initialization on the UIKit side happens within the app delegate. Where are you initializing the qualtrics project? – nickreps Sep 23 '22 at 15:26
  • I have that in the App initializer – doesntpost Sep 23 '22 at 15:36
  • I updated my answer to handle the presentation async. Give that a try. If still not working, could you please post your qualtrics initialization code? – nickreps Sep 23 '22 at 15:54
  • still didnt work,i added the init to the intitial post – doesntpost Sep 23 '22 at 16:08
  • I see. The SwiftUI Iifecycle does not use the didFinishLaunchingWithOptions function. Can you please remove that? Keep the rest of the init the same. Addiotnally, the init function needs to be moved into your app struct, above the var body: some Scene portion. If done correctly, you should see the qualtrics initialization in your console. It will tell you if there was an error during init or not. – nickreps Sep 23 '22 at 17:27