IOS Swift/Festagram

Swift 프로젝트: FestaGram 01/로그인 화면

500beckwon 2020. 3. 15. 19:33

로그인 화면 만들기 일지

참고로 FestaGram은 FaceBook + Instagram을 합친 제가 지은 이름입니다. 

로고 디자인의 촌스러움은 아름답게 봐주세요 :)

 

1) 완성 화면

 

2) 파일 만들기

ViewController.swift파일을 쓰고 싶지 않으면 아무 파일이나 마우스 오른쪽 버튼이나

터치패트 두손가락을 꾸욱 누르면 아래 화면이 나옵니다. New File...-> Swift File 터치 후 Save as에 파일 이름을 적어주세요

로그인 화면이니까 LoginViewController이나 SignInViewController가 적당하겠네요.

 

3) class ViewController 연결

이렇게 클래스 앞에 이름을 적고 : 를 입력 후 UIViewController을 작성(상속)해주신 후 중괄호로 마무리하면 클래스가 만들어졌습니다.

Main.storyboard 파일을 누르면 뷰컨트롤러가 하나 있을 텐데 ViewController로 연결되어있으니 이걸 지우지 않고

사용하시거나 새로 하셔도 상관은 없습니다. 커맨트+시프트+L을 눌러 ViewContrllor을 끌어 놓으셔도 됩니다.

 

아래는 빈 화면이어야 하지만 미리 만들어 놓은거라 다르다고 이상하게 여기시지 않으셔도 됩니다.

왼쪽의 하얀 사각형을 누른후 오른쪽 상단의 4번째 메뉴의 class 항목에 아까 만든 클래스 이름을 입력하면

자동완성이 되어 엔터만 누르면 연결이 됩니다.

 

4) UI 연결/navigation controller 연결

이제 UI들을 넣어서 위 맨 위 사진처럼 배치하고 코딩을 하면 되는데

위 사진의 Login View Controller누른 상태에서 아래 사진처럼 최상단 Editor에서 메뉴를 찾아 선택하면

Presenting segue에서 root view controller연결이 되있을거에요.

UIButton = 비밀번호, 로그인, 회원가입, 비밀번호 찾기

UIImageView = Festagram 로고

UITextField = 회색글씨가 있는 abcde@naver.com, Password 

UIActivityIndicator = 붉은 소용돌이모양

나머지는 UILabel입니다.

 

UI와 파일을 연결을 하면 이렇습니다. 이름은 기능의 알맞게 본인 취향대로 지으시면 됩니다.

지금 보니까 이름선정이 조금 어색하네요. 더 어울리는 이름이 있다면 그걸로 지어주시면 됩니다.

 

5)키패드 출현

일단 컴파일을 하고 나면 Textfield에 글자를 입력해야 하는데 모바일 앱은 키보드로 입력을 하는게 아니라 키패드를 출현시켜 터치하는 방식인데 시뮬레이터에서 간혹 키패드가 출현하지 않을 때가 있습니다. 이럴 때는 시뮬레이터를 터치 후 최상단 Hardware라는 메뉴에서 Keyboard에서 두번째 항목을 선택해 주세요. 3개 중 아무거나 선택해도 지장은 없으니 다 눌러셔보셔도 됩니다,

6) 서버연동/pod 설치

Festagram은 SNS기능을 하기에 이용과 회원 가입을 위해서는 서버와 인터넷이 필요합니다. 서버는 Firebase를 사용하게 되는데

무료이고 서버자체의 제작에 대한 부담이 없이 사용할 수 있는 아주 좋은 플렛폼입니다.

이를 위해서는 외부 라이브러리 사용 cocoapod을 설치해야 하는데 그 과정은 아래 3개의 링크가 더 알차게 설명되어 있어

이를 참고하시는게 더 쉽게 진행할 수 있을겁니다.

 

Firebase공식 문서의 첫 설치 및 적용 설명서 

https://firebase.google.com/docs/ios/setup?hl=ko

 

iOS 프로젝트에 Firebase 추가

기본 요건 Xcode 10.1 이상을 설치합니다. CocoaPods 1.4.0 이상을 설치합니다. Xcode에서 프로젝트를 엽니다. 프로젝트에서 iOS 8 이상을 타겟팅해야 합니다. Swift 프로젝트에서 Swift 3.0 이상을 사용해야 합니다. 앱을 실행할 실제 iOS 기기 또는 iOS 시뮬레이터를 설정합니다. 클라우드 메시징에는 다음이 필요합니다. 실제 iOS 기기 Apple 개발자 계정의 Apple 푸시 알림 인증 키 Xcode의 App(앱) >

firebase.google.com

https://www.youtube.com/watch?v=iMkifTEaefE&feature=emb_title

Firebase 공식 채널의 첫 설치 및 적용 설명 동영상(한글자막 있음)

https://zeddios.tistory.com/25 

pod 처음 이용시 보기 좋은 글

 

