[TIL] 10.16

Junyoung_Hong·2023년 10월 16일
0

TIL_10월

목록 보기
9/20
post-thumbnail

1. 카카오톡 로그인 구현하기

옛날에 시도를 했었지만 실패를 했었던 카카오톡 로그인을 구현하고자 한다.

1-1. Kakao Developers에 등록

카카오톡 로그인을 구현하기 위해서는 우선 Kakao Developers에 적용시키고 싶은 프로젝트를 등록해야 한다.

https://developers.kakao.com/

등록하는 방법은 다른 분이 너무 자세하게 잘 설명해주셔서 참고하면 좋을 것 같다.

참고 Medium

1-2. SDK 설치하기

Cocoapod를 이용한 방법과 SPM을 이용하는 방법이 있는데, 선호하는 방식으로 설치를 하면 될 것 같다. 지금은 SPM으로 진행을 해보겠다.

https://github.com/kakao/kakao-ios-sdk

검색부분에 깃허브 주소를 넣으면 설치를 할 수 있다.

공식문서를 참고해도 좋다.

https://developers.kakao.com/docs/latest/ko/ios/getting-started

1-3. info.plist에 등록

공식문서나 다른 블로그에서 LSApplicationQueriesSchemes 를 등록하라고 해서 등록을 했더니 Queried URL Schemes 로 자동으로 변해진다. Xcode 15.0 버전에서 부터 바뀌었는지, 잘 모르겠다.

1-4. URL Schemes 설정하기

info.plist에 등록을 하고, 아래쪽을 보면 URL Types 항목을 볼 수 있다. 여기에서 Native App Key를 등록해야 한다.

Native App Key는 Kakao Developers 페이지에서 확인 할 수 있다.

빨강색 부분에 있는 문자열이 키이다. 이 앱 키를 URL Types에서 + 버튼을 눌러서 나온 항목중에 URL Schemes에 넣으면 된다.

1-5. 초기화

AppDelegate.swift 파일에서 Kakao SDK를 초기화하는 코드를 추가하자.

원래는 apiKey 에 앞에서 계속 사용했던 앱 키를 넣어야 한다.

KakaoSDK.initSDK(appKey: "123456")

123456자리에 앱 키를 넣어야 하는 것이다. 그렇지만 GitHub를 사용할 때, apiKey를 같이 push 하는 것은 상당히 위험하다. 따라서 apiKey라는 파일을 따로 만들어서 관리를 하는 것이 좋다. 물론 이 파일은 gitignore에 추가해야 한다.

1-6. 사용자 인증에 필요한 함수 추가

이 부분은 iOS 버전이 13.0 이전이냐 이후냐에 따라 달라진다.

iOS 13.0 이전

AppDelegate에 handelOpenUrl() 를 추가해주면 된다.

import KakaoSDKAuth
...

class AppDelegate: UIResponder, UIApplicationDelegate {
    ...
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        if (AuthApi.isKakaoTalkLoginUrl(url)) {
            return AuthController.handleOpenUrl(url: url)
        }

        return false
    }
    ...
}

iOS 13.0 이후

AppDelegate.swift 파일 대신 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)
            }
        }
    }
    ...
}

1-7. 버튼에 로그인 함수 추가하기

우선 로그인을 진행하기 위한 두가지 버튼을 추가했다. Kakao에서는 앱으로 로그인하는 방식을 추천하지만, 시뮬레이터에 카카오톡이 깔려있지 않기 때문에 Web으로 접근을 해서 계정으로 로그인하는 버튼도 추가를 했다.

앱으로 로그인하기

사실 공식문서에서 제공하는 코드를 넣으면 끝이다.

// 카카오톡 실행 가능 여부 확인
if (UserApi.isKakaoTalkLoginAvailable()) {
    UserApi.shared.loginWithKakaoTalk {(oauthToken, error) in
        if let error = error {
            print(error)
        }
        else {
            print("loginWithKakaoTalk() success.")

            //do something
            _ = oauthToken            
        }
    }    
}

계정으로 로그인하기

UserApi.shared.loginWithKakaoAccount {(oauthToken, error) in
        if let error = error {
            print(error)
        }
        else {
            print("loginWithKakaoAccount() success.")            

            //do something
            _ = oauthToken            
        }
    }

전체 코드_ViewController

import UIKit
import KakaoSDKAuth
import KakaoSDKUser

class LoginViewController: UIViewController {
    
    private let loginView = LoginView()
    
    override func loadView() {
        view = loginView
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        clickLoginButton()
    }

}

private extension LoginViewController {
    
