
#if DEBUG 컴파일러 디렉티브 활용하기iOS 개발을 진행하다 보면, 디버그(테스트) 환경에서만 실행되어야 하는 코드를 작성해야 하는 상황이 빈번히 발생한다. 예를 들어, 테스트 중에만 특정 데이터를 초기화하거나, 개발자 전용 기능을 활성화하고 싶을 때가 있다. 이러한 요구를 효과적으로 충족시키기 위해 Swift에서는 #if DEBUG 컴파일러 디렉티브를 제공한다. 이번 글에서는 #if DEBUG의 개념과 활용 방법을 쉽게 설명하고, 실제 코드 예제를 통해 그 사용법을 알아본다.

#if DEBUG란?#if DEBUG는 Swift에서 제공하는 컴파일러 디렉티브 중 하나로, 특정 코드 블록이 디버그 빌드에서만 컴파일되고 실행되도록 조건을 설정할 수 있게 해준다. 이는 릴리즈(배포) 빌드에서는 해당 코드가 무시되도록 하여, 프로덕션 환경에 불필요한 코드가 포함되지 않도록 도와준다.
#if DEBUG를 사용할까?개발 과정에서 다음과 같은 경우에 #if DEBUG를 활용할 수 있다:
이러한 기능들을 프로덕션 환경에 포함시키지 않음으로써, 앱의 안정성과 보안성을 유지할 수 있다.
#if DEBUG 사용 방법Swift에서 #if DEBUG를 사용하는 기본적인 방법은 다음과 같다:
#if DEBUG
// 디버그 빌드에서만 실행되는 코드
#endif
이 디렉티브는 디버그 빌드 설정에 DEBUG 플래그가 자동으로 설정되어 있다는 전제 하에 동작한다. Xcode의 기본 설정에서는 디버그 빌드에만 DEBUG 플래그가 포함되므로, 추가 설정 없이도 정상적으로 작동한다.
다음은 filterButtonTapped 메서드를 예로 들어, 디버그 빌드에서만 UserDefaults를 초기화하도록 구현한 예제이다.
@objc func filterButtonTapped() {
#if DEBUG
// UserDefaults 초기화 (특정 키만 제거)
UserDefaults.standard.removeObject(forKey: hasShownSwipeGuideKey)
sharedUserDefaults.removeObject(forKey: "hasShownSwipeGuide")
#endif
// 필터 화면 표시
let filterVC = FilterAlertViewController()
filterVC.modalPresentationStyle = .overFullScreen
filterVC.modalTransitionStyle = .crossDissolve
filterVC.onApplyFilter = { [weak self] selectedDrippers, selectedTemperatures in
self?.applyFilter(drippers: selectedDrippers, temperatures: selectedTemperatures)
}
present(filterVC, animated: true, completion: nil)
}
위 코드에서 #if DEBUG 블록 내의 코드는 디버그 빌드에서만 실행되며, 릴리즈 빌드에서는 무시된다. 이를 통해 테스트 시에만 UserDefaults를 초기화할 수 있어, 개발 과정에서의 유연성을 높일 수 있다.
#if DEBUG의 장점그렇다면 실제 디버그 환경에서만 작동해야 하는 코드가 릴리즈 빌드에서 작동하지 않는 경우를 테스트하려면 어떻게 해야 할까? 그 방법은 다음과 같다.
릴리즈 빌드를 생성한다.
Xcode에서 Product > Scheme > Edit Scheme... > Run > Build Configuration을 Release로 설정한다.


창을 닫고 앱을 실행하여 filterButtonTapped 메서드를 호출한다.
앱을 실행한 후, filterButtonTapped 메서드를 트리거하는 UI 요소(예: 버튼)를 눌러 해당 메서드를 호출한다.
UserDefaults가 초기화되지 않았는지 확인한다.
콘솔 로그나 UserDefaults의 값을 확인하여 디버그 빌드에서는 초기화되고, 릴리즈 빌드에서는 초기화되지 않았는지 검증한다. 이를 통해 #if DEBUG 블록 내의 코드가 릴리즈 빌드에서 실행되지 않았음을 확인할 수 있다.
전체 UserDefaults 초기화는 피한다: 테스트 용도로 모든 UserDefaults를 초기화하는 코드는 #if DEBUG 블록 내에서만 사용해야 하며, 프로덕션 환경에서는 절대 포함되지 않도록 주의해야 한다.
@objc func filterButtonTapped() {
#if DEBUG
// 전체 UserDefaults 초기화 (테스트 용도)
if let appDomain = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: appDomain)
}
sharedUserDefaults.removePersistentDomain(forName: "group.com.cheshire0105.TeaLike")
#endif
// 필터 화면 표시
let filterVC = FilterAlertViewController()
filterVC.modalPresentationStyle = .overFullScreen
filterVC.modalTransitionStyle = .crossDissolve
filterVC.onApplyFilter = { [weak self] selectedDrippers, selectedTemperatures in
self?.applyFilter(drippers: selectedDrippers, temperatures: selectedTemperatures)
}
present(filterVC, animated: true, completion: nil)
}
필요한 키만 선택적으로 제거: UserDefaults를 초기화할 때는, 필요한 키만 선택적으로 제거하여 데이터 손실을 최소화하는 것이 좋다.
Swift의 #if DEBUG 컴파일러 디렉티브는 개발 과정에서만 필요한 코드를 안전하게 관리할 수 있는 강력한 도구이다. 이를 통해 디버그 빌드와 릴리즈 빌드 간의 코드 차이를 명확히 구분하고, 프로덕션 환경의 안정성과 보안성을 향상시킬 수 있다. 이번 글에서 소개한 예제와 함께, #if DEBUG를 적절히 활용하여 효율적인 iOS 개발을 진행해보자.