[swiftUI] NSPredicate
프로젝트를 진행하면서 아이디, 비밀번호에 대해 정규표현식 검사를 하다가 swift에서 제공해 주는 클래스에 대해서
알게 되었다.
그래서 어떻게 사용하고 어떤 문제점이 있는지 알아보고자 한다~
공식 문서에서는 데이터 조회(fetch) 또는 메모리 필터링에 대한 검색을 제한하기 위한 논리적 정의라고 설명되어 있다.
사용방법
- .evaluate(with: ) : NSPredicate의 메서드이며 정규식을 판별할 때 주로 쓰인다.
- .evaluate(with:substitutionVariables:) : NSPredicate의 메서드이며 변수를 포함하는 조건자를 생성할 수 있다.
주로 정규 표현식 검사를 할 땐 포맷 지정자를 통해 값을 변환하거나 비교하는 데 사용된다.
✔️ 포맷지정자
포맷 지정자에는 %d, %c, %K, %f 등등 많지만 기본적인 것들은 제외하고 이번 프로젝트를 하면서 알게 된 것들을 바탕으로 설명해 보겠다.
- %@ : 객체, 문자열, 숫자, 날짜, Bool 값을 나타낼 때 사용하며 정수, 문자열 등 모든 타입의 값을 받을 수 있으며 또는 문자열로 변환할 때 사용된다.
- %K : 문자열로 된 키 경로를 나타내며, 데이터의 특정 속성을 나타낸다.
코드
func validateName() {
let nameRegex = "^[가-힣a-zA-Z]+$"
showErrorName = !NSPredicate(format: "SELF MATCHES %@", nameRegex).evaluate(with: name)
print(showErrorName)
}
NSPredicate 클래스를 적용시킨 코드이다.
format 부분에서는 현재 객체에 대해 정규 표현식과 매칭되고 있는지 확인하고 있으며 %@를 통해 nameRegex에 저장된 문자열로 대체된다.
showErrorName의 초기값을 false로 선언해 주었고, 위에 이름 유효성 검사하는 함수에서는 evaluate를 통해 name값이 정규 표현식 문자열(nameRegex)과 다르다면 false를 반환, 같다면 true를 반환하지만
내 프로젝트에서는 입력포맷이 틀릴 때 입력 포멧 관련 문구가 떠야 하기 때문에 값을 (!NSPredicate를 통해) 반전시켜 주었다.
문제점
정규 표현식을 사용하는 것은 개발자 입장에서 코드 짤 때 간편하긴 하지만 성능적인 측면에서 안 좋다고 들었다.
사용자가 Input값을 자주 변경하게 되는 경우 또는 엄청 복잡한 정규 표현식을 사용하게 되면 추가적인 메모리 할당과 해제를 반복하게 되어 앱이 점점 느려지게 되는 치명적인 문제가 발생할 수도 있다.
하지만 지금 프로젝트 규모정도의 정규 표현식을 사용하는 것은 문제가 크게 되지 않겠지만, 정보를 캐싱하거나 디바운싱하는 방법으로 코드를 리펙토링 해보는 것도 좋은 방법이 될 거 같다.