Skip to content

hyun99999/KakaoLoginTutorial-iOS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

12 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

KakaoLoginTutorial-iOS

๐Ÿ‘ทโ€โ™€๏ธ login tutorial using Kakao iOS SDK

๋ชฉ์ฐจ

๋””์ž์ธ ๊ฐ€์ด๋“œ

์• ํ”Œ ๋กœ๊ทธ์ธ๊ณผ ๋™์ผํ•˜๊ฒŒ ์นด์นด์˜ค๋„ ์—ญ์‹œ ๋””์ž์ธ ๊ฐ€์ด๋“œ๊ฐ€ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ PNG ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ํ•  ์ˆ˜ ์žˆ๋‹ค.

Kakao Developers design-guide

๊ทธ๋Ÿฌ๋ฉด ๋ณธ๊ฒฉ์ ์œผ๋กœ ์‹œ์ž‘ํ•˜๊ธฐ์ „์— ์„ค์ •๋‹จ๊ณ„๋ฅผ ์•Œ์•„๋ณด์ž. ์•„๋ž˜์˜ ๋‚ด์šฉ๋“ค์€ ์นด์นด์˜ค ๊ฐœ๋ฐœ์ž๋ฌธ์„œ๋ฅผ ์š”์•ฝ + ์‹ค์Šต์ด๋‹ค.

์„ค์ •๋‹จ๊ณ„

1๏ธโƒฃ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก

์นด์นด์˜ค API๋Š” ๊ฐœ๋ฐœ์ž ์›น์‚ฌ์ดํŠธ์— ๋“ฑ๋ก๋œ ๊ฐ๊ฐ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์ดํ•˜ ์•ฑ) ์ •๋ณด ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋ฏ€๋กœ, ์นด์นด์˜ค API๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๊ฐœ๋ฐœ์ž ์›น์‚ฌ์ดํŠธ์— ์•ฑ์„ ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์•ฑ ๋งŒ๋“ค๊ธฐ

์นด์นด์˜ค API ์‚ฌ์šฉ์„ ์œ„ํ•ด ๊ฐœ๋ฐœ์ž ์›น์‚ฌ์ดํŠธ์—์„œ ์•ฑ์„ ๋งŒ๋“ค๊ณ , ํ•ด๋‹น ์•ฑ์— ์„œ๋น„์Šค ์ด๋ฆ„๊ณผ ํšŒ์‚ฌ๋ช…, ์•„์ด์ฝ˜ ๋“ฑ ์ •๋ณด๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ ์ •๋ณด๋Š” ์„œ๋น„์Šค ์ด๋ฆ„, ์ œ3์ž ์ •๋ณด์ œ๊ณต๋™์˜ ๋“ฑ ๋ฒ•์ ์ธ ์‚ฌํ•ญ๊ณผ๋„ ๊ด€๋ จ์ด ์žˆ์œผ๋ฏ€๋กœ ์‹ค์ œ ์„œ๋น„์Šค์™€ ๊ฐ™์€ ๋‚ด์šฉ์œผ๋กœ ๊ตฌ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ์ž ์›น์‚ฌ์ดํŠธ์—์„œ ๋กœ๊ทธ์ธํ•œ ํ›„, [๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜] > [์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ]๋ฅผ ๋ˆŒ๋Ÿฌ ์•ฑ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์นด์นด์˜ค๊ณ„์ • ๋กœ๊ทธ์ธ

3

ํ‚ค ๊ฐ’ ํ™•์ธ

์•ฑ์„ ์ƒ์„ฑํ•˜๋ฉด ํ”Œ๋žซํผ๋ณ„ ์•ฑ ํ‚ค(App Key)๊ฐ€ ๋ฐœ๊ธ‰๋ฉ๋‹ˆ๋‹ค.

Kakao SDK for JavaScript(์ดํ•˜ JavaScript SDK)์—๋Š” JavaScript ํ‚ค, iOS์™€ Android์—๋Š” ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ ํ‚ค, HTTP ์š”์ฒญ์ด๋‚˜ ์„œ๋ฒ„ ๊ธฐ๋Šฅ ๊ตฌํ˜„์—๋Š” REST API ํ‚ค๋ฅผ ๊ฐ๊ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์•ฑ ํ‚ค์™€ ํ•จ๊ป˜ ์–ด๋“œ๋ฏผ ํ‚ค(Admin Key)๋„ ํ•จ๊ป˜ ๋ฐœ๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์–ด๋“œ๋ฏผ ํ‚ค๋Š” ์‚ฌ์šฉ์ž ๋ชฉ๋ก ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ๊ฐ™์€ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

4

ํ”Œ๋žซํผ ๋“ฑ๋ก

๋“ฑ๋กํ•œ ์•ฑ์—์„œ API๋ฅผ ํ˜ธ์ถœํ•˜๋ ค๋ฉด ์‚ฌ์šฉํ•˜๋ ค๋Š” ํ”Œ๋žซํผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐœ๋ฐœ์ž ์›น์‚ฌ์ดํŠธ์— ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

5

iOS ํ”Œ๋žซํผ์—๋Š” ๋‹ค์Œ ์ •๋ณด๋ฅผ ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฒˆ๋“ค ID(Bundle ID): iOS ์•ฑ์˜ ๊ณ ์œ  ๊ฐ’์ž…๋‹ˆ๋‹ค. Xcode์˜ ํ”„๋กœ์ ํŠธ ์ •๋ณด์— ์„ค์ •๋œ Bundle Identifier ๊ฐ’๊ณผ ๋™์ผํ•œ ๊ฐ’์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • ์•ฑ์Šคํ† ์–ด ID(Appstore ID): ์• ํ”Œ ์•ฑ์Šคํ† ์–ด ๋“ฑ๋ก ์‹œ ๋ฐœ๊ธ‰๋ฐ›์€ ์•ฑ ID์ž…๋‹ˆ๋‹ค.
  • ๋งˆ์ผ“ URL(Market URL): ์‚ฌ์šฉ์ž์˜ ๊ธฐ๊ธฐ์—์„œ ์•ฑ์„ ์‹คํ–‰์‹œํ‚ฌ ๋•Œ, ์‚ฌ์šฉ์ž์˜ ๊ธฐ๊ธฐ์— ํ•ด๋‹น ์•ฑ์ด ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์„ ๊ฒฝ์šฐ ์ด๋™ํ•  ์•ฑ์Šคํ† ์–ด ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ์นด์นด์˜ค๋งํฌ API๋‚˜ ์นด์นด์˜คํ†ก ๋ฉ”์‹œ์ง€ API๋ฅผ ํ†ตํ•ด ์ „์†ก๋œ ๋ฉ”์‹œ์ง€์—์„œ ์•ฑ์„ ์‹คํ–‰์‹œํ‚ค๋Š”ย ๋งํฌ๋ฅผ ๋ˆŒ๋ €์„ ๋•Œ, ์•ฑ ์‹คํ–‰์„ ์š”์ฒญํ•œ ์‚ฌ์šฉ์ž์˜ ๊ธฐ๊ธฐ์— ํ•ด๋‹น ์•ฑ์ด ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฉด ์ง€์ •ํ•œ ๋งˆ์ผ“ URL ์ฃผ์†Œ๋กœ ์ด๋™ํ•˜์—ฌ ํ•ด๋‹น ์•ฑ์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ์Šคํ† ์–ด ID๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋งˆ์ผ“ URL์ด ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

์ถœ์ฒ˜ :

Kakao Developers getting-started/app

2๏ธโƒฃ CocoaPods ํ†ตํ•ด ๋ชจ๋“ˆ ์„ค์น˜

# ์ „์ฒด ์ถ”๊ฐ€
pod 'KakaoSDK'

