After update the pod weblogin not compiled in ios 10 version.
When I change to 11.0 version of ios it says:
InstagramLoginWebView
properties instead.InstagramLoginWebViewProtocol
closure properties instead.When I changed InstagramLoginWebViewDelegate to InstagramLoginWebViewProtocol:
My Codes:
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**
}
}
extension LoginViewController : InstagramLoginWebViewProtocol { --'InstagramLoginWebViewProtocol' requires that 'LoginViewController' inherit from 'UIView'
func userLoggedSuccessfully() {
print("User Logged Successfully")
DispatchQueue.main.async {
self.loginWebView.removeFromSuperview()
}
}
Hey @effecttwins 😊
InstagramLoginWebView
has changed a lot in the last update, and support for iOS 10.*
had to be dropped because of incompatibility.
Using loginDelegate
is no longer suggested, although still functional.
All you have to do to get the behavior you're used to is setting the following properties on your loginWebView
:
didReachEndOfLoginFlow
is a _closure_ called like redirected
used to.didSuccessfullyLogIn
is a _closure_ replacing the _delegate_'s userLoggedSuccessfully()
.completionHandler
is a _closure_ replacing the _delegate_'s webViewFinishedToLoadUser(sessionChache:handler:)
This is the updated code for 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()
}
}
so when I change the extension InstagramLoginWebViewDelegate to InstagramLoginWebViewProtocol and it says: 'InstagramLoginWebViewProtocol' requires that 'LoginViewController' inherit from 'UIView'
Code:
extension 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)")
}
}
You should never conform to InstagramLoginWebViewProtocol
.
My fault for not marking it internal
. I apologize.
This is all the code you need. 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 thanks for your all help.
But instagram login page not loaded there is only white page in screen
This is all the code you need. No
InstagramLoginWebViewProtocol
. NoInstagramLoginWebViewDelegate
.
@effecttwins copy and paste the code I wrote above. Don't forget to call the loadInstagramLogin()
.
It's literally already implemented for you 😊
It works
yeap I did copy and paste all code and called loadInstagramLogin :)
Also deleted InstagramLoginWebViewProtocol and InstagramLoginWebViewDelegate
in console I am getting this error, I am not sure it is related with this project or not
Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service
Sorry, I've never added the loginWebView
to the view
in my code hahaha
I've edited it. Check it again. It should work now @effecttwins
You are awesome @sbertix
It is working now
Thanks for you all help
Hey @sbertix
What happens I'm following MVVM pattern and my view and my viewController is in different files? The view should not send data to View Controller. Is there way to have access to didSuccessfullyLogIn
function after the initialization of the InstagramLoginWebView?
You don't need to init
InstagramLoginWebView
with a didSuccessfullyLogIn
(it's optional).
And even with the other _closures_: you can simply assign a different value once you have it.
@anonrig
Can you provide an example of this, if I may ask? @sbertix :)
Sure. Can you send more info about your code? The way your model and view are setup, for instance.
Yeah of course!
Before 1.7.x I was handling the login success event on ViewController level using the delegates
Example view:
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")
}
}
Example ViewController:
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")
}
}
I don't exactly know what LoginWebViewModel
is... but if the objective is to get everything into completeObservable
you can simply do:
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")
}
}
I've changed InstagramLoginWebView
init(frame:)
to init(frame:completionHandler:)
and then updated the completionHandler
to push values to your subject.
Thanks @sbertix