
안녕하세요. 바티 입니다.
Web 2.0이라는 단어가 유명해지기 시작하면서 주목 받던 주제 중 하나가 ‘공유’였던 것으로 기억합니다. ‘공유’라고 하면 개발자들은 먼저 떠오르는 단어들 중 하나가 ‘Open API’이거나 ‘SDK’가 아닐까 싶네요. 구글과 페이스북 같은 대기업에서 부터 소규모의 스타텁까지 SDK 및 Open API를 제공하고 사용하기 위해서 혈안이 되어 있는 모습입니다. 그런 의미로 블로그를 통해 메이져 회사들의 SDK를 완전 분해해 보고자 합니다.
앞으로 완전분해 해보기 위해서는 세가지 툴을 사용할 것입니다. ‘관찰’, ‘해석’ 그리고 ‘비교’. 긴 여정이 될 것 같은데 먼저 긴 여행도 첫 발이 중요한 만큼 첫 시리즈로는 온라인에서 많은 사용자들로 부터 사랑을 받고 있는 ‘페이스북’ SDK입니다. 페이스북에서 제공해주고 있는 SDK와 함께 예제 소스를 통해서 어떻게 사용하는지, 또는 그 속은 어떻게 되어 있는지 한번 살펴보고자 합니다.
부족하거나 잘못된 부분 혹은 궁금한 부분이 있으시면 자유롭게 댓글 달아주시면 함께 고민해보아요.
본 포스트에서는 Facebook SDK를 사용하여 로그인 하는 방법을 알 아볼 것입니다. Login Dialog의 종류의 특징, 상황에 따른 SDK가 컨트롤하는 Login Dialog, 그리고 제공 받을 정보에 대한 Permission에 대한 내용 및 몇 가지를 다룰 것이다.
Facebook Login on iOS
페이스북 로그인은 타 개발사들이 ‘접근자 토큰’ (Access token)을 제공 해줌으로써 페이스북의 서비스를 사용할 수 있게 해준다. 이 기능을 자신의 로그인과 인증 시스텐에 넣어서 사용할 수 있다. 예를 들어 현재 시장에 올라오는 앱들을 살펴보면 대부분 ‘Login with Facebook’라고 새겨진 파란 버튼을 쉽게 찾아 볼수 있다. 이 버튼들은 대부분 자신이 만든 페이스북 버튼이거나 FBLoginView를 갖다 붙여 놓은 것들이다.

페이스북에서 제공하는 ‘FBLoginView’
Login Dialog
자신이 직접 버튼을 만들었던, 페이스북에서 제공해주는 인증과정을 위한 Login Dialog는 다음과 같이 크게 5 가지로 구분할 수 있다.
- 페이스북 앱 Native Login Dialog
- iOS 6 Native Login Dialog
- Facebook 앱 웹 Login Dialog
- 모바일 Safari Login Dialog
- 임베디드 WebView Login Dialog
각 Dialog는 사용자의 iOS 설정 혹은 디바이스에 페이스북이 설치되어 있는 여부에 따라 보여지는 것이 달라진다. 그럼 이제 부터 각각의 Login Dialog에 대해 페이스북 문서에서 알려주고 있는 장단점과 Dialog에 대해 알아보자. 페이스북 개발자 사이트
#1. 페이스북 앱 Native Login Dialog

Facebook App Native Login Dialog
100 퍼센트 Native이며 ‘Facebook’ 앱에서 열려지는 창이다. 이 방법을 사용하기 위해서는 ‘.plist’ 파일에 ‘FacebookDisplayName’이라는 이름 아래에 앱 이름을 정의를 해주어야 한다. 정의된 키의 값은 페이스북 개발자 사이트에 등록한 이름과 동일해야만 한다.
- 장점: 100 퍼센트 Native
- 단점: iOS 6.0 이상용 페이스북 앱이 설치가 되어 있어야만 한다.
#2. 페이스북 앱 Native Login Dialog

iOS 6 Native Login Dialog
이 Login Dialog 창은 Apple이 iOS 6에서 새로 선보인 ‘Facebook 통합’에 해당하는 기능이다. 먼저 사람들은 iOS 설정에서 페이스북을 설정해야만 사용이 가능하다. 해당 방법은 디바이스 차원의 인증 방법이기 때문에 사용자가 가지고 있는 모든 iOS에 설정 해야만 사용이 가능하다.
- 장점: *100 퍼센트 Native
*로그인 과정에서 앱을 벗어나지 않아도 됨.
- 단점: *iOS 6 이상 사용자에 한에 사용가능
*멋진 비주얼이 없다. (단순 UIAlertView로 뜸)
*프라이버시 옵션 선택이 불가능함.
#3. 페이스북 앱 웹 Login Dialog

Facebook App Web Login Dialog
해당 Login Dialog창은 ‘페이스북’ Native 앱에서 열리며, 페이스북 앱의 버젼이 맞지 않을 때 웹 베이스의 컴포넌트에서 띄어준다.
- 장점: 모든 Facebook 앱 버전과 호환 가능함
- 단점: 웹 베이스 뷰는 사용자들에게 최상의 경험을 줄수 없다.
#4. 모바일 사파리 Login Dialog

Mobile Safari Login Dialog
해당 Login Dialog 창은 모바일의 사파리 브라우저에서 열린다. 다른 Login Dialog 창의 최종 대안이 된다.
- 장점: 사용자 디바스에 설치되어 있는 페이스북 버전에 의존하지 않는다.
- 단점: *웹 베이스 뷰는 사용자들에게 최상의 경험을 줄수 없다.
*모바일 버전 사파리 브라우저에서 로그인을 해야하는 불편함.
#5. 임베드 WebView Login Dialog

