segunda-feira, 11 de junho de 2012

Facebook API no iOS

Olá povo,

Logo após escrever um post sobre como utilizar a API do Facebook no Android, tive que fazer o mesmo para o iOS, então resolvi compartilhar com vocês.

Registrando a aplicação do Facebook

Devemos primeiro criar/registrar nossa aplicação no Facebook. Para tal, acesse: https://developers.facebook.com/apps, faça o login com uma conta do facebook (aconselho criar uma conta de teste) e clique na opção Create New App. A janela abaixo será exibida:
Digite o nome da aplicação e clique em Continue.

Nota: Por questões de segurança o Facebook pede que você coloque uma informação que te identifique. No meu caso, eu tive que preencher o número do meu celular. Uma vez que cadastrei, o Facebook envia um código de ativação via SMS. Clique no link que foi enviado para o seu aparelho ou digite o código de confirmação para concluir o seu cadastro.

Uma vez que a aplicação está cadastrada, habilite a opção Native iOS App.


Preencha o campo iOS Bundle ID com o ID da sua aplicação (configurado no Xcode) e habilite as opções Configured for iOS SSO e iOS Native Deep Linking.

Importanto o projeto do Facebook SDK

O código do Facebook SDK está disponível em um repositório GIT, mas você pode baixá-lo no formato ZIP. Acesse https://github.com/facebook/facebook-ios-sdk e selecione a opção Download this repository as a ZIP file". Terminado o download, descompacte onde desejar.

Após descompactar, abra o terminal para gerar a lib que nos permitirá utilizar o Automatic Reference Counting (ARC) recurso do iOS que nos permite delegar para o sistema operacional limpeza dos objetos da memória. Digite o seguinte comando no diretório onde você descompactou o facebook SDK:

./scripts/build_facebook_ios_sdk_static_lib.sh

Será gerado o diretório lib/facebook. Você irá copiar esse diretório para o diretório da sua aplicação.

Criando o projeto

Crie um novo projeto no Xcode do tipo Single View Application e clique em Next. Preencha no nome do projeto e o company identifier de modo que juntos formem o campo iOS Bundle ID utilizado no cadastro do Facebook. Conclua o assistente de criação do projeto. Adicione a pasta lib que foi gerada na seção anterior para seu projeto (botão direito sobre o projeto, Add files).

Abra o delegate da sua aplicação e deixe-o conforme abaixo:

#import <UIKit/UIKit.h>
#import "FBConnect.h"

@interface NGAppDelegate : UIResponder 
  <UIApplicationDelegate, FBSessionDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) Facebook *facebook;

@end
#import "NGAppDelegate.h"

@implementation NGAppDelegate

@synthesize window = _window;
@synthesize facebook;

// Método que trata a autenticação após o facebook
// validar o login e senha do usuário no browser
- (BOOL)application:(UIApplication *)application 
  openURL:(NSURL *)url 
  sourceApplication:(NSString *)sourceApplication 
  annotation:(id)annotation {

  return [facebook handleOpenURL:url];
}

// *** Métodos do Protocolo FBSessionDelegate
// Salva o accessToken e data de expirar
-(void)fbDidLogin {
  NSUserDefaults *defaults = 
    [NSUserDefaults standardUserDefaults];
  [defaults setObject:[facebook accessToken] 
    forKey:@"FBAccessToken"];
  [defaults setObject:[facebook expirationDate] 
    forKey:@"FBExpirationDateKey"];
  [defaults synchronize];
}

// Ao fazer logout, apaga o accessToken
-(void)fbDidLogout {
  NSUserDefaults *defaults = 
    [NSUserDefaults standardUserDefaults];
  [defaults removeObjectForKey:@"FBAccessToken"];
  [defaults removeObjectForKey:@"FBExpirationDateKey"];
  [defaults synchronize];    
}

-(void)fbDidNotLogin:(BOOL)cancelled {}

-(void)fbDidExtendToken:(NSString *)accessToken 
  expiresAt:(NSDate *)expiresAt{}

