Je crée une application qui utilise le SDK de Facebook pour authentifier les utilisateurs. J'essaie de consolider la logique de Facebook dans une classe séparée. Voici le code (dépouillé pour la simplicité):
import Foundation
class FBManager {
class func fbSessionStateChane(fbSession:FBSession!, fbSessionState:FBSessionState, error:NSError?){
//... handling all session states
FBRequestConnection.startForMeWithCompletionHandler { (conn: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
println("Logged in user: \n\(result)");
let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())
let loggedInView: UserViewController = storyboard.instantiateViewControllerWithIdentifier("loggedInView") as UserViewController
loggedInView.result = result;
//todo: segue to the next view???
}
}
}
J'utilise la méthode de classe ci-dessus pour vérifier les changements d'état de session et tout fonctionne correctement.
Q: Une fois que j'ai les données de l'utilisateur, comment puis-je passer à la vue suivante depuis cette classe personnalisée?
EDIT: Juste pour être clair, j'ai un segue avec un identifiant sur le story-board, et j'essaie de trouver un moyen de réaliser un segue d'une classe qui n'est pas le contrôleur de vue.
Si votre séquence existe dans le storyboard avec un identificateur de séquence entre vos deux vues, vous pouvez simplement l'appeler par programme en utilisant:
performSegue(withIdentifier: "mySegueID", sender: nil)
Pour les anciennes versions:
performSegueWithIdentifier("mySegueID", sender: nil)
Vous pouvez aussi faire:
presentViewController(nextViewController, animated: true, completion: nil)
Ou si vous êtes dans un contrôleur de navigation:
self.navigationController?.pushViewController(nextViewController, animated: true)
Vous pouvez utiliser NSNotification
Ajoutez une méthode de publication dans votre classe personnalisée:
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
Ajouter un observateur dans votre ViewController:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodOFReceivedNotication:", name:"NotificationIdentifier", object: nil)
Ajouter une fonction dans votre ViewController:
func methodOFReceivedNotication(notification: NSNotification){
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
}
Si votre séquence existe dans le storyboard avec un identifiant de séquence entre vos deux vues, vous pouvez simplement l'appeler par programme à l'aide de
self.performSegueWithIdentifier("yourIdentifierInStoryboard", sender: self)
Si vous êtes dans le contrôleur de navigation
let viewController = YourViewController(nibName: "YourViewController", bundle: nil)
self.navigationController?.pushViewController(viewController, animated: true)
Je vous recommanderai pour une deuxième approche à l'aide du contrôleur de navigation.
Vous pouvez utiliser segue comme ceci:
self.performSegueWithIdentifier("Push", sender: self)
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if segue.identifier == "Push" {
}
}
Swift - fonctionne également avec SpriteKit
Vous pouvez utiliser NSNotification.
Exemple:
1.) Créez une séquence dans le storyboard et nommez l'identifiant "séquence"
2.) Créez une fonction dans le ViewController à partir duquel vous vous situez.
func goToDifferentView() {
self.performSegue(withIdentifier: "segue", sender: self)
}
3.) Dans ViewDidLoad () de votre ViewController, vous créez l’observateur.
NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: "segue" as NSNotification.Name, object: nil)
Mise à jour - La dernière fois que j'ai utilisé cela, je devais changer l'appel .addObserver
en code suivant pour mettre les erreurs au silence.
NotificationCenter.default.addObserver(self, selector: #selector(goToDifferentView), name: NSNotification.Name(rawValue: "segue"), object: nil)
4.) Dans le ViewController ou la scène à laquelle vous vous inscrivez, ajoutez la méthode de publication à l’endroit où vous le souhaitez.
NotificationCenter.default.post(name: "segue" as NSNotification.Name, object: nil)
Mise à jour - La dernière fois que j'ai utilisé cela, je devais changer l'appel .post
en code suivant pour mettre les erreurs au silence.
NotificationCenter.default.post(NSNotification(name: NSNotification.Name(rawValue: "segue"), object: nil) as Notification)
Ce que vous voulez faire est vraiment important pour les tests unitaires. En gros, vous devez créer une petite fonction locale dans le contrôleur de vue. Nommez la fonction à n’importe quoi, incluez simplement le performSegueWithIndentifier
.
func localFunc() {
println("we asked you to do it")
performSegueWithIdentifier("doIt", sender: self)
}
Ensuite, changez votre classe d'utilitaires FBManager
pour inclure un initialiseur qui prend un argument d'une fonction et une variable pour contenir la fonction de ViewController qui effectue la séquence.
public class UtilClass {
var yourFunction : () -> ()
init (someFunction: () -> ()) {
self.yourFunction = someFunction
println("initialized UtilClass")
}
public convenience init() {
func dummyLog () -> () {
println("no action passed")
}
self.init(dummyLog)
}
public func doThatThing() -> () {
// the facebook login function
println("now execute passed function")
self.yourFunction()
println("did that thing")
}
}
(L'initiation commod vous permet de l'utiliser dans les tests unitaires sans exécuter la séquence.)
Enfin, là où vous avez // todo: segue à la vue suivante ???, mettez quelque chose comme suit:
self.yourFunction()
Dans vos tests unitaires, vous pouvez simplement l'invoquer comme suit:
let f = UtilClass()
f.doThatThing()
où doThatThing est votre changement de statut de fbsession et UtilClass
est de FBManager.
Pour votre code actuel, passez simplement localFunc
(sans parenthèse) à la classe FBManager.
Cela a fonctionné pour moi.
Tout d’abord, attribuez au contrôleur de vue de votre storyboard un ID de storyboard dans l’inspecteur d’identité. Utilisez ensuite l'exemple de code suivant (en veillant à ce que la classe, le nom du storyboard et l'ID de story board correspondent à ceux que vous utilisez):
let viewController:
UIViewController = UIStoryboard(
name: "Main", bundle: nil
).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
// .instantiatViewControllerWithIdentifier() returns AnyObject!
// this must be downcast to utilize it
self.presentViewController(viewController, animated: false, completion: nil)
Pour plus de détails, voir http://sketchytech.blogspot.com/2012/11/instantiate-view-controller-using.html meilleurs voeux