# or

# ํ•„์š”ํ•œ ๋ชจ๋“ˆ ์ถ”๊ฐ€
pod 'KakaoSDKCommon'  # ํ•„์ˆ˜ ์š”์†Œ๋ฅผ ๋‹ด์€ ๊ณตํ†ต ๋ชจ๋“ˆ
pod 'KakaoSDKAuth'  # ์‚ฌ์šฉ์ž ์ธ์ฆ
pod 'KakaoSDKUser'  # ์นด์นด์˜ค ๋กœ๊ทธ์ธ, ์‚ฌ์šฉ์ž ๊ด€๋ฆฌ
pod 'KakaoSDKTalk'  # ์นœ๊ตฌ, ๋ฉ”์‹œ์ง€(์นด์นด์˜คํ†ก)
pod 'KakaoSDKStory'  # ์นด์นด์˜ค์Šคํ† ๋ฆฌ 
pod 'KakaoSDKLink'  # ๋ฉ”์‹œ์ง€(์นด์นด์˜ค๋งํฌ)
pod 'KakaoSDKTemplate'  # ๋ฉ”์‹œ์ง€ ํ…œํ”Œ๋ฆฟ 
pod 'KakaoSDKNavi'  # ์นด์นด์˜ค๋‚ด๋น„

์ด๋ฟ๋งŒ ์•„๋‹ˆ๋ผ RxSwift ๋„ ์ง€์›ํ•œ๋‹ค.

๋กœ๊ทธ์ธ์„ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ •ํ™•ํžˆ ์–ด๋– ํ•œ ๋ชจ๋“ˆ์ด ํ•„์š”ํ•œ์ง€ ํ—ท๊ฐˆ๋ ค์„œ pod 'KakaoSDKUser' ๋งŒ ์ ์–ด์ฃผ์—ˆ๋”๋‹ˆ ์ด๊ฒƒ ์™ธ์—๋„ ์ž๋™์œผ๋กœ ํ•„์š”ํ•œ ๋ชจ๋“ˆ์ด install ๋˜์—ˆ๋‹ค. ๋‚˜์™€ ๊ฐ™์€ ๊ณ ๋ฏผ์œผ๋กœ ๊ฑฑ์ •ํ•˜์ง€ ์•Š์•„๋„ ๋  ๊ฒƒ ๊ฐ™๋‹ค.

1

3๏ธโƒฃ Info.plist ์„ค์ •

์•ฑ ์‹คํ–‰ ํ—ˆ์šฉ ๋ชฉ๋ก ๋“ฑ๋กํ•˜๊ธฐ

iOS 9.0 ์ด์ƒ์—์„œ iOS SDK๋ฅผ ํ†ตํ•ด ์นด์นด์˜คํ†ก์ด๋‚˜ ์นด์นด์˜ค์Šคํ† ๋ฆฌ, ์นด์นด์˜ค๋‚ด๋น„ ๋“ฑ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์ดํ•˜ ์•ฑ)์„ ์‹คํ–‰์‹œํ‚ค๋Š” ๊ธฐ๋Šฅ์„ ์ด์šฉํ•˜๋ ค๋ฉด Info.plist ํŒŒ์ผ์— ์„ค์ •์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ปค์Šคํ…€ ์Šคํ‚ด ์ •๋ณด๋ฅผ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

(์•ฑ์—์„œ ์นด์นด์˜คํ†ก์•ฑ์„ ์‹คํ–‰์‹œ์ผœ ๋กœ๊ทธ์ธ ํ•˜๋Š” ๊ฒƒ๊ณผ ์›น์„ ํ†ตํ•ด ์นด์นด์˜ค ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ ํ•˜๋Š” ๊ฒƒ ๋‘˜๋‹ค ํ•ด๋ณผ ๊ฒƒ์ด๋‹ค.)