Embedded WebView Login Dialog
해당 Login Dialog 창은 SDK를 사용하여 개발하는 앱의 임베디드 WebView에서 나타나게 된다. 해당 Login Dialog를 띄우기 위해서는 트리거할 수 있는 코드를 작정해야한다.
- 장점: 다른 앱 전환 없이 사용 가능함.
- 단점: *웹 기반 뷰는 사용자들에게 최상의 경험을 줄수 없다.
* 사용자는 Login Flow를 탈 때마다 페이스북 ID와 비밀번호를 입력해야하는 불편함이 있다.
위에서 살펴본 다양한 Login Dialog 창들은 SDK를 적용하는 개발자는 FBSession open* 으로 시작하는 메서드를 사용하여 다양한 사용자 디바이스 환경에 대응할 수 있다. 가장 먼저 SDK는 해당 디바이스의 iOS 6 이상 버전인 것을 확인 할 것이고, 만약 사용 중이라면 OS 레벨에서 Facebook 계정을 연동하였는지 확인 할 것이다. 만약 사용한다면 iOS 6 Native Login Dialog 창을 띄어 줄 것이다. 하지만 iOS 버전이 지원을 안하든지, OS 차원에서 페이스북과 연동을 하지 않은 디바이스에서는 다음 단계의 대안(fallback)을 살펴볼 것이다. 페이스북 앱이 설치되어 있는지 볼 것이고, 되어 있다면 페이스북 앱의 버전을 확인하여 Facebook App Native Login Dialog나 Facebook App web Login Dialog를 보여 줄 것이다. 만약 페이스북 앱도 깔려 있지 않은 디바이스에서는 최후의 선택으로 ‘모바일 사파리 Login Dialog’ 창을 띄어서 인증을 할 것이다. 이 외에도 ‘임베디드 WebView Login Dialog’ 창을 통하여서 개발 중인 앱을 빠져 나가지 않고 해당 앱에서 웹뷰 창을 띄어 줄 수 있는 대안도 있다.
만약 개발 중인 앱의 ‘.plist’ 파일에 ‘FacebookDiskplayName’ 설정을 추가하지 않았다면 로그인 과정은 다음 과정을 차례대로 시도하며 내려갈 것이다.
- iOS 6 Login Dialog
- Facebook App Web Login Dialog
- Mobile Safari Login Dialog
만약 ‘iOS 6 Login Dialog’를 건너뛰고 싶다면, FBSession 클래스 인스턴스의 openWithBehavior:completionHandler: 메서드에 FBSessionLoginBehavior 파라미터를 ‘FBSessionLoginBehaviorUseSystemAccountIfPresent’ 파라미터를 제외하고 다른 파라미터를 사용하면 된다.
// Initialize a session object
FBSession *session = [[FBSession alloc] init];
// Set the active session
[FBSession setActiveSession:session];
// Open the session
[session openWithBehavior:FBSessionLoginBehaviorWithNoFallbackToWebView
completionHandler:^(FBSession *session, FBSessionState status, NSError *error){
// Respond to session state changes,
// ex: updating the view
}];
// Initialize a session object
FBSession *session = [[FBSession alloc] init];
// Set the active session
[FBSession setActiveSession:session];
// Open the session
[session openWithBehavior:FBSessionLoginBehaviorWithNoFallbackToWebView
completionHandler:^(FBSession *session, FBSessionState status, NSError *error){
// Respond to session state changes,
// ex: updating the view
}];
위 코드를 사용했을 때 SDK의 로그인 플로우는 다음과 같을 것이다.
- Facebook App Native Login Dialog
- Facebook App Web Login Dialog
- Mobile Safari Login Dialog
구현
위에서 설명한 Login Dialog를 통한 인증 과정을 걸치기 위해서 실제적으로 적용해야하는 구현을 설명하겠다. 크게 두가지 방법으로 구현할 수 있을 것이다. FBSession 인스턴스를 사용하는 방법과 FBLoginView를 사용하는 방식이 있다. 먼저 인스턴스를 초기화와 동시에 적용하는 방법을 알아보자.
#1. FBLoginView를 사용하는 방법
FBLoginView *loginView = [[FBLoginView alloc] init];
loginView.readPermissions = @[@"basic_info"];
[modalViewController.view addSubview:loginView];
FBLoginView *loginView = [[FBLoginView alloc] init];
loginView.readPermissions = @[@"basic_info"];
[modalViewController.view addSubview:loginView];
위 코드는 FBLoginView를 초기화 하고 원하는 Permission을 설정한다음에 뷰단에 붙이는 작업이다. 위 코드를 적용하게 되면은 아래와 같은 ‘Login with Facebook’ 버튼이 자동으로 생길 것이다.

페이스북에서 제공하는 ‘FBLoginView’
버튼을 누르게 되면 사용자의 상황에 맞는 Login flow가 실행되어 질것이다. 사용자가 가장 쉽게 적용할 수 있는 방법이라고 생각되어 진다. 코드상으로 addSubview:를 사용하여 적용할 수도 있고, 아니면 xib 파일에서 커스텀 버튼을 적용하는 방식으로도 사용이 가능하다.
#2. FBSession을 사용한 로그인
사용자는 FBLoginView에 상응하는 UI를 만들어주어야 한다. 페이스북 개발자 사이트에 나와있는 Tutorial에서 제안하는 방법으로 커스텀 “Login” 버튼의 핸들러에 다음과 같은 메서드를 적용해보자. Static 메서드를 통한 호출 방식과 인스턴스를 만들어 호출하는 방식 둘중에 아무구나 사용해도 무관하다.
* Static 메서드
[FBSession openActiveSessionWithReadPermissions:@[@"basic_info", @"email"]
allowLoginUI:YES
completionHandler: ^(FBSession *session, FBSessionState state, NSError *error)
{
[self sessionStateChanged:session state:state error:error];
}];
[FBSession openActiveSessionWithReadPermissions:@[@"basic_info", @"email"]
allowLoginUI:YES
completionHandler: ^(FBSession *session, FBSessionState state, NSError *error)
{
[self sessionStateChanged:session state:state error:error];
}];
* FBSession 인스턴스 방식
FBSession *session = [[FBSession alloc] init];
[FBSession setActiveSession:session];
[session openWithBehavior:FBSessionLoginBehaviorWithNoFallbackToWebView
completionHandler:^(FBSession *session, FBSessionState status, NSError *error)
{
// Respond to session state changes
// ex: updating the view
}];
FBSession *session = [[FBSession alloc] init];
[FBSession setActiveSession:session];
[session openWithBehavior:FBSessionLoginBehaviorWithNoFallbackToWebView
completionHandler:^(FBSession *session, FBSessionState status, NSError *error)
{
// Respond to session state changes
// ex: updating the view
}];
방식은 static method와 거의 흡사하다.
#3. 객체 초기화 후 Permission 받기
Facebook SDK는 사용자의 정보를 초기화할 때 요청할 수도 있고, 초기화 후 요청을 할 수도 있다. 초기화 후에 추가로 요청할 경우에는 위 코드와 같은 방식으로 요청을 하면된다.
[FBSession.activeSession requestNewReadPermissions:@[@"user_likes"]
completionHandler:^(FBSession *session, NSError *error)
{
// Handle new permissions callback
}];
[FBSession.activeSession requestNewReadPermissions:@[@"user_likes"]
completionHandler:^(FBSession *session, NSError *error)
{
// Handle new permissions callback
}];
글 쓰기 Permission을 받기 위해서는 requestNewPublishPersmissions:defaultAudience:completionHandler 메서드를 통해 요청할 수 있다.
[FBSession.activeSession requestNewPublishPermissions:@[@"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error)
{
// Handle new permissions callback
}];
[FBSession.activeSession requestNewPublishPermissions:@[@"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error)
{
// Handle new permissions callback
}];
#4. 로그인 상태 체크하기
if ([FBSession.activeSession isOpen])
{
// Session is open
}
else
{
// Session is closed
}
if ([FBSession.activeSession isOpen])
{
// Session is open
}
else
{
// Session is closed
}
#5. Access 토큰 받기
서비스나 앱의 특성에 따라 달라질 것이지만, 어떤 경우에는 서버에 Access 토큰을 저장해야 하는 경우가 있다. 이럴땐 다음과 같은 방법으로 토큰을 얻을 수 있다.
NSString *accessToken = [[FBSession.activeSession accessTokenData] accessToken];
NSString *accessToken = [[FBSession.activeSession accessTokenData] accessToken];
#6. 로그 아웃하기
로그 아웃하는 방법은 다음과 같다. 다음 코드를 사용하면 세션도 닫아주고 동시에 저장되어 있는 캐시도 지워준다.
[FBSession.activeSession closeAndClearTokenInformation];
[FBSession.activeSession closeAndClearTokenInformation];
하지만 여러가지 이유로 캐시를 꼭 안지워 줄 때는 다음과 같이 close 메서드를 사용한다.
[FBSession.activeSession close];
[FBSession.activeSession close];
마치며..
Facebook SDK의 인증 부분을 분석하기 위해서 먼저 ‘관찰’이라는 방법을 통해 어떤 일을 하는지 알아 보았다. 이번 포스팅에서는 로그인에 관한 내용을 페이스북 개발자 문서에 설명한 순서대로 설명해보았다.
사용자가 처해있는 환경에 따라 알맞은 Dialog를 보여주는 SDK의 위력은 대단하다고 생각한다. 만약 SDK가 커버해주지 못한다면 앱 개발자들이 자신의 코드에서 대응해야 할 것인데 수고를 덜어줄 뿐만이 아니라 위대한 빙산의 일각을 보는 느낌이라고나 할까? 경의로움까지 느낀다. FBSession는 여러 상태를 가지고 있다.
다음 포스팅에서는 FBSession 객체의 ‘Status’ (상태)에 대해서 알아보자. 어떤 상태들이 있는지 알아보게 될 것이고, 어떤 상황에서 어떤 상태로 변화 되는지 알아보게 될 것이다.