巧合的是,在您发布问题大约 3 天后,我尝试在一个专有的 SwiftUI/iOS13 项目中实现 SnapKit SDK。
很遗憾,我无法直接解决您的问题,因为 Snapchat 必须使用他们的 SDK 解决一些关键问题,然后才能使用 iOS 13 中引入的 SceneDelegate 和 AppDelegate 范式进行开发。但我希望我能摆脱阐明您的问题,并将我的发现介绍给处于类似困境中的任何其他人。
这些是我在 SwiftUI 中实现 SCSDKLoginKit 和 SCSDKBitmojiKit 的过程中提出的以下问题/观察:
正如您正确意识到的那样,最基本的问题是 SCSDKLoginKit 模块已过时。 SCSDKLoginClient.login() 要求调用视图符合 (UIKIT) UIViewController 类。所以我们必须使用带有 UIViewControllerRepresentable 的解决方法来充当我们的 SwiftUI UIKit 中介。
但是,根本问题与 SnapKit SDK 文档尚未更新以向开发人员提供 Snapchat Auth 和您的应用程序逻辑之间的 SceneDelegate 链接这一事实有关。因此,即使您正确实现了 SCSDKLoginButton,也并非一帆风顺!
现在直接回答您的问题,您正在尝试将 SCSDKLoginButton 包装在 UIViewControllerRepresentable 中,这是可以做到的,我相信比我更了解协调员等的人可以帮助您解决这个问题。但是,我只是想表明,在 snapchat 提供更新的 SDK 之前,您目前的努力可能会徒劳无功。
这是我的设置:
[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)
}
}
}
[运行如下]:
GIF: Code Running On Device
有关 SceneDelegate 接口链接问题的更多信息:
当您不可避免地实现 SCSDKLoginClient.login() 调用时(大概是在按下您的 SCSDKLoginButton 时),Snapchat 将打开,假设您的应用程序已链接到 Snapchat 开发门户中,它将正确显示“授予访问权限”表。
当您接受这些权限时,Snapchat 会重定向到您的应用程序。然而,这就是您的应用程序与检索 snapchat 用户名/bitmoji 之间的链接将崩溃的地方。这是因为在新的 iOS 13 应用程序中,SceneDelegate 会在您的应用程序状态更改时处理,而不是像 iOS13 之前的版本那样处理 AppDelegate。因此 Snapchat 会返回用户数据,但您的应用从不检索它。
[继续前进]
- SnapKitSDK(当前版本 1.4.3)需要随文档一起更新。
- 我刚刚向 Snapchat 提交了一个支持问题,询问此更新何时发布,因此如果我听到更多信息,我会更新此内容。如果您正在寻找 SCSDKLoginButton() 问题的直接解决方案,我们深表歉意,我只是想让您知道目前还有哪些挑战。
[延伸阅读]