네이버는 한국 사이트라 자료도 몇 없더라..
네이버도 구글, 페이스북과 마찬가지로 개발자 계정으로 등록을 해야하고, 앱 역시 번들아이디와 함께 등록이 필요하다. 개발자 계정과 앱 등록을 마친 후에 아래 튜토리얼을 시도해 보자.
네이버 API 사용하기
https://developers.naver.com/docs/login/ios
1. 라이브러리 다운로드 및 프로젝트에 임포트
위에 게시한 주소에서 네이버 로그인 라이브러리를 다운받는다.
다운받을 땐 항상 최신 버전으로.
다운받은 라이브러리 안에는 Resources 폴더와 thirdPartyModule 폴더가 있다.
이 폴더를 프로젝트 내로 복사해주면 되는데, 폴더 째로 복사하면 타겟 - Build Pases - Link Binary와 Copy Bundle Resources 에서도 폴더 째로 추가된다. 그리고 이럴 경우, 안돌아간다....;;
수동으로 추가해 줄 수도 있겠지만, 편의상 폴더 내 파일들을 프로젝트로 복사 후, 그룹으로 분류했다.
그러면 Link Binary 와, Copy Bundle 에서도 자동으로 각각 추가가 될 것이다.
2. Other Linker Flags 설정
이건 사실 다른걸 다 끝내놓고 빌드에러를 보고 설정하는 방향을 추천하는데...
경우에 따라 정말 case by case 이기 때문 ㅎㅎㅎㅎㅎㅎ
네이버 공식 튜토리얼은 -ObjC -all_loaded를 추가하라고 하지만, -ObjC 따위 ㅎㅎㅎㅎㅎ 나한텐 수십개의 에러를 가져다주었음
그래서 열심히 구글링과 삽질 후 $(inherited) -all_loaded 로 추가해 주니 이상 무.
(경우에 따라, $(inherited) 만으로도 빌드될 수 있으니 참조하자)
3. 헤더 설정
Bridging-Header 를 만들어 주고, 프로젝트 - Build Settings - Objective-C Bridging Header 에 헤더 파일 명을 입력. 헤더파일 안에는 다음과 같이 라이브러리를 임포트
#import "NLoginThirdPartyOAuth20InAppBrowserViewController.h"
#import "NaverThirdPartyConstantsForApp.h"
#import "NaverThirdPartyLoginConnection.h"
이 라이브러리가 만약 xcodeproj 와 다른 폴더에 있다면 폴더명까지 명시해 주어야 한다.
그리고 NaverThirdPartyConstantsForApp.h 에서 값 몇개를 지정해 줘야 하는데, 이건 네이버 튜토리얼을 그대로 긁어옴..
// 애플리케이션 이름// 콜백을 받을 URL Scheme
#define kUrlSampleAppUrlScheme @"thirdparty20samplegame"
// 애플리케이션에서 사용하는 클라이언트 아이디
#define kConsumerKey @"jyvqXeaVOVmV"
// 애플리케이션에서 사용하는 클라이언트 시크릿
#define kConsumerSecret @"527300A0_COq1_XV33cf"
#define@"네이버 아이디로 로그인하기"
여기에 들어갈 데이터는 네이버에 등록한 내 애플리케이션 정보를 참고하면 된다.
4. URL Scheme 등록
네이버에서 로그인 후, 앱으로 돌아와야 하는데, 이 때 돌아올 앱을 가리킬 수 있는 키가 URL Scheme.
타겟 - Info - URL Types 에서 등록해 줘야 한다.
Identifier 에는 번들 아이디를 넣고, URL Schemes 에는 적당한 값을 넣어주면 된다.
그리고 이 값은 곧, 네이버에 등록한 내 애플리케이션의 URL Scheme 와, 위의 헤더에 들어갈 kUrlSampleAppUrlScheme가 된다.
나는 심플하게 앱 이름으로. ㅎㅎㅎ
5. AppDelegate 설정
네이버 로그인 API를 사용하기 위해 앱을 기동할 때 몇 가지 값을 설정해줘야 하는데, 그것들은 아래와 같다.
// application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) 내에 설정
// Initialize Naver SignIn
let loginConn = NaverThirdPartyLoginConnection.getSharedInstance()
// 네이버앱으로 로그인 (네이버앱 미설치시, 앱 내 사파리 연결)
loginConn?.isNaverAppOauthEnable = true
// 헤더에서 설정한 앱 설정값 할당
loginConn?.serviceUrlScheme = kServiceAppUrlScheme
loginConn?.consumerKey = kConsumerKey
loginConn?.consumerSecret = kConsumerSecret
loginConn?.appName = kServiceAppName
// 화면 가로 회전 차단하기
loginConn?.setOnlyPortraitSupportInIphone(true)
그리고 아래는 로그인 실패 혹은 로그인을 거부했을 때 호출되는 메소드다.
로그인이 성공하면 호출이 안된다?
왜지... 네이버 뷰 컨트롤러에서 url을 오픈하면 항상 호출되어야 하는 거 아닌가....
라는 궁금증은 아직 미해결.
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
printDebug(message: url)
var naverSignInResult = false
if url.scheme == kServiceAppUrlScheme {
if url.host == kCheckResultPage {
let loginConn = NaverThirdPartyLoginConnection.getSharedInstance()
let resultType = loginConn?.receiveAccessToken(url)
if resultType == SUCCESS {
printDebug(message: "Naver login success")
naverSignInResult = true
} else {
printDebug(message: "ERROR : Naver Sign In Failed")
}
}
}
return naverSignInResult
}
6. 로그인
대충 버튼을 하나 만들고.
class viewController: UIViewController, NaverThirdPartyLoginConnectionDelegate {
@IBAction func onTapNaverSignIn(_ sender: UIButton) {
let loginConn = NaverThirdPartyLoginConnection.getSharedInstance()
loginConn?.delegate = self
loginConn?.requestThirdPartyLogin()
}
// 로그인 토큰이 없는 경우, 로그인 화면을 오픈한다.
func oauth20ConnectionDidOpenInAppBrowser(forOAuth request: URLRequest!) {
// Open Naver SignIn View Controller
let naverSignInViewController = NLoginThirdPartyOAuth20InAppBrowserViewController(request: request)!
present(naverSignInViewController, animated: true, completion: nil)
}
// ------------------------로그인 완료시 호출
// 로그인 토큰이 없는 경우
func oauth20ConnectionDidFinishRequestACTokenWithRefreshToken() {
getNaverEmailFromURL()
}
// 로그인 토큰이 있는 경우
func oauth20ConnectionDidFinishRequestACTokenWithAuthCode() {
getNaverEmailFromURL()
}
}
네이버로그인은 앱이 없는 경우, 로그인화면을 직접 오픈해줘야 하더라.
- oauth20ConnectionDidOpenInAppBrowser
그리고 로그인 완료 후 호출되는 메소드가 로그인 동작 전에 로그인 토큰이 있었던 경우와 없었던 경우가 달랐다!
- oauth20ConnectionDidFinishRequestACTokenWithRefreshToken
- oauth20ConnectionDidFinishRequestACTokenWithAuthCode
그래서 두 메소드 모두 같은 동작을 수행하도록 사용자 정보를 가져오는 메소드를 따로 분류.
그리고 난 로그인 팝업을 항상 열도록 할거기 땜에 로그인 완료 후 토큰 삭제! (는 사실 아래 메소드로 분리..)
7. 사용자 정보 가져오기
사용자 정보 중 대표적으로 이메일을 가져와 보자.
이 방법을 찾는데 꽤 애를 먹었는데,
http://developer.naver.com/wiki/pages/NaverLogin_spec
이 페이지의 6.1 네이버 사용자 기본 정보 조회 - 인증 요청문 명세 에 있었다...
실제로 사용자의 정보가 담겨있는 데이터는 str 이라고 지정한 String.
이것을 (내가 만든) xmlParser 라는 메소드에 넣고 파싱한다.
이메일 외 다른 파라미터를 가져오고 싶다면, "email" 외에 네이버에서 지정한 다른 파라미터 키를 넣어주면 된다.
이것 역시 위 링크를 참조.
func getNaverEmailFromURL() {
// Naver SignIn Success
let loginConn = NaverThirdPartyLoginConnection.getSharedInstance()
let tokenType = loginConn?.tokenType
let accessToken = loginConn?.accessToken
// Get User Profile
if let url = URL(string: "https://apis.naver.com/nidlogin/nid/getUserProfile.xml") {
if tokenType != nil && accessToken != nil {
let authorization = "\(tokenType!) \(accessToken!)"
var request = URLRequest(url: url)
request.setValue(authorization, forHTTPHeaderField: "Authorization")
let dataTask = URLSession.shared.dataTask(with: request) {(data, response, error) in
if let str = String(data: data!, encoding: .utf8) {
var email = CommonUtil().xmlParser(xml: str, title: "email")
email = email.components(separatedBy: "[")[2].components(separatedBy: "]")[0]
self.printDebug(message: "Naver email : " + email)
// Naver Sign Out
loginConn?.resetToken()
}
}
dataTask.resume()
}
}
}
사실 이건... 과잉친절같지만....
암튼 그러면 끝 ㅎㅎㅎㅎ
아.
printDebug(message: Any) 역시 간편한 디버깅을 위해 자체제작한 메소드입니다.
'Development > Solutions' 카테고리의 다른 글
CXErrorCodeCallDirectoryManagerError (0) | 2018.04.13 |
---|---|
[Swift3] 그림자를 만들자 (0) | 2017.02.08 |
[iOS - swift] 구글 로그인 달기 (1) | 2016.10.21 |
퀵 정렬 알고리즘 (Quick Sort) (0) | 2016.10.18 |
WRITTEN BY
- minjee
우리는 무엇을 할 수 있을까?