- (void)fbSessionInvalidated {}

// *** Métodos de UIApplicationDelegate ***
- (BOOL)application:(UIApplication *)application 
  didFinishLaunchingWithOptions:
   (NSDictionary *)launchOptions
{
  facebook = [[Facebook alloc] 
    initWithAppId:@"ID_SUA_APP" andDelegate:self];
    
  // Carregar o AccessToken pra ver se está logado
  NSUserDefaults *defaults = 
    [NSUserDefaults standardUserDefaults];
  if ([defaults objectForKey:@"FBAccessToken"] && 
      [defaults objectForKey:@"FBExpirationDateKey"]){

    facebook.accessToken = 
      [defaults objectForKey:@"FBAccessToken"];
    facebook.expirationDate = 
      [defaults objectForKey:@"FBExpirationDateKey"];
  }
  // Se não estiver logado, exibe a tela de login
  if (![facebook isSessionValid]) {

    NSArray *permissions = [NSArray 
      arrayWithObjects:@"publish_stream", nil];
        
    [facebook authorize:permissions];
  }                            
    
  return YES;
}
Agora vamos mexer no ViewController
#import <UIKit/UIKit.h>
#import "Facebook.h"

@interface NGViewController : UIViewController 
  <FBRequestDelegate> {

  Facebook *facebook;    
}
@property (weak, nonatomic) IBOutlet 
  UITextField *txtMensagem;

- (IBAction)updateStatusClick:(id)sender;
- (IBAction)logoutClick:(id)sender;

@end
#import "NGViewController.h"
#import "NGAppDelegate.h"

@implementation NGViewController
@synthesize txtMensagem;

- (void)viewDidLoad
{
  [super viewDidLoad];
    
  NGAppDelegate *delegate = (NGAppDelegate *)
    [UIApplication sharedApplication].delegate;
  facebook = delegate.facebook;
}

- (void)viewDidUnload
{
  [self setTxtMensagem:nil];
  [super viewDidUnload];
  facebook = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:
  (UIInterfaceOrientation)interfaceOrientation
{
  return (interfaceOrientation != 
    UIInterfaceOrientationPortraitUpsideDown);
}

- (IBAction)updateStatusClick:(id)sender {
  NSMutableDictionary *params = 
    [[NSMutableDictionary alloc]init];

  [params setObject:txtMensagem.text 
    forKey:@"message"];
    
  [facebook requestWithGraphPath:@"me/feed" 
    andParams:params andHttpMethod:@"POST" 
    andDelegate:self];
}

- (IBAction)logoutClick:(id)sender {
  if (![facebook isSessionValid]) {
    NSArray *permissions = [NSArray arrayWithObjects:
      @"publish_stream", nil];
        
    [facebook authorize:permissions];
  } else {
    [facebook logout];
  }
}

-(void)request:(FBRequest *)request 
  didReceiveResponse:(NSURLResponse *)response {
  UIAlertView *alert = [[UIAlertView alloc] 
    initWithTitle:@"Info" message:response.description 
    delegate:nil cancelButtonTitle:@"OK" 
    otherButtonTitles:nil, nil];
  [alert show];
}

@end
Abra agora o *.plist com o nome da sua aplicação no modo XML e adicone o trecho abaixo dentro da tag <dic>:
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>fbID_SUA_APP</string>
    </array>
  </dict>
</array>
Arraste uma caixa de texto e ligue com o Outlet txtMensagem. Arraste dois botões e associe o evento Touch Up Inside aos métodos logoutClick e updateStatusClick. Feito isso é só rodar a aplicação:

Na primeira vez que a aplicação for executada, será exibida a tela acima, onde o usuário deverá autorizar nossa aplicação a utilizar a conta do facebook do usuário. Após aceitar a permissão, a nossa aplicação volta para foreground, e aparece conforme abaixo:
Pronto! Digite sua mensagem e clique no botão para atualizar o status do facebook.

Qualquer dúvida, deixem seus comentários.

4br4ç05,
nglauber

Nenhum comentário: