ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android] 회원가입시 LiveData 사용한 비밀번호 유효성 검사 (ViewModel/ Pattern, Matcher 정규식)
    안드로이드 2024. 3. 29. 18:32

    ✏️ TIL(Today I Learned)

    회원가입시, 비밀번호의 조건을 만족할 때까지 아래에 주의문구가 보이도록 만들었다. LiveData를 사용하여 입력받은 text를 관찰하면서, 조건을 만족하면 주의문구의 visibility를 GONE으로 바꿨다.

     

    우선 뷰모델을 사용하기 위해서,

    ViewModelProvider를 통해 SignUpViewModel가져오고 LifeCycle을 가진 owner를 넣었다. (this==현재 Activity)

    addTextChangedListener를 사용해서 EditText들의 텍스트가 변경될 때마다 ViewModel에 LiveData 값을 업데이트했다.

    // SignUpActivity
    
    viewModel = ViewModelProvider(this).get(SignUpViewModel::class.java)
    
    viewModel.isPasswordValid.observe(this) { isPasswordValid ->
        pwdWarningTv.visibility = if (isPasswordValid) {
            View.GONE
        } else {
            View.VISIBLE
        }
    }
    viewModel.isPasswordMatch.observe(this) { isPasswordMatch ->
        pwdCheckWarningTv.visibility = if (isPasswordMatch) {
            View.GONE
        } else {
            View.VISIBLE
        }
    }
    
    pwdEt.addTextChangedListener {
        viewModel.setPassword(it.toString())
    }
    pwdcheckEt.addTextChangedListener {
        viewModel.setPasswordCheck(it.toString())
    }

     

    뷰모델 내부에서 설정하는 자료형은 뮤터블로 해서 변경가능하도록 했다.

    공개적으로 가져오는 변수는 private 사용 X, 외부에서도 접근가능하도록 했고,
    값을 직접 LiveData에 접근 X, 뷰모델을 통해 가져오게 설정했다.

     

    비밀번호가 유효한 지를 나타내는 _isPasswordValid와 비밀번호가 일치 여부를 나타내는 _isPasswordMatch 변수를 만들었다. 뷰에서 이를 관찰하면서 값에 따라 주의문구를 담은 TextView의 visibility를 바꿀 것이다.

    // SignUpViewModel
    
    private val _password = MutableLiveData<String>()
    val password: LiveData<String>
        get() =_password
    
    private val _passwordCheck = MutableLiveData<String>()
    val passwordCheck: LiveData<String>
        get() =_passwordCheck
    
    private val _isPasswordValid = MutableLiveData<Boolean>()
    val isPasswordValid: LiveData<Boolean>
        get() = _isPasswordValid
    
    private val _isPasswordMatch = MutableLiveData<Boolean>()
    val isPasswordMatch: LiveData<Boolean>
        get() = _isPasswordMatch
    
    init {
        _isPasswordValid.value = true
        _isPasswordMatch.value = true
    }
    
    fun setPassword(password: String) {
        _password.value = password
        isPasswordValid(password)
    }
    fun setPasswordCheck(passwordCheck: String) {
        _passwordCheck.value = passwordCheck
        _isPasswordMatch.value = (passwordCheck==_password.value)
    }
    
    // 대문자, 소문자, 특수문자, 숫자를 포함하는 정규식
    private val pattern = Regex("^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*+=])(?=\\S+$).{8,15}$")
    private fun isPasswordValid(password: String) {
        _isPasswordValid.value = pattern.matches(password)
    }

     

    비밀번호를 입력할 때마다, isPasswordValid()함수를 호출하여 조건을 만족하는 지 확인하여 _isPasswordValid

     value를 업데이트 한다. _isPasswordMatch도 마찬가지이다.

     

    그러면 아래와 같이 실시간으로 비밀번호가 일치하는 순간 주의문구가 보이지 않게 된다.

     

     


     

    📝 공부한 Kotlin 정리

    [LiveData]

    LiveData는 안드로이드 아키텍처 컴포넌트 라이브러리의 일부로, 수명 주기를 인식하는 Data Holder 클래스이다. LiveData는 observable Data Holder로서, 뷰(activity, fragment, service 등)는 Data의 변경을 관찰하고 필요에 따라 UI를 자동으로 수정하는 데에 사용한다. 수명 주기 인식을 통해 관찰 대상의 수명 주기가 끝난 후에는 자동으로 삭제된다.

    // LiveData 캡슐화 (직접 접근 제한)
    
    private val _password = MutableLiveData<String>() // MutableLiveData를 사용하여 프라이빗 변수 선언
    val password: LiveData<String> // 공개적으로 액세스 가능한 LiveData를 정의 (외부에서 접근 가능하게)
        get() = _password // 내부의 MutableLiveData에 대한 참조를 반환

     

     

    [정규 표현식]

     

    Pattern 클래스

    • Pattern 클래스는 정규 표현식을 컴파일하고 패턴을 나타내는 데 사용된다.
    • 정규 표현식은 문자열 검색 및 매칭을 위한 패턴을 나타낸다.
    • Pattern.compile(String regex) 메소드를 사용하여 정규 표현식을 컴파일할 수 있다.
    • 컴파일된 패턴은 Pattern 객체로 나타내진다.
    • 주요 메소드:
      • compile(String regex) : 주어진 정규표현식으로부터 패턴 생성
      • pattern() : 컴파일된 정규표현식을 String 형태로 반환
      • matcher(CharSequence input) : 대상 문자열이 패턴과 일치할 경우 true를 반환
      • asPredicate() : 문자열을 일치시키는 데 사용할 수있는 술어를 작성
      • split(CharSequence input) : 문자열을 주어진 인자값 CharSequence 패턴에 따라 분리

     

    Matcher

    • Matcher 클래스는 주어진 입력 문자열에서 정규식 패턴을 찾는 데 사용된다.
    • Pattern.matcher(CharSequence input) 메소드를 사용하여 주어진 입력 문자열에 대한 매처를 얻을 수 있다.
    • 매처를 사용하여 문자열에서 패턴을 검색하고 매칭된 부분을 찾을 수 있다.
    • 매칭된 결과를 찾기 위해 find(), matches() 등의 메소드를 사용할 수 있다.
    • 주요 메소드:
      • matches() : 대상 문자열과 패턴이 일치할 경우 true 반환
      • find() : 대상 문자열과 패턴이 일치하는 경우 true를 반환하고, 그 위치로 이동
      • find(int start) : start위치 이후부터 매칭검색을 수행
      • start() : 매칭되는 문자열 시작위치 반환
      • start(int group) : 지정된 그룹이 매칭되는 시작위치 반환
      • end() : 매칭되는  문자열 끝 다음 문자위치 반환
      • end(int group) : 지정되 그룹이 매칭되는 끝 다음 문자위치 반환
      • group() : 매칭된 부분을 반환
      • group(int group) : 매칭된 부분중 group번 그룹핑 매칭부분 반환
      • groupCount() : 패턴내 그룹핑한(괄호지정) 전체 갯수를 반환

     

    정규식

    분류 정규식 패턴
    숫자 ^[0-9]*$
    최소 한 개의 숫자 포함 (?=.*[0-9])
    영문자 ^[a-zA-Z]*$
    최소 한 개의 알파벳 문자 포함
    (대문자 또는 소문자)
    (?=.*[A-Za-z])
    한글 ( [가-힣]는 모든 한글 범위 ) ^[가-힣]*$
    닉네임 ( [ㄱ-ㅣ]는 자음 범위 ) ^[ㄱ-ㅣ가-힣]*$
    영어&숫자 ^[a-zA-Z0-9]*$
    숫자, 문자 포함의 6~12자리 이내 ^[A-Za-z0-9]{6,12}$
    숫자, 문자, 특수문자 포함 8~15자리 이내 ^.*(?=^.{8,15}$)(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&+=]).*$
    이메일 ^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$
    휴대전화 ^\\d{3}-\\d{3,4}-\\d{4}$
    일반전화 ^\\d{2,3}-\\d{3,4}-\\d{4}$
    주민등록번호 \d{6} \- [1-4]\d{6}
    파일확장자 ^\\S+.(?i)(txt|pdf|hwp|xls)$
    이중 파일확장자 (.+?)((\\.tar)?\\.gz)$

     

    표현식
    설명
    ^ 문자열의 시작을 의미
    $ 문자열의 끝을 의미
    . 임의의 한 문자 (문자의 종류 가리지 않음,  단, \ 는 넣을 수 없음)
    * 앞 문자가 없을 수도 무한정 많을 수도 있음
    + 앞 문자가 하나 이상
    ? 앞 문자가 없거나 하나있음
    [] 문자의 집합이나 범위를 나타내며 두 문자 사이는 - 기호로 범위를 나타냄
    []내에서 ^가 선행하여 존재하면 not 을 나타냄
    {} 횟수 또는 범위를 나타냄
    () 소괄호 안의 문자를 하나의 문자로 인식
    | 패턴 안에서 or 연산을 수행할 때 사용
    \s 공백 문자
    \S 공백 문자가 아닌 나머지 문자
    \w 알파벳이나 숫자
    \W 알파벳이나 숫자를 제외한 문자
    \d 숫자 [0-9]와 동일
    \D 숫자를 제외한 모든 문자
    \ 정규표현식 역슬래시(\)는 확장 문자
    역슬래시 다음에 일반 문자가 오면 특수문자로 취급, 역슬래시 다음에 특수문자가 오면 그 문자 자체를 의미
    (?i) 앞 부분에 (?i) 라는 옵션을 넣어주면 대소문자를 구분하지 않음
Designed by Tistory.