왕 초보를 위한 CocoaPods(코코아팟) 사용법 (Xcode와 연동)

안녕하세요! 오늘은 CocoaPod사용법에 대해 알려드릴려고해요 :) 저는 CocoaPod 처음에 시작할 때 뭐가 뭔지 몰라서 정말 하나도 몰라서 진짜 어려운거구나...라고 생각했었어요. 하지만 한번 배워 놓으면 정말 쉽..

zeddios.tistory.com

주관적인 생각이지만 저 과정을 따라하는건 어렵지 않은데 터미널 경로를 타고 들어가 pod install하는 과정이 굉장한 난이도를 자랑해서(어디까지나 주관적) mac에 익숙하지 않으면 삭제 충동이 일정도로 어려웠는데 숱한 도전 끝에 편법(?)을 찾아 내서 알려드립니다.

프로젝트 최상위 폴더(xcodeproj파일을 품은 폴더)에서 마우스 오른쪽 버튼이나 터치패드로 두손가락 탭을 누르고

맨 아래 서비스 항목의 맨 아래 항목을 누르면!

짠! pod install을 할 위치로 바로 이동할 수 있습니다. 지금이야 터미널 켜서 경로 입력 후  해당 폴더 들어가는게 어렵지 않지만

터미널을 처음 사용해서 pod을 설치할려고 했을때의 저의 맨탈은 사르르 녹아내렸었고, 숱한 도전 끝에 알아낸 편법 아닌 편법입니다.

 

7) 코드 작성 

먼저 viewDidLoad()를 작성해서 로그인뷰가 최초로 나타날때의 기본적인 설정을 합시다

textfield Delegate설정을 해주고

키보드 입력칸을 보면 알겠지만 양끝이 둥그렇게 되있는데 이건 layer를 이용해서 깎은 건데요

해당textfield.layer.cornerRadius를 통해 가능하답니다

보통 완전한 원을 그릴 때 사용하는데 키보드 칸이 원형이면 안돼니 10~15정도를 입력해 끝에만 뭉툭하게 만들어줍시다.

override func viewDidLoad() {
        super.viewDidLoad()
        
        emailTextField.delegate = self
        passwordTextField.delegate = self
        
        emailTextField.layer.borderWidth = 1
        emailTextField.layer.cornerRadius = 15
        passwordTextField.layer.borderWidth = 1
        passwordTextField.layer.cornerRadius = 15
        emailTextField.clipsToBounds = true
        passwordTextField.clipsToBounds = true
    }

textfield 위에 회색 글씨는 Placeholder라고 입력이나 입력 후 영역을 벗어 났을 때 나타나는 안내문구 같은 것으로 Main.storyboard에서

textfield를 선택한 후 아래 메뉴로 가면

Placeholder칸에 글자를 입력해주면 화면에 회색글씨가 띄워지는걸 확인 할 수 있습니다 위의 Alignment는 글자 위치 선정으로 저는 가운데에 위치하도록 설정했습니다.

해당 메뉴서 아래쪽으로 내려가보면 이 항목이 있는데 이걸 설정해야 UI를 사용할 수 있습니다. 설정이 되지 않으면 화면잠금처럼 뭘 눌러도 반응 해주지 않습니다. 이 항목들은 코드로도 할 수 있고 이렇게 메뉴로 설정해줄 수도 있습니다.

 

 

저는 extension을 통해서 delegate관련 함수들은 분리해서 작성해서 가독성을 높이는 방법을 쓰고 있습니다.

맨 아래에 이렇게 따로 해놓으면 기능별로 볼 수 있어 편하지요.

다만 tableview나 collection은 많아서 거기서 거기인 경우도 있습니다ㅎㅎ;;

아래 코드는 키패드의 리턴키를 누르면 키패드가 자동으로 닫히는걸 승인하는 델리게이트로 class에 연결된 textfield의 델리게이트를 설정해줬다면 컴파일시 정상적으로 키패드가 사라지는걸 확인 할 수 있습니다.

extension LoginViewController : UITextFieldDelegate {
	func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }
}

 

 

 

회원가입 버튼을 눌러 회원가입 화면으로 이동하는 @IBAction입니다. 다음 포스팅에 쓸 뷰로 이동하는 내용이고 뷰를 선언할 때

gurad를 넣어 as!의 강제 언랩핑을 피하게 하는 것으로 코드를 작성하면 됩니다. 언랩핑은 실무에서 절대로 안하는 방식 중 하나래요!

실무를 해본적이 없어서 모르지만;;

예외적으로 자주 쓰는 appDelegate를 선언할 때는 as!를 써도 무방하다고 합니다.

 @IBAction func newSignBtn (_ sender : UIButton) {
        guard let loginView = storyboard?.instantiateViewController(withIdentifier: "NewSignInViewController") as? NewSignInViewController else { return }
        navigationController?.pushViewController(loginView, animated: true)
    }

 

