Swiftyinsta: WebLogin no funciona

Creado en 22 jul. 2019  ·  16Comentarios  ·  Fuente: TheM4hd1/SwiftyInsta

Después de la actualización, el weblogin del pod no está compilado en la versión ios 10.
Cuando cambio a la versión 11.0 de ios, dice:

  • 'loginDelegate' está en desuso: use InstagramLoginWebView propiedades en su lugar.
  • 'InstagramLoginWebViewDelegate' está en desuso: use las propiedades de cierre InstagramLoginWebViewProtocol en su lugar.

Cuando cambié InstagramLoginWebViewDelegate a InstagramLoginWebViewProtocol:

  • 'InstagramLoginWebViewProtocol' requiere que 'LoginViewController' herede de 'UIView'

Mis códigos:

class LoginViewController: UIViewController {

var loginWebView: InstagramLoginWebView! = nil

override func viewDidLoad() {
    super.viewDidLoad()

    loginWebView = InstagramLoginWebView(frame: self.view.frame)
    self.view.addSubview(loginWebView!)
    loginWebView?.loginDelegate = self **-- Cannot assign value of type 'LoginViewController' to type 'InstagramLoginWebViewDelegate?'**
    self.loginWebView?.loadInstagramLogin(isNeedPreloadForCookieSync: true) **--Argument passed to call that takes no arguments**
}

}

extensión LoginViewController: InstagramLoginWebViewProtocol { - 'InstagramLoginWebViewProtocol' requiere que 'LoginViewController' herede de 'UIView'

func userLoggedSuccessfully() {
    print("User Logged Successfully")

    DispatchQueue.main.async {
        self.loginWebView.removeFromSuperview()
    }

}
help wanted

Todos 16 comentarios

Hola @effecttwins 😊

InstagramLoginWebView ha cambiado mucho en la última actualización, y el soporte para iOS 10.* tuvo que ser eliminado debido a incompatibilidad.
Ya no se sugiere usar loginDelegate , aunque sigue siendo funcional.
Todo lo que tiene que hacer para obtener el comportamiento al que está acostumbrado es establecer las siguientes propiedades en su loginWebView :

  • didReachEndOfLoginFlow es un _closure_ llamado como antes redirected .
  • didSuccessfullyLogIn es un _closure_ que reemplaza el userLoggedSuccessfully() del _delegate_.
  • completionHandler es un _closure_ que reemplaza el webViewFinishedToLoadUser(sessionChache:handler:) del _delegate_

Este es el código actualizado para 1.7.* .

class LoginViewController: UIViewController {
    var loginWebView: InstagramLoginWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        loginWebView = InstagramLoginWebView(frame: self.view.frame,
                                             didSuccessfullyLogIn: { [weak self] in DispatchQueue.main.async { self?.loginWebView.removeFromSuperview() }},
                                             completionHandler: { sessionCache, handler in /* do whaterver you need to */ })
        view.addSubview(loginWebView)
        loginWebView.loadInstagramLogin()
    }
}

así que cuando cambio la extensión InstagramLoginWebViewDelegate a InstagramLoginWebViewProtocol y dice: 'InstagramLoginWebViewProtocol' requiere que 'LoginViewController' herede de 'UIView'

Código:

extensión LoginViewController: InstagramLoginWebViewDelegate {

func userLoggedSuccessfully() {
    print("User Logged Successfully")

}

func webViewFinishedToLoadUser(sessionCache: SessionCache, handler: APIHandlerProtocol) {
    print("Loading user with sessioncache is successful")

    do{
        let encoder = JSONEncoder()
        let data = try encoder.encode(sessionCache)

        let sessionCacheString = String(data: data, encoding: .utf8)

    }catch {
        print("Whoops, an error occured: \(error)")
    }


}

Nunca se debe conformar a InstagramLoginWebViewProtocol .
Mi culpa por no marcarlo internal . Me disculpo.

Este es todo el código que necesita. No InstagramLoginWebViewProtocol . No InstagramLoginWebViewDelegate .

import UIKit
import SwiftyInsta

class LoginViewController: UIViewController {
    var loginWebView: InstagramLoginWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        loginWebView = InstagramLoginWebView(frame: view.frame,
                                             didReachEndOfLoginFlow: nil,
                                             didSuccessfullyLogIn: { [weak self] in
                                                // I would actually put this in `didReachEndOfLoginFlow`,
                                                // so the user never sees their timeline blinking.
                                                DispatchQueue.main.async {
                                                    self?.loginWebView.removeFromSuperview()
                                                }
            },
                                             completionHandler: { sessionCache, _ in
                                                print("Loading user with sessioncache is successful")

                                                do {
                                                    let encoder = JSONEncoder()
                                                    let data = try encoder.encode(sessionCache)

                                                    let sessionCacheString = String(data: data, encoding: .utf8)
                                                } catch {
                                                    print("Whoops, an error occured: \(error)")
                                                }
        })
        view.addSubview(loginWebView)
        loginWebView.loadInstagramLogin()
    }
}

@sbertix gracias por toda su ayuda.
Pero la página de inicio de sesión de Instagram no está cargada, solo hay una página en blanco en la pantalla

Este es todo el código que necesita. No InstagramLoginWebViewProtocol . No InstagramLoginWebViewDelegate .

@effecttwins copia y pega el código que escribí arriba. No olvide llamar al loadInstagramLogin() .
Literalmente ya está implementado para ti 😊
Funciona

sí, copié y pegué todo el código y llamé loadInstagramLogin :)
También se eliminó InstagramLoginWebViewProtocol e InstagramLoginWebViewDelegate

