巧合的是,在您发布问题大约 3 天后,我尝试在一个专有的 SwiftUI/iOS13 项目中实现 SnapKit SDK。
不幸的是,我无法直接解决您的问题,因为 Snapchat 必须通过其 SDK 解决一些关键问题,然后才能适合使用 iOS 13 中引入的 SceneDelegate 和 AppDelegate Paradigm 进行开发。但我希望我可以为您提供帮助向处于类似困境的其他人提出问题并向他们展示我的发现。
这些是我在 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()
}
}
}
[登录CVWrapper.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
}
}
[登录ViewController.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:在设备上运行的代码 https://i.stack.imgur.com/UaE0C.gif
更多关于SceneDelegate接口链接问题:
当您不可避免地实现 SCSDKLoginClient.login() 调用时(大概是在按下 SCSDKLoginButton 时),Snapchat 将打开,假设您的应用程序已链接到 Snapchat 开发门户中,它将正确显示“授予访问权限”表。
当您接受这些权限时,Snapchat 会重定向到您的应用程序。然而,这就是您的应用程序与检索 snapchat 用户名/位莫吉之间的链接将崩溃的地方。这是因为,在新的 iOS 13 应用程序中,SceneDelegate 会处理应用程序状态更改的情况,而不是像 iOS13 之前的版本中那样由 AppDelegate 处理。因此 Snapchat 返回用户数据,但您的应用程序永远不会检索它。
[向前走]
- SnapKitSDK(当前版本为1.4.3)需要随文档一起更新。
- 我刚刚向 Snapchat 提交了一个支持问题,询问此更新何时发布,因此如果我听到更多信息,我会更新此问题。如果您正在寻找 SCSDKLoginButton() 问题的直接解决方案,我深表歉意,我只是想让您知道当前时刻存在哪些挑战。
[延伸阅读]
- Facebook 更新了他们的工具和文档以合并场景/应用程序代表。请参阅此处的步骤“5.连接您的应用程序代理和场景代理”:https://developers.facebook.com/docs/facebook-login/ios/ https://developers.facebook.com/docs/facebook-login/ios/