[Info] > [Custom iOS Target Properties]์— Array ํƒ€์ž… ํ‚ค(Key)์ธ LSApplicationQueriesSchemes๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ , ํ•ด๋‹น ํ‚ค์˜ 'Item'์œผ๋กœ ์ปค์Šคํ…€ ์Šคํ‚ด์— ์‚ฌ์šฉํ•  ๊ฐ’์ธ 'kakaokompassauth', 'kakaolink'๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

5

์œ„ ์„ค์ •์€ Info.plist ๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•ด์„œ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

<key>LSApplicationQueriesSchemes</key>
  <array>
      <!-- ์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ -->
      <string>kakaokompassauth</string>
      <!-- ์นด์นด์˜ค๋งํฌ -->
      <string>kakaolink</string>
  </array>

URL Schemes ์„ค์ •ํ•˜๊ธฐ

์นด์นด์˜ค๊ณ„์ •์„ ํ†ตํ•œ ์ธ์ฆ๊ณผ ์นด์นด์˜คํ†ก ๋ฉ”์‹œ์ง€๋ฅผ ํ†ตํ•œ ์•ฑ ์‹คํ–‰์„ ์œ„ํ•ด URL Schemes ์„ค์ •์„ ํ•ฉ๋‹ˆ๋‹ค.

[Info] > [URL Types] > [URL Schemes] ํ•ญ๋ชฉ์— ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ ํ‚ค(Native App Key)๋ฅผ kakao{NATIVE_APP_KEY} ํ˜•์‹์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

(์•ฑ ๋“ฑ๋กํ•  ๋•Œ ๋ฐœ๊ธ‰๋ฐ›์•˜๋˜ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ ํ‚ค๋ฅผ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.)

6

4๏ธโƒฃ ์ดˆ๊ธฐํ™”

iOS ์•ฑ์—์„œ iOS SDK๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด iOS SDK ํŒŒ์ผ์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž„ํฌํŠธ(import)ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋„ค์ดํ‹ฐ๋ธŒ ์•ฑ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•ด iOS SDK๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. AppDelegate.swift์— Kakao SDK๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

import KakaoSDKCommon

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

  ...
  KakaoSDKCommon.initSDK(appKey: "NATIVE_APP_KEY")
  ...

}

์ถœ์ฒ˜ :

Kakao Developers getting-started/sdk-ios

์‹œ์ž‘ํ•˜๊ธฐ ์ „

๋‘๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋กœ๊ทธ์ธ์„ ํ•œ๋‹ค๊ณ  ์˜ˆ๊ณ ํ–ˆ๋Š”๋ฐ ์ž์„ธํžˆ ์•Œ์•„๋ณด์ž.

์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ

์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์นด์นด์˜คํ†ก์— ์—ฐ๊ฒฐ๋œ ์นด์นด์˜ค๊ณ„์ • ๋ฐ ์ธ์ฆ ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์นด์นด์˜ค๊ณ„์ • ์ •๋ณด๋ฅผ ์ง์ ‘ ์ž…๋ ฅํ•˜์ง€ ์•Š์•„๋„ ๊ฐ„ํŽธํ•˜๊ฒŒ ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ์–ด ๋ณด๋‹ค ๊ถŒ์žฅ๋˜๋Š” ์ธ์ฆ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์›น ๋ธŒ๋ผ์šฐ์ €(Default Browser)๋ฅผ ํ†ตํ•ด ์นด์นด์˜ค๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ

๊ธฐ๋ณธ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด ์นด์นด์˜ค๊ณ„์ • ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ๋กœ๊ทธ์ธํ•  ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž๊ฐ€ ์นด์นด์˜ค๊ณ„์ • ์ •๋ณด๋ฅผ ์ง์ ‘ ์ž…๋ ฅํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ์‚ฌ์šฉ์ž๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์นด์นด์˜ค๊ณ„์ •์„ ์‚ฌ์šฉํ•˜๋Š” ์„œ๋น„์Šค๋‚˜ ์นด์นด์˜คํ†ก์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋””๋ฐ”์ด์Šค์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๊ฐ ์ธ์ฆ ๋ฐฉ๋ฒ•์˜ ํŠน์ง•๊ณผ ์„œ๋น„์Šค์˜ ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ๋™์„ ์„ ๊ณ ๋ คํ•˜์—ฌ ์–ด๋Š ์ธ์ฆ ๋ฐฉ๋ฒ•์ด ์ ํ•ฉํ•œ์ง€ ํŒ๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๊ฐ€์ง€ ์ธ์ฆ ๋ฐฉ๋ฒ•์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ธ์ฆ ๋ฐฉ๋ฒ•์— ๋”ฐ๋ผ ํ•„์š”ํ•œ ์„ค์ •์ด๋‚˜ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์— ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

โ—๏ธ ์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ์„ ์œ„ํ•œ ์„ค์ •

์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ํ•„์ˆ˜ ์„ค์ •์ž…๋‹ˆ๋‹ค.

์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ์€ ์„œ๋น„์Šค ์•ฑ์—์„œ ์นด์นด์˜คํ†ก์œผ๋กœ ์ด๋™ํ•œ ํ›„, ์‚ฌ์šฉ์ž๊ฐ€ [๋™์˜ํ•˜๊ณ  ๊ณ„์†ํ•˜๊ธฐ] ๋ฒ„ํŠผ ๋˜๋Š” ๋กœ๊ทธ์ธ ์ทจ์†Œ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋‹ค์‹œ ์นด์นด์˜คํ†ก์—์„œ ์„œ๋น„์Šค ์•ฑ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ณผ์ •์„ ๊ฑฐ์นฉ๋‹ˆ๋‹ค.

  • SceneDelegate.swift ํŒŒ์ผ์— handleOpenUrl()์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
import KakaoSDKAuth
...

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    ...
    func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
        if let url = URLContexts.first?.url {
            if (AuthApi.isKakaoTalkLoginUrl(url)) {
                _ = AuthController.handleOpenUrl(url: url)
            }
        }
    }
    ...
}

์‹œ์ž‘ํ•˜๊ธฐ

  • Main.storyboard

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์Šคํ† ๋ฆฌ๋ณด๋“œ์—์„œ ์‹ค์Šตํ•  ๊ฒƒ์ด๋‹ค.

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2021-08-16 แ„‹แ…ฉแ„’แ…ฎ 3 41 51

๐Ÿ“Œ ์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ

1๏ธโƒฃ ๊ธฐ๋Šฅ๊ตฌํ˜„

// โœ… ๋ชจ๋“ˆ ์ถ”๊ฐ€
import KakaoSDKUser

// ...

// โœ… ์นด์นด์˜ค๋กœ๊ทธ์ธ ์ด๋ฏธ์ง€์— UITapGestureRecognizer ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ ์‚ฌ์šฉํ•  @objc ๋ฉ”์„œ๋“œ.
// โœ… ์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ
    @objc
    func loginKakao() {
        print("loginKakao() called.")
        
        // โœ… ์นด์นด์˜คํ†ก ์„ค์น˜ ์—ฌ๋ถ€ ํ™•์ธ
        if (UserApi.isKakaoTalkLoginAvailable()) {
            UserApi.shared.loginWithKakaoTalk {(oauthToken, error) in
                if let error = error {
                    print(error)
                }
                else {
                    print("loginWithKakaoTalk() success.")
                    
                    // โœ… ํšŒ์›๊ฐ€์ž… ์„ฑ๊ณต ์‹œ oauthToken ์ €์žฅ๊ฐ€๋Šฅํ•˜๋‹ค
                    // _ = oauthToken
                    
                    // โœ… ์‚ฌ์šฉ์ž์ •๋ณด๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ํ™”๋ฉด์ „ํ™˜ ํ•œ๋‹ค.
                    self.getUserInfo()
                }
            }
        }
        // โœ… ์นด์นด์˜คํ†ก ๋ฏธ์„ค์น˜
        else {
            print("์นด์นด์˜คํ†ก ๋ฏธ์„ค์น˜")
        }
    }