en la consola recibo este error, no estoy seguro de que esté relacionado con este proyecto o no
No se pudo señalar el servicio com.apple.WebKit.Networking: 113: No se pudo encontrar el servicio especificado

Lo siento, nunca agregué loginWebView a view en mi código jajaja
Lo he editado. Revísalo de nuevo. Debería funcionar ahora @effecttwins

Eres increíble @sbertix
Está trabajando ahora
Gracias por todos ustedes ayuda

Hola @sbertix

¿Qué sucede si sigo el patrón MVVM y mi vista y mi viewController están en archivos diferentes? La vista no debe enviar datos a View Controller. ¿Hay alguna forma de tener acceso a la función didSuccessfullyLogIn después de la inicialización de InstagramLoginWebView?

No necesitas init InstagramLoginWebView con didSuccessfullyLogIn (es opcional).
E incluso con las otras _closures_: simplemente puede asignar un valor diferente una vez que lo tenga.
@anonrig

¿Puede dar un ejemplo de esto, si puedo preguntar? @sbertix :)

Por supuesto. ¿Puedes enviar más información sobre tu código? La forma en que se configuran su modelo y vista, por ejemplo.

¡Sí, por supuesto!

Antes de 1.7.x, estaba manejando el evento de éxito de inicio de sesión en el nivel de ViewController usando delegates

Vista de ejemplo:

final class LoginWebView: UIView {
    // MARK: - Properties
    var bag = DisposeBag()

    private(set) lazy var webView: InstagramLoginWebView = InstagramLoginWebView(frame: UIScreen.main.bounds)

    private(set) lazy var closeButtonLabel: UILabel = {
        let label: UILabel = .create(text: "Close".localized(), numberOfLines: 1, textAlignment: .center, textColor: .white, font: .light(size: 16))
        label.isUserInteractionEnabled = true
        return label
    }()

    private(set) lazy var closeButtonBarItem: UIBarButtonItem = UIBarButtonItem(customView: closeButtonLabel)

    // MARK: - Initialization
    init() {
        super.init(frame: .zero)

        [webView].forEach(addSubview(_:))

        webView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

ViewController de ejemplo:

final class LoginWebViewController: UIViewController, View, ErrorDisplayer {
    // MARK: - Properties
    private lazy var viewSource = LoginWebView()

    private(set) var bag: DisposeBag
    private(set) var viewModel: LoginWebViewModel
    private(set) var completionObservable = PublishSubject<(SessionCache?, APIHandlerProtocol?)?>()

    // MARK: - Initialization
    init() {
        bag = DisposeBag()
        viewModel = LoginWebViewModel()

        super.init(nibName: nil, bundle: nil)

        bindErrorHandling()
        observeDatasource()
    }

    // MARK: - Life cycle
    override func loadView() {
        view = viewSource
        view.backgroundColor = .white
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        viewSource.webView.loginDelegate = self
        viewSource.webView.loadInstagramLogin(isNeedPreloadForCookieSync: true)

        // viewSource.webView.didSuccessfullyLogIn
        configureNavBar(with: "Login".localized(), prefersLargeTitle: false)

        navigationItem.rightBarButtonItem = viewSource.closeButtonBarItem
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

No sé exactamente qué es LoginWebViewModel ... pero si el objetivo es poner todo en completeObservable , simplemente puede hacer:

final class LoginWebView: UIView {
    // MARK: - Properties
    var bag = DisposeBag()

    private(set) lazy var webView: InstagramLoginWebView = InstagramLoginWebView(frame: UIScreen.main.bounds, completionHandler: nil)

    private(set) lazy var closeButtonLabel: UILabel = {
        let label: UILabel = .create(text: "Close".localized(), numberOfLines: 1, textAlignment: .center, textColor: .white, font: .light(size: 16))
        label.isUserInteractionEnabled = true
        return label
    }()

    private(set) lazy var closeButtonBarItem: UIBarButtonItem = UIBarButtonItem(customView: closeButtonLabel)

    // MARK: - Initialization
    init() {
        super.init(frame: .zero)

        [webView].forEach(addSubview(_:))

        webView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
final class LoginWebViewController: UIViewController, View, ErrorDisplayer {
    // MARK: - Properties
    private lazy var viewSource = LoginWebView()

    private(set) var bag: DisposeBag
    private(set) var viewModel: LoginWebViewModel
    private(set) var completionObservable = PublishSubject<(SessionCache?, APIHandlerProtocol?)?>()

    // MARK: - Initialization
    init() {
        bag = DisposeBag()
        viewModel = LoginWebViewModel()

        super.init(nibName: nil, bundle: nil)

        bindErrorHandling()
        observeDatasource()
    }

    // MARK: - Life cycle
    override func loadView() {
        view = viewSource
        view.backgroundColor = .white
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        viewSource.webView.completionHandler = { [weak self] cache, handler in
            self?.completionObservable.accept((cache, handler))
        }
        viewSource.webView.loadInstagramLogin()

        // viewSource.webView.didSuccessfullyLogIn
        configureNavBar(with: "Login".localized(), prefersLargeTitle: false)

        navigationItem.rightBarButtonItem = viewSource.closeButtonBarItem
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Cambié InstagramLoginWebView init(frame:) a init(frame:completionHandler:) y luego actualicé completionHandler para enviar valores a su asunto.

Gracias @sbertix

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

anonrig picture anonrig  ·  3Comentarios

biox86 picture biox86  ·  12Comentarios

reefer picture reefer  ·  18Comentarios

sbertix picture sbertix  ·  8Comentarios

sbertix picture sbertix  ·  3Comentarios