Debug와 Release로 정의를 전환하는 세 번째 최고의 방법

8974 단어 iOSSwift아이폰
대부분의 앱은 다음과 같은 방법으로 나누고 있다고 생각합니다.
하나는 User-Defined를 사용하는 방법.
하나는 전처리기 매크로를 사용하는 방법.

이것보다, 자신이 베스트라고 생각하는 방법이 있어. 라는 기사입니다.

Maven의 프로파일이나 Gradle의 Android Plugin과 같이 환경별 파일을 준비해, 빌드에 어느 것을 사용하는지를 판단시키는 방법입니다.

방법



우선, Environment-Info-develop.plist , Environment-Info-production.plist 와 같이 환경 마다의 파일을 작성합니다.
내용은 다음과 같이 환경별 차이를 설명합니다.

Configuration/Environment-Info-develop.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>apiUrl</key>
    <string>https://develop.hoge.jp</string>
</dict>
</plist>

Configuration/Environment-Info-production.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>apiUrl</key>
    <string>https://hoge.jp</string>
</dict>
</plist>

그런 다음 Build Phases에서 Run Script를 만듭니다.
내용은 다음과 같습니다. 즉, 선택한 Build Configuration에 해당하는 파일을 Environment-Info.plist 로 앱에 번들하고 있습니다.

/bin/sh
BUILD_PRODUCT="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app"
PROJECT_PATH="${PROJECT_DIR}/${PROJECT_NAME}"
INFO_BUILD_PATH="${BUILD_PRODUCT}/Environment-Info.plist"

rm -rf "${INFO_BUILD_PATH}"
if [ "${CONFIGURATION}" = "Debug" ]; then
  cp "${PROJECT_PATH}/Configuration/Environment-Info-develop.plist" "${INFO_BUILD_PATH}"
  echo "Development Environment-Info copied into ${BUILD_PRODUCT}"
else
  cp "${PROJECT_PATH}/Configuration/Environment-Info-production.plist" "${INFO_BUILD_PATH}"
  echo "Production Environment-Info copied into ${BUILD_PRODUCT}"
fi

마지막으로 이 내용을 다루는 클래스를 만들고 이용하기만 하면 됩니다.
얻을 수 없었던 경우는 단순한 버그이므로, 즉시 떨어뜨려 눈치채도록(듯이), Forced unwrapping 시킵니다.

EnvironmentHolder.swift
public class EnvironmentHolder {

    static let sharedInstance = EnvironmentHolder()

    let apiUrl: String

    private init() {
        let bundle = Bundle.main

        let environmentPath = bundle.path(forResource: "Environment-Info", ofType: "plist")!
        let environmentDict = NSDictionary(contentsOfFile: environmentPath)!
        self.apiUrl = environmentDict.object(forKey: "apiUrl") as! String
    }
}

사용자 정의와 비교



User-Defined는 Target > Build Settings에서 "+"를 누르고 "add User-Defined Setting"에서 Configuration별로 설정하는 방법입니다.



그리고 Info.plist에 쓰고

Info.plist
       <key>apiUrl</key>
       <string>${apiUrl}</string>

코드에서 다음과 같이 호출합니다.
let apiUrl = Bundle.main.object(forInfoDictionaryKey: "apiUrl")

좋지 않은 점은 User-Defined가 *.xcodeproj/project.pbxproj에 저장된다는 것입니다.
개발 중에는, Debug의 경우만 써 두고, 나중에 copipe 해 프로덕션용을 준비한다고 할 수 없습니다.

반면에 처음 제안한 방법은 단순한 plist이므로 쉽게 복사 할 수 있으며 diff를 알기 쉽습니다.

전처리기 매크로와의 비교



Objective-c라면 Preprocessor Macros에, 예를 들어, DEBUG=1Swift라면 Other Swift Flags 에 -D DEBUG
코드에서 다음과 같이 호출합니다.

Objective-C의 경우
 #ifdef DEBUG
    // ...
 #elif RELEASE
    // ...
 #endif

Swift의 경우
  #if DEBUG
    // ...
  #elseif RELEASE
    // ...
  #endif

그다지 좋지 않은 점은 본질적이지 않은 처리가 코드에 나타나는 것입니다. 값이 적으면 좋지만, 많아지면 가독성이 손상되어 버그를 알아차리기 어려워집니다.
이 방법에서는 EnvironmentHolder.swift와 같은 클래스를 준비하고 한 클래스에만 닫는 전략이 좋습니다.
어쨌든, 처음 제안한 방법은 불필요한 분기가 없다는 장점이 있습니다.

좋은 웹페이지 즐겨찾기