아래 코드는 로그인 버튼을 눌렀을 때 기능하는 메소드입니다. 아직 회원가입 기능을 구현하지 않아서 설명만 조금 하면

이메일과 패스워드가 맞게 입력되면 로그인 되어 Festagram 메인 화면으로 이동하고 입력이 잘못됬거나 입력한 내용이 없을 시

UIAlertController이 나타나 다시 입력하라는 안내화면이 나타납니다.

@IBAction func loginBtn(_ sender : UIButton) {
        let email = emailTextField.text ?? ""
        let password = passwordTextField.text ?? ""
        Auth
            .auth()
            .signIn(withEmail: email,
                    password: password) { [weak self] authResult, error in
                        guard let self = self else { return }
                        if let error = error {
                            print("error = \(error.localizedDescription)")
                            let alert = UIAlertController(title: "정보 불일치",
                                                          message: "이메일 혹은 비밀번호가 일치하지 않거나 존재하지 않습니다", preferredStyle: .alert)
                            let okaction = UIAlertAction(title: "확인",
                                                         style: .default)
                            alert.addAction(okaction)
                            self.present(alert,animated: true)
                        }
                        if let user =  authResult?.user {
                            let uid = user.uid
                            self.activityIndicatorView.startAnimating()
                            guard let startView = self.storyboard?.instantiateViewController(withIdentifier: "tab") as? UITabBarController else { return }
                            self.navigationController?.pushViewController(startView, animated: true)
                            self.appDelegate.currentUID = uid
                            self.activityIndicatorView.startAnimating()
                        }
        }
    }

 

 

이번에는 비밀번호 찾기 버튼을 눌렀을 때 기능하는 함수로 가입한 이메일 인증에 성공시 해당 메일로 비밀번호가 전송되는 기능을 합니다.

핵심은 Auth.auth().sendPasswordReset() 함수로 이메일이 일치하면 비밀번호가 전송됩니다(보안은..?)

//MARK:비밀번호, 이메일 찾기 버튼
    @IBAction func findIdPw(_ sender: UIButton) {
        let alert = UIAlertController(title: "이메일, 비밀번호 찾기", message: "찾고자 하시는 항목을 선택해 주세요", preferredStyle: .alert)
        
        let pwAction = UIAlertAction(title: "이메일(Email)", style: .default) { (_) in
            let msg = "가입하실 때 사용하신 이메일을 입력해주세요"
            let pwAlert = UIAlertController(title: "비밀번호 찾기",
                                            message: msg,
                                            preferredStyle: .alert)
            pwAlert.addTextField()
            let cancel = UIAlertAction(title: "취소",
                                       style: .cancel)
            
            let okAction = UIAlertAction(title: "인증",
                                         style: .default) { (_) in
                                            let firestoreRef = Firestore.firestore()
                                            
                                            firestoreRef
                                                .collectionGroup("user")
                                                .getDocuments { (users, error) in
                                                    if let error = error {
                                                        print("\(error.localizedDescription)")
                                                    } else {
                                                        if users != nil {
                                                            guard let users = users else { return }
                                                            for document in users.documents {
                                                                guard let email = document["email"] as? String else { return}
                                                                if email == pwAlert.textFields?[0].text {
                                                                    guard let text = pwAlert.textFields?[0].text else { return }
                                                                    Auth
                                                                        .auth()
                                                                        .sendPasswordReset(withEmail: text) { error in
                                                                            if let error = error {
                                                                                print("\(error.localizedDescription)")}
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                            }
            }
            
            pwAlert.addAction(cancel)
            pwAlert.addAction(okAction)
            self.present(pwAlert,animated: true)
        }
        
        let cancel = UIAlertAction(title: "취소", style: .cancel)
        
        alert.addAction(pwAction)
        alert.addAction(cancel)
        self.present(alert,animated: true)
    }

 

 

이 기능은 회원가입후 로그인 후 다시 앱을 실행시킬 때 기능하는  viewDIdApper입니다.

로그인 기록이 있을 경우 자동으로 로그인 되어 메인화면으로 넘어가고 로그아웃을 따로 하지 않을 때까지는 자동 로그인이 지속적으로 활성화 됩니다.

 //MARK: 로그인 기록이 있을 경우 자동 로그인
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        if Auth.auth().currentUser != nil {
            let startView = self.storyboard?.instantiateViewController(withIdentifier: "tab") as! UITabBarController
            Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false, block: { (timer) in
                guard let currentUID = Auth.auth().currentUser?.uid else { return }
                self.appDelegate.currentUID = currentUID
                self.navigationController?.pushViewController(startView, animated: true)
            })
        }
    }

 

공부+포트폴리오 용도로 만든거라 살짝 조잡한 느낌이 있지만 기능 자체는 문제가 없기 때문에 개량을 하면 멋지고 더 기능적인 화면이 될 수 있겠지요?(특히 로고라던가...)

다음에는 회원가입 화면 포스팅을 작성해보겠습니다.