xcode Facebook SDK 登录启动一个新的 ViewController
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12240702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Facebook SDK Login launch a new ViewController
提问by Nathan Cleary
I've been following one of the Login tutorials from the Facebook SDK. I have coded this correctly to log in and log out using the same ViewController and Button. I was wondering how to activate another ViewController once logged in to Facebook, any advice would be great...
我一直在关注 Facebook SDK 中的登录教程之一。我已正确编码以使用相同的 ViewController 和 Button 登录和注销。我想知道如何在登录到 Facebook 后激活另一个 ViewController,任何建议都会很棒......
I have a LoginViewController and once logged in I want to launch MainViewController
我有一个 LoginViewController,登录后我想启动 MainViewController
Code:
代码:
AppDelegate.h
AppDelegate.h
#import <UIKit/UIKit.h>
#import <FacebookSDK/FacebookSDK.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
extern NSString *const FBSessionStateChangedNotification;
extern NSString *const SCSessionStateChangedNotification;
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI;
- (void) closeSession;
@end
AppDelegate.m
AppDelegate.m
#import "AppDelegate.h"
@implementation AppDelegate
NSString *const FBSessionStateChangedNotification =
@"com.example.Login:FBSessionStateChangedNotification";
NSString *const SCSessionStateChangedNotification =
@"com.nathancleary.Login:SCSessionStateChangedNotification";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
/*
* If we have a valid session at the time of openURL call, we handle
* Facebook transitions by passing the url argument to handleOpenURL
*/
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// attempt to extract a token from the url
return [FBSession.activeSession handleOpenURL:url];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
// this means the user switched back to this app without completing
// a login in Safari/Facebook App
if (FBSession.activeSession.state == FBSessionStateCreatedOpening) {
[FBSession.activeSession close]; // so we close our session and start over
}
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[FBSession.activeSession close];
}
/*
* Callback for session changes.
*/
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
if (!error) {
// We have a valid session
NSLog(@"User session found");
}
break;
case FBSessionStateClosed:
case FBSessionStateClosedLoginFailed:
[FBSession.activeSession closeAndClearTokenInformation];
break;
default:
break;
}
[[NSNotificationCenter defaultCenter]
postNotificationName:FBSessionStateChangedNotification
object:session];
if (error) {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
}
/*
* Opens a Facebook session and optionally shows the login UX.
*/
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"user_likes",
@"read_stream",
nil];
return [FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
[self sessionStateChanged:session
state:state
error:error];
}];
}
- (void) closeSession {
[FBSession.activeSession closeAndClearTokenInformation];
}
@end
LoginViewController.h
登录视图控制器.h
#import <UIKit/UIKit.h>
@interface LoginViewController : UIViewController
- (IBAction)authButtonAction:(id)sender;
@property (strong, nonatomic) IBOutlet UIButton *authButton;
@end
LoginViewController.m
登录视图控制器.m
#import "LoginViewController.h"
#import "AppDelegate.h"
@interface LoginViewController ()
@end
@implementation LoginViewController
@synthesize authButton;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(sessionStateChanged:)
name:FBSessionStateChangedNotification
object:nil];
// Check the session for a cached token to show the proper authenticated
// UI. However, since this is not user intitiated, do not show the login UX.
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate openSessionWithAllowLoginUI:NO];
}
- (void)viewDidUnload
{
[self setAuthButton:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)sessionStateChanged:(NSNotification*)notification {
if (FBSession.activeSession.isOpen) {
[self.authButton setTitle:@"Logout" forState:UIControlStateNormal];
} else {
[self.authButton setTitle:@"Login" forState:UIControlStateNormal];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)authButtonAction:(id)sender {
AppDelegate *appDelegate =
[[UIApplication sharedApplication] delegate];
// If the user is authenticated, log out when the button is clicked.
// If the user is not authenticated, log in when the button is clicked.
if (FBSession.activeSession.isOpen) {
[appDelegate closeSession];
} else {
// The user has initiated a login, so call the openSession method
// and show the login UX if necessary.
[appDelegate openSessionWithAllowLoginUI:YES];
}
}
@end
回答by Pochi
If you are using Facebook's sdk 3 you can place this in the method called by the completition handler:
如果您使用的是 Facebook 的 sdk 3,您可以将其放在完成处理程序调用的方法中:
- (void)openFacebookSession
{
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"user_photos",
nil];
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler: ^(FBSession *session, FBSessionState state, NSError *error){
[self sessionStateChanged:session state:state error:error];
}];
}
Here is where the main viewcontroller is launched:
这是启动主视图控制器的位置:
- (void)sessionStateChanged:(FBSession *)session
state:(FBSessionState) state
error:(NSError *)error
{
switch (state) {
case FBSessionStateOpen:
{
NSLog(@"FBSessionStateOpen");
//[activityIndicator startAnimating];
// initialize the viewcontroller with a little delay, so that the UI displays the changes made above
double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard"
bundle: nil];
UIViewController *controller = [mainStoryboard instantiateViewControllerWithIdentifier: @"MainViewController"];
[self presentViewController:controller animated:YES completion:nil];
//[activityIndicator stopAnimating];
});
break;
}
case FBSessionStateClosed:
{
NSLog(@"FBSessionStateClosed");
break;
}
case FBSessionStateClosedLoginFailed:
{
[FBSession.activeSession closeAndClearTokenInformation];
NSLog(@"Facebook State Closed or Failed");
break;
}
default:
{
break;
}
}
if (error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
message:error.localizedDescription
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alertView show];
}
}
THIS method is specifically made for when you have to load a heavy main controller (thats why you can activate a loading indicator). You can easily modify it to load a simple one which can be initiated in the same thread.
这个方法是专门为当你必须加载一个沉重的主控制器时而设计的(这就是你可以激活加载指示器的原因)。您可以轻松修改它以加载一个可以在同一线程中启动的简单程序。