我可以在SwiftUI上使用Snapchat SDK(SnapKit)吗?

我正在尝试将Snapkit与iOS应用程序集成,但是我想使用SwiftUI代替UIKit。我已经使用snapkit完成了必需的设置,现在我正尝试使snapchat登录按钮显示在我的应用程序中。我知道snapkit SDK是为UIKit而设计的,而不是为SwiftUI设计的,但是SwiftUI可以通过UIViewRepresentable协议来wrap UIViews into SwiftUI。我已经尝试实施此操作,但是登录按钮仍然不显示。

这是我的代码:

import SwiftUI
import UIKit
import SCSDKLoginKit

struct ContentView: View {
    var body: some View {
        snapchatLoginButtonView()
    }
}

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


struct snapchatLoginButtonView: UIViewRepresentable {

    func makeCoordinator() -> Coordinator {
        Coordinator()
    }

    func makeUIView(context: Context) -> SCSDKLoginButton {
        let s = SCSDKLoginButton()
        s.delegate = context.coordinator

        return s
    }

    func updateUIView(_ uiView: SCSDKLoginButton,context: Context) {
    }

    class Coordinator: NSObject,SCSDKLoginButtonDelegate {
        func loginButtonDidTap() {
        }
    }
}

我感觉我在SCSDKLoginButton中缺少一些东西,但不确定是什么,所以这里有文件SCSDKLoginButton.h供参考。任何帮助将不胜感激!

//
//  SCSDKLoginButton.h
//  SCSDKLoginKit
//
//  Copyright © 2018 snap,Inc. All rights reserved.
//

#import <UIKit/UIKit.h>

@protocol SCSDKLoginButtonDelegate
- (void)loginButtonDidTap;
@end

@interface SCSDKLoginButton : UIView

@property (nonatomic,weak,nullable) id<SCSDKLoginButtonDelegate> delegate;

- (instancetype)initWithCompletion:(nullable void (^)(BOOL success,NSError *error))completion NS_DESIGNATED_INITIALIZER;

@end
huanwujun 回答:我可以在SwiftUI上使用Snapchat SDK(SnapKit)吗?

巧合的是,在您发布问题大约三天后,我尝试在独家SwiftUI / iOS13项目中实现SnapKit SDK。

不幸的是,我无法直接解决您的问题,因为在适合iOS 13中引入的SceneDelegate和AppDelegate范式进行开发之前,Snapchat必须使用其SDK解决一些关键问题,但是我希望我能摆脱根据您的问题,向遇到类似困境的任何人介绍我的发现。

这些是我在SwiftUI中实现SCSDKLoginKit和SCSDKBitmojiKit时遇到的以下问题/观察:

  • 最基本的问题是,正如您正确认识到的那样,SCDSKLoginKit模块已过时。 SCSDKLoginClient.login()要求调用视图符合(UIKIT)UIViewController类。因此,我们必须将变通方法与UIViewControllerRepresentable一起使用,以充当我们的SwiftUI UIKit中介。

  • 但是,根本问题涉及以下事实:尚未更新SnapKit SDK文档,无法为开发人员提供Snapchat Auth和您的应用程序逻辑之间的SceneDelegate链接。因此,即使您正确实现了SCSDKLoginButton,它也不是一帆风顺的!

现在直接回答您的问题,您正在尝试将SCSDKLoginButton包装在UIViewControllerRepresentable中,这是可以做到的,并且我确定比我自己更了解协调器等知识的人可以为您提供帮助。但是,我只是想表明,在gmail提供了更新的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 Dev Portal中,它将正确显示“授权访问”表。

当您接受这些权限时,Snapchat会重定向到您的应用程序。但是,这是您的应用程序与检索gmail用户名/ bitmoji之间的链接将断开的地方。这是由于以下事实:在新的iOS 13应用程序中,当应用程序状态更改时,SceneDelegate会处理,而不是像iOS13之前的版本中的AppDelegate。因此,Snapchat返回了用户数据,但您的应用程序从未检索到它。

[前进]

  • SnapKitSDK(当前版本1.4.3)需要与文档一起更新。
  • 我刚刚向Snapchat提交了一个支持问题,询问该更新何时发布,以便在听到更多信息时进行更新。抱歉,如果您正在寻找直接解决SCSDKLoginButton()问题的方法,我只想让您知道当前这个时刻所面临的挑战。

[进一步阅读]

,

@ Stephen2697正确地指出,尚未为iOS 13构建快照sdk,这是由于SceneDelegate现在正在处理oauth重定向而不是AppDelegate。我想出了一种解决方法,可以在场景委托中使用SCSDKLoginClient.application()方法(为appdelegate创建)。这是代码,将其添加到场景委托中,传递给Snapchat登录名的完成处理程序将运行:

func scene(_ scene: UIScene,openURLContexts URLContexts: Set<UIOpenURLContext>) {
    for urlContext in URLContexts {
        let url = urlContext.url
        var options: [UIApplication.OpenURLOptionsKey : Any] = [:]
        options[.openInPlace] = urlContext.options.openInPlace
        options[.sourceApplication] = urlContext.options.sourceApplication
        options[.annotation] = urlContext.options.annotation
        SCSDKLoginClient.application(UIApplication.shared,open: url,options: options)
    }
}

只要未出现登录按钮,请确保将完成处理程序添加到SCSDKLoginButton实例,否则它将不起作用。像这样:

let s = SCSDKLoginButton { (success,error) in
        //handle login
    }
本文链接:https://www.f2er.com/2468431.html

大家都在问