본문 바로가기

Swift

[Swift] Namespace 네임스페이스 란? (Struct, Enum 활용)

다른 라이브러리, 프레임워크와 이름이 충돌되지 않기 위해 Objective-C 클래스에는 고유한 이름이 있습니다. 애플이 UIView, CGRect, CALayer 와 같이 Objective-C 클래스에 접두어를 사용하는 이유입니다. 하지만 스위프트 모듈은 클래스 접두사가 필요하지 않습니다.

 

스위프트는 현재 모듈 내의 네임스페이스(Namespace) 유형과 상수에 대한 솔루션을 제공하지 않고 있습니다. 스위프트로 작업할 때 일반적인 문제는 프로젝트를 함께 진행하는 개발자 누구나 쉽게 이해하는 방식으로 상수를 정의하는 것입니다. Objective-C 에도 유사한 고민이 있습니다. 모든 상수에는 이름 충돌을 피하기 위해 두 개 또는 세 개의 글자가 앞에 붙고 용도를 설명합니다.

 

NSString * const CCAPIBaseURL = @"https://onelife2live.tistory.com";
NSString * const CCAPIToken = @"eyJhbGciOiJIUzI1Ni";

 

보통 위와 같이 사용합니다. 보기에 깔끔하지 않고 읽기도 쉽지 않습니다. 하지만 프로젝트 내내 문자열 리터럴을 사용하는 것보다는 훨씬 나은 방법입니다.

Using Structs

스위프트는 네임스페이스를 지원하지 않지만, 이 문제에 대한 몇 가지 해결책이 있습니다. 첫 번째 해결책은 구조체(struct) 를 이용하여 네임스페이스를 만들 수 있습니다.

 

struct API {
    static let BaseURL = "https://onelife2live.tistory.com"
    static let Token = "eyJhbGciOiJIUzI1Ni"
}

 

API라는 구조체를 정의했습니다. 그리고 static 상수를 2개 선언하였습니다. 훨씬 깔끔하고 사용하기 쉬우며 상수에 접근하기 위한 구문은 직관적이며 읽기 쉽습니다.

 

if let url = URL(string: API.BaseURL) {
    ...
}

 

하지만 이 방법에는 문제점이 하나 있습니다. API 구조를 인스턴스화 할 수 있다는 것입니다. 이 자체로는 문제가 되지 않지만, 이 프로젝트를 함께 하는 다른 개발자들을 혼란스럽게 할 수 있습니다. 이 문제는 API 구조체의 초기화를 private 으로 선언하여 프로젝트의 다른 부분에 접근할 수 없도록 할 수 있습니다.

 

struct API {
    private init() {}

    static let BaseURL = "https://onelife2live.tistory.com"
    static let Token = "eyJhbGciOiJIUzI1Ni"
}

let api = API() // 컴파일 에러 발생

Using Enumerations

또 다른 해결책은 열거형(Enumeration)을 사용하는 것입니다. 구조체를 사용하는 대신에, case가 없는 열거형을 사용하는 것입니다. case가 없는 열거형은 인스턴스화 되지 않고 네임스페이스 역할을 해낼 수 있습니다.

 

이 방법은 구조체를 사용하는 방법과 거의 동일합니다. 주요 차이점은 컴파일 에러 없이 API 열거형 인스턴스를 만들 수는 없다는 것입니다.

 

enum API {
    static let BaseURL = "https://onelife2live.tistory.com"
    static let Token = "eyJhbGciOiJIUzI1Ni"
}

let api = API() // 컴파일 에러 발생

 

네임스페이스를 만들기 위해 열거형이나 구조체를 사용하는 것은 제게는 매우 깔끔하고 직관적인 코드를 만드는 좋은 방법이라고 생각합니다. 아래의 예제는 특히 Objective-C와 비교했을 때 상당히 매력적인 방법입니다.

 

extension UserDefaults {

    enum Keys {
        static let CurrentVersion = "currentVersion"
        static let DarkModeEnabled = "darkModeEnabled"
    }

}

 

UserDefaults 클래스에 대한 extension 을 생성하고 내포된 열거형 Keys 를 정의하였습니다. 이는 아래처럼 활용이 가능합니다.

 

// Update User Defaults
let userDefaults = UserDefaults.standard
userDefaults.set(1.0, forKey: UserDefaults.Keys.CurrentVersion)

정리

  • 구조체 또는 열거형을 이용하여 네임스페이스를 만들어 보았습니다.
  • 상수를 직관적이고 쉽게 사용할 수 있는 간단한 패턴입니다.

참조