После обновления pod weblogin не компилируется в версии ios 10.
Когда я перехожу на версию ios 11.0, он говорит:
InstagramLoginWebView
.InstagramLoginWebViewProtocol
.Когда я изменил InstagramLoginWebViewDelegate на InstagramLoginWebViewProtocol:
Мои коды:
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' требует, чтобы 'LoginViewController' унаследовал от 'UIView'
func userLoggedSuccessfully() {
print("User Logged Successfully")
DispatchQueue.main.async {
self.loginWebView.removeFromSuperview()
}
}
Привет, @effecttwins 😊
InstagramLoginWebView
сильно изменился в последнем обновлении, и поддержка iOS 10.*
была прекращена из-за несовместимости.
Использование loginDelegate
больше не рекомендуется, хотя все еще работает.
Все, что вам нужно сделать, чтобы добиться привычного поведения, - это установить следующие свойства на вашем loginWebView
:
didReachEndOfLoginFlow
- это _closure_, который называется как раньше redirected
.didSuccessfullyLogIn
- это _closure_, заменяющий userLoggedSuccessfully()
_delegate_.completionHandler
- это _closure_, заменяющий webViewFinishedToLoadUser(sessionChache:handler:)
_delegate_Это обновленный код для 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()
}
}
поэтому, когда я меняю расширение InstagramLoginWebViewDelegate на InstagramLoginWebViewProtocol, и он говорит: 'InstagramLoginWebViewProtocol' требует, чтобы 'LoginViewController' унаследовал от 'UIView'
Код:
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)")
}
}
Вы никогда не должны соответствовать InstagramLoginWebViewProtocol
.
Моя вина, что я не пометил его internal
. Я прошу прощения.
Это весь код, который вам нужен. Нет InstagramLoginWebViewProtocol
. Нет 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 спасибо за вашу помощь.
Но страница входа в Instagram не загружена, на экране есть только белая страница
Это весь код, который вам нужен. Нет
InstagramLoginWebViewProtocol
. НетInstagramLoginWebViewDelegate
.
@effecttwins скопируйте и вставьте код, который я написал выше. Не забудьте позвонить в loadInstagramLogin()
.
Это буквально уже реализовано для вас 😊
Оно работает
да, я скопировал и вставил весь код и вызвал loadInstagramLogin :)
Также удалены InstagramLoginWebViewProtocol и InstagramLoginWebViewDelegate.
в консоли я получаю эту ошибку, я не уверен, что это связано с этим проектом или нет
Не удалось сигнализировать о службе com.apple.WebKit.Networking: 113: не удалось найти указанную службу
Извините, я никогда не добавлял loginWebView
к view
в моем коде хахаха
Я его отредактировал. Проверьте это еще раз. Теперь он должен работать @effecttwins
Ты классный @sbertix
Сейчас работает
Спасибо за вашу помощь
Привет @sbertix
Что происходит, когда я следую шаблону MVVM, и мое представление и мой viewController находятся в разных файлах? Представление не должно отправлять данные в контроллер представления. Есть ли способ получить доступ к функции didSuccessfullyLogIn
после инициализации InstagramLoginWebView?
Вам не нужно init
InstagramLoginWebView
с didSuccessfullyLogIn
(это необязательно).
И даже с другими _closures_: вы можете просто назначить другое значение, когда оно у вас есть.
@anonrig
Могу я спросить, можете ли вы привести пример этого? @sbertix :)
Конечно. Вы можете прислать дополнительную информацию о своем коде? Например, способ настройки вашей модели и вида.
Да, конечно!
До версии 1.7.x я обрабатывал событие успешного входа в систему на уровне ViewController, используя delegates
Пример просмотра:
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:
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")
}
}
Я точно не знаю, что такое LoginWebViewModel
... но если цель состоит в том, чтобы поместить все в completeObservable
вы можете просто сделать:
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")
}
}
Я изменил InstagramLoginWebView
init(frame:)
на init(frame:completionHandler:)
а затем обновил completionHandler
чтобы передать значения вашей теме.
Спасибо @sbertix