์นด์นด์˜คํ†ก์ด ์„ค์น˜๋˜์žˆ์ง€ ์•Š์œผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ค๋ฅ˜๋ฅผ ๋ณด์—ฌ์ค€๋‹ค. ํ•ธ๋“œํฐ์— ์—ฐ๊ฒฐํ•ด์„œ ์‹ค์Šตํ•ด์•ผํ•œ๋‹ค.

7

2๏ธโƒฃ ํ•ธ๋“œํฐ์—์„œ ๋นŒ๋“œ

์ฒ˜์Œ์— ์‹œ๋„ํ•˜๋ฉด ์ด๋Ÿฐ ํ™”๋ฉด์ด ๋‚˜์˜ฌํ…๋ฐ Kakao developers ์˜ [๋‚ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜] > [์ œํ’ˆ์„ค์ •] > [์นด์นด์˜ค ๋กœ๊ทธ์ธ] ์—์„œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ์„ ํ™œ์„ฑํ™”๋ฅผ ํ•ด์ฃผ์–ด์•ผ๋งŒ ์‹ค์ œ ์„œ๋น„์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

10

์ด์™€ ๊ฐ™์ด ํ™œ์„ฑํ™”๋ฅผ ํ•ด์ฃผ๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋กœ๊ทธ์ธ ํ™”๋ฉด์ด ๋ณด์—ฌ์ง„๋‹ค.

๐Ÿ“Œ ์นด์นด์˜ค๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ

1๏ธโƒฃ ๊ธฐ๋Šฅ๊ตฌํ˜„

// โœ… ๋ชจ๋“ˆ ์ถ”๊ฐ€
import KakaoSDKUser

// ...

// โœ… ์นด์นด์˜ค๋กœ๊ทธ์ธ ์ด๋ฏธ์ง€์— UITapGestureRecognizer ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ ์‚ฌ์šฉํ•  @objc ๋ฉ”์„œ๋“œ.
// โœ… ์นด์นด์˜ค๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ
    @objc
    func loginKakaoAccount() {
        print("loginKakaoAccount() called.")
        
        // โœ… ๊ธฐ๋ณธ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊ทธ์ธ ์ง„ํ–‰.
        UserApi.shared.loginWithKakaoAccount {(oauthToken, error) in
            if let error = error {
                print(error)
            }
            else {
                print("loginWithKakaoAccount() success.")
                
                // โœ… ํšŒ์›๊ฐ€์ž… ์„ฑ๊ณต ์‹œ oauthToken ์ €์žฅ
                // _ = oauthToken
                
                // โœ… ์‚ฌ์šฉ์ž์ •๋ณด๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ํ™”๋ฉด์ „ํ™˜ ํ•œ๋‹ค.
                self.getUserInfo()
            }
        }
    }

์นด์นด์˜ค๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ๋„ ์ž˜๋˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด๊ฒ ๋‹ค.

๐Ÿ“Œ ๋™์˜ ํ•ญ๋ชฉ ์„ค์ •

์ฒ˜์Œ์—๋Š” ๋™์˜ํ•ญ๋ชฉ์ด ํ•˜๋‚˜๋„ ์„ค์ •๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ Kakao Developer ์—์„œ ์„ค์ •๊ฐ€๋Šฅํ•˜๋‹ค.

แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2021-08-16 แ„‹แ…ฉแ„’แ…ฎ 3 09 40

