Nella versione FacebookLogin corrente (0.2.0) per Swift, il delegato LoginButton proprietà è definita come proprietà forte:
public class LoginButton: UIView {
...
/// Delegate of the login button that can handle the result, logout events.
public var delegate: LoginButtonDelegate?
... }
Se si aggiunge il login Pulsante seguendo le istruzioni di Facebook e impostare la classe UIViewController
bambino come pulsante delegato ...
... verrà creato un ciclo di riferimento. La vista conterrà un forte riferimento al pulsante, il pulsante conterrà un forte riferimento al controller e il controller avrà un forte riferimento alla sua vista, vedi questo post.
La mia soluzione era quella di utilizzare una variabile membro debole per avere un riferimento al pulsante di accesso e quando la vista scompare, il pulsante delegato è impostato a zero, in questo modo:
import UIKit
import FacebookCore
import FacebookLogin
import RxSwift
class LoginViewController: UIViewController, LoginButtonDelegate {
private weak var facebookLoginButton: LoginButton? = nil
override func viewDidLoad() {
super.viewDidLoad()
// Add the Facebook login button
let loginButton = LoginButton(readPermissions: [ .publicProfile, .email, .userFriends ])
loginButton.center = view.center
// WARNING!: Facebook login button delegate property is defined currently as STRONG.
// Therefore, it must be set to nil before leaving the view to avoid reference cycles
loginButton.delegate = self
view.addSubview(loginButton)
// Store the login button as a weak reference, since it is holded by the main view with a
// strong reference
facebookLoginButton = loginButton
}
override func willMove(toParentViewController parent: UIViewController?) {
super.willMove(toParentViewController:parent)
if parent == nil {
// The back button was pressed, interactive gesture used, or programatically pop view
// was executed
// Do not forget to set delegate in Facebook button to nil to break reference cycle.
facebookLoginButton?.delegate = nil
}
}
// MARK: - Facebook login
/**
Called when the button was used to login and the process finished.
- parameter loginButton: Button that was used to login.
- parameter result: The result of the login.
*/
func loginButtonDidCompleteLogin(_ loginButton: LoginButton, result: LoginResult) {
switch result {
case .failed(let error):
// Action on failed
case .cancelled:
// Action on cancelled
case .success(let grantedPermissions, let declinedPermissions, let accessToken):
// Action on success
}
}
/**
Called when the button was used to logout.
- parameter loginButton: Button that was used to logout.
*/
func loginButtonDidLogOut(_ loginButton: LoginButton) {
// Action on logout
}
}
Non utilizzare la funzione viewWillDissapear()
per impostare a nil
il delegato, poiché la pagina di accesso di Facebook verrà visualizzata nella parte superiore della tua app, attivando questa funzione e non otterrai il risultato di accesso poiché non sarai più il delegato. Si noti che this solution funziona correttamente per le visualizzazioni all'interno di un controller di navigazione. Un'altra soluzione dovrebbe essere trovata per le finestre modali.
Spero che aiuta, Xavi
Si dovrebbe controllare per il successo a callback (cioè registrati nel = successo) nella vista. Se hai effettuato l'accesso, puoi "reindirizzare" a un'altra vista. –
Questa potrebbe essere una domanda stupida, ma come faccio a fare questo poiché non c'è un codice reale nel controller di visualizzazione? – Soporificdreamer