Coincidentally I attempted implementing the SnapKit SDK in an exclusive SwiftUI/ iOS13 project about 3 days after you posted your Issue.
Unfortunately I can't directly resolve your issue as there are a few key issues which Snapchat has to address with their SDK before it is suitable for development with the SceneDelegate & AppDelegate Paradigm introduced in iOS 13. But I hope I can shed light on your question and present my findings to anyone else who is in a similar predicament.
These are the following issues/ observations I made on my quest of Implementing SCSDKLoginKit & SCSDKBitmojiKit in SwiftUI:
The most basic issue is that the SCSDKLoginKit Module is outdated, As you correctly realised. SCSDKLoginClient.login() requires the calling view to conform to the (UIKIT) UIViewController class. So we must use the workaround with a UIViewControllerRepresentable to act as our SwiftUI <-> UIKit intermediary.
However the fundamental issue relates to the fact that the SnapKit SDK documentation has not been updated to give developers a SceneDelegate link between Snapchat Auth and Your app's logic. So even if you implemented your SCSDKLoginButton correctly it is not smooth sailing!
Now to directly answer your question, You are attempting to wrap a SCSDKLoginButton in a UIViewControllerRepresentable which can be done and I'm sure someone with better knowledge of coordinators etc than myself can help you with that. However I just wanted to show that your efforts at the moment may be fruitless until snapchat provides an updated SDK.
Here is my setup:
[ContentView.swift]
import SwiftUI
struct ContentView: View {
@State private var isPresented = false
var body: some View {
Button("Snapchat Login Button") { self.isPresented = true}
.sheet(isPresented: $isPresented) {
LoginCVWrapper()
}
}
}
[LoginCVWrapper.swift]
import SwiftUI
import UIKit
import SCSDKLoginKit
struct LoginCVWrapper: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
return LoginViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
//Unused in demonstration
}
}
[LoginViewController.swift]
import UIKit
import SCSDKLoginKit
class LoginViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
performLogin() //Attempt Snap Login Here
}
//Snapchat Credential Retrieval Fails Here
private func performLogin() {
//SCSDKLoginClient.login() never completes once scene becomes active again after Snapchat redirect back to this app.
SCSDKLoginClient.login(from: self, completion: { success, error in
if let error = error {
print("***ERROR LOC: manualTrigger() \(error.localizedDescription)***")
return
}
if success {
self.fetchSnapUserInfo({ (userEntity, error) in
print("***SUCCESS LOC: manualTrigger()***")
if let userEntity = userEntity {
DispatchQueue.main.async {
print("SUCCESS:\(userEntity)")
}
}
})
}
})
}
private func fetchSnapUserInfo(_ completion: @escaping ((UserEntity?, Error?) -> ())){
let graphQLQuery = "{me{displayName, bitmoji{avatar}}}"
SCSDKLoginClient
.fetchUserData(
withQuery: graphQLQuery,
variables: nil,
success: { userInfo in
if let userInfo = userInfo,
let data = try? JSONSerialization.data(withJSONObject: userInfo, options: .prettyPrinted),
let userEntity = try? JSONDecoder().decode(UserEntity.self, from: data) {
completion(userEntity, nil)
}
}) { (error, isUserLoggedOut) in
completion(nil, error)
}
}
}
[This Runs as follows]:
GIF: Code Running On Device
More on the SceneDelegate interface link issue:
When you inevitably implement the SCSDKLoginClient.login() call (presumably when your SCSDKLoginButton is pressed), Snapchat will open, it will present the "grant access" sheet correctly assuming your app is linked in the Snapchat Dev Portal.
When you accept these permissions, Snapchat redirects to your application. However this is where the link between your app and retrieving a snapchat username/ bitmoji will breakdown. This is due to the fact that in new iOS 13 apps, the SceneDelegate handles when your application states change not the AppDelegate as in pre iOS13 versions. Therefore Snapchat returns the user data but your app never retrieves it.
[Going Forward]
- The SnapKitSDK (currently version 1.4.3) needs to be updated along with the documentation.
- I have just submitted a support question to Snapchat asking when this update will come so I will update this if I hear more. Apologies if you were looking for a direct solution to your SCSDKLoginButton() issue, I just wanted you to know what challenges lie beyond it at this current moment in time.
[Further Reading]