์ด๋ฉ”์ผ ๊ฒฝ์šฐ๋Š” ํ•„์ˆ˜๋™์˜๋ฅผ ๋ฐ›๊ธฐ์œ„ํ•ด์„œ๋Š” ๊ฒ€์ˆ˜๋ฅผ ํ•„์š”ํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‹‰๋„ค์ž„์€ ํ•„์ˆ˜๋™์˜, ์ด๋ฉ”์ผ์€ ์„ ํƒ๋™์˜๋กœ ๋™์˜๋ฅผ ๋ฐ›์•„๋ณด๊ฒ ๋‹ค.

๐Ÿ“Œ ๋กœ๊ทธ์•„์›ƒ & ์—ฐ๊ฒฐ ๋Š๊ธฐ

  • ๋กœ๊ทธ์•„์›ƒ : ๋กœ๊ทธ์•„์›ƒ API๋Š” ํ† ํฐ์„ ์‚ญ์ œํ•˜์—ฌ, ๋” ์ด์ƒ ํ•ด๋‹น ์‚ฌ์šฉ์ž ์ •๋ณด๋กœ ์นด์นด์˜ค API๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

  • ์—ฐ๊ฒฐ๋Š๊ธฐ : ์—ฐ๊ฒฐ ๋Š๊ธฐ API๋Š” ์นด์นด์˜ค ํ”Œ๋žซํผ ์•ˆ์—์„œ ์•ฑ๊ณผ ์‚ฌ์šฉ์ž ์นด์นด์˜ค๊ณ„์ •์˜ ์—ฐ๊ฒฐ ์ƒํƒœ๋ฅผ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

  • LogoutViewController.swift

import UIKit
import KakaoSDKUser

class LogoutViewController: UIViewController {
    
    // ...
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // ...
    }

    @IBAction func logoutClicked(_ sender: Any) {
        
        // โœ… ๋กœ๊ทธ์•„์›ƒ : ๋กœ๊ทธ์•„์›ƒ์€ API ์š”์ฒญ์˜ ์„ฑ๊ณต ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ํ† ํฐ์„ ์‚ญ์ œ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•ฉ๋‹ˆ๋‹ค.
        UserApi.shared.logout {(error) in
            if let error = error {
                print(error)
            }
            else {
                print("logout() success.")
                
                // โœ… ๋กœ๊ทธ์•„์›ƒ ์‹œ ๋ฉ”์ธ์œผ๋กœ ๋ณด๋ƒ„
                self.navigationController?.popViewController(animated: true)
            }
        }
    }
    @IBAction func unlinkClicked(_ sender: Any) {
        
        // โœ… ์—ฐ๊ฒฐ ๋Š๊ธฐ : ์—ฐ๊ฒฐ์ด ๋Š์–ด์ง€๋ฉด ๊ธฐ์กด์˜ ํ† ํฐ์€ ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ์—ฐ๊ฒฐ ๋Š๊ธฐ API ์š”์ฒญ ์„ฑ๊ณต ์‹œ ๋กœ๊ทธ์•„์›ƒ ์ฒ˜๋ฆฌ๊ฐ€ ํ•จ๊ป˜ ์ด๋ค„์ ธ ํ† ํฐ์ด ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.
        UserApi.shared.unlink {(error) in
            if let error = error {
                print(error)
            }
            else {
                print("unlink() success.")
                
                // โœ… ์—ฐ๊ฒฐ๋Š๊ธฐ ์‹œ ๋ฉ”์ธ์œผ๋กœ ๋ณด๋ƒ„
                self.navigationController?.popViewController(animated: true)
            }
        }
    }
}

extension LogoutViewController {
    // ...
}

๐Ÿ“Œ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ

๋‹‰๋„ค์ž„(user.kakaoAccount.profile.nickname)๊ณผ ์ด๋ฉ”์ผ(user.kakaoAccount.email)์„ ๊ฐ€์ ธ์™€ ๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

