iOS/트러블슈팅

환경 변수가 값을 못 불러오는 현상 해결하기

thinkySide 2025. 2. 23. 23:36

🤨 문제 정의

캐플 프로젝트의 자동 로그인 기능에 이상이 생겨 살펴보던 중 이해할 수 없는 현상이 발생했습니다. Xcode로 빌드할 때는 API 통신이 잘되고, 앱을 껐다 다시 키면 API 통신이 모두 먹통이 되는,,,? 어떻게 디버깅 해야 할지도 막막한 상황이 발생했습니다.

 

🪓 삽질 기록

1. API 오류?

API 오류인가 싶어 네트워킹 오류 Alert에 error 문자열을 출력해봤습니다. API 통신을 담당하는 QappleRepository 모듈에서 발생한 에러로 SecretKey 값 설정이 잘못되었다고 하네요! 문제는 왜 처음 Xcode로 빌드할 때는 잘되냐는,,,거였습니다.

 

캐플의 BaseURL, Port Number 등 민감한 정보는 모두 scheme의 Environment Variables로 관리되고 있었습니다. 만약 해당 값이 잘못되었다면, 애초에 첫 빌드에서도 API 통신에 실패해야하는 것이죠.

 

2. Environment Variables 넌 무엇이냐

아무래도 Environment Variables 문제인 것 같아 검색해보니,,, 역시 이 문제가 맞았습니다. StackOverflow의 한 게시물에 따르면 Environment Variables는 Xcode를 통해 앱을 실행할 때만 포함된다고 하네요!

 

원래 xcconfig 파일을 사용해 민감한 정보를 관리하고 있다가 요 방식이 더 편해보여서(gitignore 설정이 안꼬이고 잘되기도하고 깔끔해서,,)제대로 알아보지 않고 적용했는데 그 대가를 이렇게 치르게 된 것 같습니다.

StackOverflow는 신이야

 

😈 문제 해결

문제를 해결하고자 xcconfig 파일을 사용하는 방식으로 롤백했습니다. 사실 gitignore와 plist 모두 세팅해둔게 있어 금방 해결할 수 있었습니다! 다만, Module 내부에 해당 값들을 불러오는 코드가 심어져있었기에 약간의 트릭이 필요했습니다.

 

메인 프로젝트에서는 xccongif 파일을 이용해 값을 불러오고, 모듈 내부에서 실행할 때는(유닛 테스트를 위해!) 기존의 Environment Variables를 사용하는 방식으로 코드를 업데이트했습니다!

 

[PR] BaseURL fetch 방식 업데이트

/// API 호출을 위한 기본 URL 생성 관리
enum BaseURL {
    
    class PackageClass {}
    
    private static let scheme: String = "http"
    
    static func serverKey(_ server: Server) -> String {
        switch server {
        case .production: "PRODUCTION_URL"
        case .test: "TEST_URL"
        }
    }
    
    /// 기본 URL을 받아옵니다.
    static func fetch(from server: Server) throws -> String {
        
        // 모듈 외부에서 실행될 경우
        if Bundle.main == Bundle(for: PackageClass.self) {
            guard let host = Bundle.main.infoDictionary?[serverKey(server)] as? String else {
                throw APIError.invalidSecretKey("HOST_URL_\(server.rawValue.uppercased())")
            }
            guard let port = Bundle.main.infoDictionary?["PORT_NUM"] as? String else {
                throw APIError.invalidSecretKey("PORT_NUM")
            }
            return "\(scheme)://\(host):\(port)"
        }
        
        // 모듈 내부에서 실행될 경우
        else {
            guard let host = ProcessInfo.processInfo.environment[serverKey(server)] else {
                throw APIError.invalidSecretKey("HOST_URL_\(server.rawValue.uppercased())")
            }
            guard let port = ProcessInfo.processInfo.environment["PORT_NUM"] else {
                throw APIError.invalidSecretKey("PORT_NUM")
            }
            return "\(scheme)://\(host):\(port)"
        }
    }
}

 

오늘의 교훈: 뭐든 잘 찾아보고 적용하자 🙃

 

💌 레퍼런스

 

How to read environment variable from .env file using Xcode?

In order to keep api key secret and not hard coding them in code I have created .env file where I have set the value of key shown below. Now I want to inject this value during build time. 1 .env file

stackoverflow.com

 

Environment Variables in Xcode

Creating custom variables & looking into some of the predefined ones in Xcode

m25lazi.medium.com