    func clickLoginButton() {
        loginView.kakaoLoginByAppButton.addTarget(self, action: #selector(kakaoLoginByApp), for: .touchUpInside)
        loginView.kakaoLoginByWebButton.addTarget(self, action: #selector(kakaoLoginByWeb), for: .touchUpInside)
    }
    
    @objc func kakaoLoginByApp() {
        if (UserApi.isKakaoTalkLoginAvailable()) {
            UserApi.shared.loginWithKakaoTalk {(oauthToken, error) in
                if let error = error {
                    print(error)
                }
                else {
                    print("loginWithKakaoTalk() success.")

                    //do something
                    _ = oauthToken
                    
                    let accessToken = oauthToken?.accessToken
                    self.setUserInfo()
                }
            }
        }
    }
    
    @objc func kakaoLoginByWeb() {
        UserApi.shared.loginWithKakaoAccount {(oauthToken, error) in
            if let error = error {
                print(error)
            }
            else {
                print("loginWithKakaoAccount() success.")
                
                //do something
                _ = oauthToken
                
                let accessToken = oauthToken?.accessToken
                self.setUserInfo()
            }
        }
    }
    
    func setUserInfo() {
        UserApi.shared.me() {(user, error) in
            if let error = error {
                print(error)
            }
            else {
                print("me() success.")
                //do something
                _ = user
                self.loginView.userNameLabel.text = user?.kakaoAccount?.profile?.nickname
                self.loginView.userIDLabel.text = String((user?.id)!)
            }
        }
    }
}

user? 다음에 속성에 접근을 하면 다양한 속성을 이용할 수 있다.

전체 코드_View

import UIKit
import SnapKit

class LoginView: UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        configureUI()
        addSubView()
        autoLayout()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    // 카카오톡 로그인 버튼
    private(set) lazy var kakaoLoginByAppButton: UIButton = {
        let button = UIButton()
        button.setTitle("카카오톡으로 로그인", for: .normal)
        button.titleLabel?.textColor = UIColor.white
        button.backgroundColor = UIColor.systemBlue
        return button
    }()
    
    // 카카오 계정 로그인 버튼
    private(set) lazy var kakaoLoginByWebButton: UIButton = {
        let button = UIButton()
        button.setTitle("카카오계정으로 로그인", for: .normal)
        button.titleLabel?.textColor = UIColor.white
        button.backgroundColor = UIColor.systemBlue
        return button
    }()
    
    private(set) lazy var userNameLabel: UILabel = {
        let label = UILabel()
        label.text = "userName"
        label.textColor = UIColor.black
        label.font = UIFont.bodyFont(.medium, weight: .bold)
        return label
    }()
    
    private(set) lazy var userIDLabel: UILabel = {
        let label = UILabel()
        label.text = "userID"
        label.textColor = UIColor.black
        label.font = UIFont.bodyFont(.medium, weight: .bold)
        return label
    }()
}

private extension LoginView {
    
    // NoticeBoardView의 기본 UI 설정
    func configureUI() {
        backgroundColor = UIColor.white
    }
    
    // noticeBoardTableView를 SubView에 추가
    func addSubView() {
        addSubview(kakaoLoginByAppButton)
        addSubview(kakaoLoginByWebButton)
        addSubview(userNameLabel)
        addSubview(userIDLabel)
    }
    
    // 오토레이아웃 설정
    func autoLayout() {
        kakaoLoginByAppButton.snp.makeConstraints { make in
            make.center.equalToSuperview()
            make.leading.equalTo(snp.leading).offset(Constant.margin3)
            make.trailing.equalTo(snp.trailing).offset(-Constant.margin3)
        }
        
        kakaoLoginByWebButton.snp.makeConstraints { make in
            make.top.equalTo(kakaoLoginByAppButton.snp.bottom).offset(Constant.margin3)
            make.leading.equalTo(snp.leading).offset(Constant.margin3)
            make.trailing.equalTo(snp.trailing).offset(-Constant.margin3)
        }
        
        userNameLabel.snp.makeConstraints { make in
            make.top.equalTo(kakaoLoginByWebButton.snp.bottom).offset(Constant.margin3)
            make.leading.equalTo(snp.leading).offset(Constant.margin3)
            make.trailing.equalTo(snp.trailing).offset(-Constant.margin3)
        }
        
        userIDLabel.snp.makeConstraints { make in
            make.top.equalTo(userNameLabel.snp.bottom).offset(Constant.margin3)
            make.leading.equalTo(snp.leading).offset(Constant.margin3)
            make.trailing.equalTo(snp.trailing).offset(-Constant.margin3)
        }
    }
}

실행 결과

버튼 이미지도 디자인 리소스에서 다운받아서 적용시켰다.

https://developers.kakao.com/tool/resource/login

profile
iOS 개발자를 향해 성장 중

0개의 댓글