-
Core Data) NSPredicateiOS 2021. 8. 16. 16:02
NSPredicate
Core Data에서 아주 많이 사용하는 NSPredicate에 대해 알아봅시다. 공식 문서를 번역해 볼 거에요.
정의
class NSPredicate : NSObject
fetch 혹은 in-memory 필터링 검색을 제한하는데 쓰이는 논리적 조건의 정의.
간단하게 말해서 검색을 (제한) 하기 위한 조건문.
개요
Predicates는 객체 집합을 필터링하기 위해 사용하는 논리적 조건을 표현합니다.
물론 NSComparisonPredicate, NSCompoundPredicate, NSExpression의 인스턴스를 통해 predicate를 생성하는게 일반적이지만, 종종 NSPredicate의 클래스 메서드로 parsed되는 format string (형식 문자열?)으로부터 predicates를 생성하기도 합니다.
NSPredicate(format: "========")
predicate format string의 예를 봅시다! 위 생성자의 format에 들어갈 문자열이에요!
- grade == "7" 혹은 firstName like "Shaffiq" 와 같은 간단한 비교
오 == 으로만 비교해봤는데 like를 사용할 수도 있네요 🤨
- name contains[cd] "itroen" 과 같이 대/소문자 구분 없는 조회
NSPredicate(format: "%K CONTAINS[cd] %@", #keyPath(Tag.name), searchText)
저는 원래 CONTAINS[c]로 쓰고 있었는데 cd도 되네요?! 아마 case and diacritic(대소문자)의 약자로 예상됩니다.
위 predicate는 tag의 이름이 searchText를 포함하는 (대/소문자 구분 없이!) tag들을 검색하기 위한 조건이 될거에요 ㅎㅎ (keyPath도 나중에 한번 공부해 볼게요 ,, )
- (firstName like "Mark") OR (lastName like "Adderley") 와 같은 논리 연산
OR 뿐만 아니라 ||, NOT, ! 와 같은 일반적 논리 연산 기호들도 쓸 수 있습니당
- date between {$YESTERDAY, $TOMORROW} 와 같은 시간 범위 제약
근데 저 $YESTERDAY는 진짜 저렇게 쓰면 안되는 것 같더라구요? 실제로 쓸 때에는 arg로 Date객체를 지정해줘야 할 것 같아요 (틀렸으면 말 좀,, )
- group.name like "work*" 와 같은 관계 조건
?, * 과 같은 와일드카드 문자 (아무거나 들어가도 됨)를 사용 가능합니다. ?는 1개 문자 *은 0개 이상의 문자와 일치합니다. 기본적으로 정규 표현식에 사용되는 규칙?들은 통용 되는 것 같아요.
- @sum.items.price < 1000 와 같은 합계 연산
predicate 문법의 더 자세한 내용은 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Predicates/AdditionalChapters/Introduction.html#//apple_ref/doc/uid/TP40001789
여기서 볼 수 있습니다만,, 예시가 Objective-C로 작성되어 있어서 참 아쉬워요 🥲
또한 evaluate(with:substitutionVariables:) 메서드로 변수를 포함한 predicates를 만들 수 있는데,
그럼 런 타임에 결정되는 값을 지정해놓지 않고도 predicate를 미리 정의할 수 있습니다.
참고로 evaluate 메서드는 bool 값을 리턴하는데, 해당 값이 조건문을 만족하는지를 return 합니다.
토픽
Predicate 생성
init(format: String, argumentArray: [Any]?) init(format: String, arguments: CVaListPointer) func withSubstitutionVariables([String : Any]) -> Self init(value: Bool) init(block: (Any?, [String : Any]?) -> Bool) init?(fromMetadataQueryString: String)
역시 여러가지 init 메서드들이 있네요,,
보통은 근데 NSPredicate(format: String, _ args: CVarArg...) 이 메서드를 제일 많이 사용하는 것 같아요.
Predicate 평가
func evaluate(with: Any?) -> Bool func evaluate(with: Any?, substitutionVariables: [String : Any]?) -> Bool func allowEvaluation()
해당 predicate를 만족하는지 bool 값으로 return하는 함수들
String 표현식
var predicateFormat: String
predicate의 형식 문자열을 반환합니다.
— 여기까지가 NSPredicate에 대한 공식 문서 내용이에요
사실 검색하려는 상황은 무궁무진하게 다양해 질 수 있기 때문에 NSPredicate랑 저 위에 쓰여있는 NSComparisonPredicate, NSCompoundPredicate, NSExpression 클래스들도 자세히 공부해 놓아야 할 것 같습니다 쉬운게 하나도 없네요 😭
'iOS' 카테고리의 다른 글
Notification) 앱 라이프 사이클 notification 받기 (0) 2021.11.08 실전! CleanSwift 바로 써먹기 -1 (세팅 및 scene, payload 모델 생성) (2) 2021.10.11 Core Data) CoreData에서 enum 값으로 검색하기 (1) 2021.08.16