# [iOS] String ValidEmail (이메일 형식 체크하기)
안녕하세요 __물먹고하자__ 입니다 :)
메일쓰기화면에서 Email 규약이 맞는지 정규식으로 체크했었는데,
"xxx.ddd123@gmail.com" 이런식이 기존에 인식이 안되었던 버그가 있어서
이참에 업데이트 하고, 테스트 했던 결과 공유드립니다.
---
## 1. NSDataDetector Link 추출후 mailto 활용하기
> 💡 NSDataDetector iOS 4.0 +
- 과거 네이버 블로그 https://blog.naver.com/xodhks_0113/220946461989?trackingCode=blog_bloghome_searchlist
- 예전에 했었는데, 기억이 안났을줄이야...
``` swift
import Foundation
// MARK: - 이메일 검증 함수
func isValidEmail(_ email: String) -> Bool {
guard !email.isEmpty else { return false }
do {
let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
let range = NSRange(email.startIndex..., in: email)
let matches = detector.matches(in: email, options: [], range: range)
// // 문자열에 메일형식이 맞는지 체크하는 부분
// for match in matches {
// if match.resultType == .link,
// let url = match.url,
// url.scheme == "mailto" {
// return true
// }
// }
// 전체 문자열이 완전히 이메일 패턴과 일치해야 함
return matches.contains { match in
match.resultType == .link &&
match.url?.scheme == "mailto" &&
NSEqualRanges(match.range, range)
}
} catch {
print("DataDetector error: \(error)")
}
return false
}
// MARK: - 테스트용 이메일 목록
let testEmails = [
// ✅ 정상적인 주소들
"john.doe@example.com",
"john_doe@example.co.uk",
"john-doe@sub.domain.com",
"user+promo@gmail.com",
"user@123.45.67.89",
"firstname.lastname@company.travel",
"me@my-domain.io",
"test@exämple.com", // 국제문자 도메인
"iveta.sevcakova@rb.cz", // 체코 도메인
"user_name@domain.org",
"user.name@domain.tech",
"user@domain.c", // 짧은 TLD
// ❌ 명백히 잘못된 이메일
"plainaddress",
"missingatsign.com",
"@nouser.com",
"user@.com",
"user@domain..com",
"invalid@@example.com",
"john@doe@example.com",
"user@localhost",
"user@domain,com",
"user@domain@domain.com",
"user@domain..co",
"user@-domain.com", // 도메인명 시작이 - 금지
"user@domain-.com", // 도메인명 끝이 - 금지
"user@.domain.com", // 도메인 시작이 . 금지
"user@domain_.com", // 언더스코어 금지
"user.@domain.com", // 점으로 끝나는 로컬파트 금지
".user@domain.com", // 점으로 시작 금지
"user@domain", // TLD 없음
"user@123", // 숫자 도메인 단독 금지
"user@domain.toolongtlddddd", // 너무 긴 TLD
// ⚠️ 경계 / 애매한 케이스
" spaced@out.com ", // 공백 포함
"", // 꺾쇠 포함
"(user)@example.com", // 괄호 포함
"\"user@name\"@example.com", // 따옴표 포함
"üñîçøðé@example.com", // 유니코드 로컬파트
"이메일@도메인.com", // 한글 포함
"user@[192.168.1.1]", // 대괄호 IP 형식
"user@sub_domain.com", // 언더스코어 포함 (비표준)
"user@do..main.com", // 연속 점
"user@domain.corporate", // 긴 TLD
"customer-service@shop-name.co.jp", // 다단계 도메인
"mailbox+filter@sub.service.io" // 플러스 라벨링
]
// MARK: - 테스트 실행
for email in testEmails {
let trimmed = email.trimmingCharacters(in: .whitespacesAndNewlines)
var check = isValidEmail(trimmed) ? "✅ Valid" : "❌ Invalid"
print("\(email) : \(check)")
}
```
코드영역 __isValidEmail__ 함수에서 해당 문자열에 이메일이 포함되어있는경우도 true로 하고 싶은경우는 주석된 부분을 사용하면 되고,
현재 코드 기준으로는 정확하게 email형식과 입력된 String이 매칭이 되었을때만 true인 상황이다.
ex) 이메일이 포함되어서 true 이지만, xodhks_0113@naver.com 이 유효한 email형식임.
---
## 마무리
너무 오래되서 까먹고 있었는데, 왜인지 이 코드를 알고있고 과거의 블로그도 썼었는데
이메일쓰기 부분을 정규식으로 해두었더군요.
그러다 보니 모든걸 허용되진 못했던 이슈가 있었고요.
다시 알고있던걸 정리했고, GPT통해서 샘플링과 허용/비허용 테스트코드도 작성해봤네요.
오늘은 이만~
즐거운 코딩 되게요.
끝.
댓글
댓글 쓰기