extension LoginViewController {

// โœ… ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์˜ค๋ฉด ํ™”๋ฉด์ „ํ™˜ ํ•œ๋‹ค.
    private func getUserInfo() {

        // โœ… ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ
        UserApi.shared.me() {(user, error) in
            if let error = error {
                print(error)
            }
            else {
                print("me() success.")
                
                // โœ… ๋‹‰๋„ค์ž„, ์ด๋ฉ”์ผ ์ •๋ณด
                let nickname = user?.kakaoAccount?.profile?.nickname
                let email = user?.kakaoAccount?.email
                
                guard let nextVC = self.storyboard?.instantiateViewController(withIdentifier: "LogoutViewController") as? LogoutViewController else { return }
                
                // โœ… ์‚ฌ์šฉ์ž ์ •๋ณด ๋„˜๊ธฐ๊ธฐ
                nextVC.nickname = nickname
                nextVC.email = email

                // โœ… ํ™”๋ฉด์ „ํ™˜
                self.navigationController?.pushViewController(nextVC, animated: true)
            }
        }
    }
}

๊ฐ ํ•ญ๋ชฉ์˜ ์ž๋ฃŒํ˜• ๋“ฑ์€ ์•„๋ž˜๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

Kakao Developers

๐Ÿ“Œ ํ† ํฐ ์กด์žฌ ์—ฌ๋ถ€ ํ™•์ธํ•˜๊ธฐ

ํ† ํฐ์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด์„œ ์•ฑ ์‹คํ–‰ ์‹œ ํšŒ์›๊ฐ€์ž…์„ ์‹œํ‚ฌ์ง€ ๋ฉ”์ธํ™”๋ฉด์œผ๋กœ ๋ณด๋‚ผ์ง€ ๋ถ„๊ธฐ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ๋ทฐ๊ฐ€ ๋‹ค ๋ณด์—ฌ์ง„ ํ›„ ํ† ํฐ์„ ๊ฒ€์‚ฌํ•ด์„œ ์œ ํšจ์„ฑ์ด ํ™•์ธ๋˜๋ฉด ๋กœ๊ทธ์ธ๋œ ํ™”๋ฉด์œผ๋กœ ์ „ํ™˜ํ•ด์ฃผ์—ˆ๋‹ค. (AppDelegate.swift ์—์„œ ์•ฑ ์‹คํ–‰ ์‹œ ์ฒซ ํ™”๋ฉด์˜ ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด์„œ ์‚ฌ์šฉํ•ด์ฃผ์–ด๋„ ๋œ๋‹ค.)
import UIKit
// โœ… ๋ชจ๋“ˆ ์ถ”๊ฐ€
import KakaoSDKUser
import KakaoSDKAuth
import KakaoSDKCommon

class LoginViewController: UIViewController {

// ...

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // โœ… ์œ ํšจํ•œ ํ† ํฐ ๊ฒ€์‚ฌ
        if (AuthApi.hasToken()) {
            UserApi.shared.accessTokenInfo { (_, error) in
                if let error = error {
                    if let sdkError = error as? SdkError, sdkError.isInvalidTokenError() == true  {
                        //๋กœ๊ทธ์ธ ํ•„์š”
                    }
                    else {
                        //๊ธฐํƒ€ ์—๋Ÿฌ
                    }
                }
                else {
                    //ํ† ํฐ ์œ ํšจ์„ฑ ์ฒดํฌ ์„ฑ๊ณต(ํ•„์š” ์‹œ ํ† ํฐ ๊ฐฑ์‹ ๋จ)
                    // โœ… ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ํ™”๋ฉด์ „ํ™˜์„ ํ•˜๋Š” ์ปค์Šคํ…€ ๋ฉ”์„œ๋“œ
                    self.getUserInfo()
                }
            }
        }
        else {
            //๋กœ๊ทธ์ธ ํ•„์š”
        }
    }
}

์ถœ์ฒ˜ :

Kakao Developers kakaologin/ios

About

๐Ÿ‘ทโ€โ™€๏ธ login tutorial using Kakao iOS SDK

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published