전 처리기 매크로가 없으면 Xcode 프로젝트의 프로젝트 레벨에서 실제 체계 특정 플래그를 정의하는 방법이 있습니까?


174

신속하게 진행하기 전에 알파, 베타 및 배포 빌드에 대한 체계를 정의했습니다. 이러한 각 구성표에는 프로젝트 수준에서 특정 동작을 게이트하도록 정의 된 매크로 세트가 있습니다. 가장 간단한 예는 실행 빌드에 대한 기본 체계에서 모든 Xcode 프로젝트에 대해 기본적으로 정의 된 DEBUG = 1 매크로입니다. #ifdef DEBUG ...를 쿼리하고 그에 따라 코드에서 결정을 내릴 수 있으며 불필요한 코드를 컴파일 할 수도 있습니다.

이러한 유형의 구성 게이팅은 매크로가 지원되지 않기 때문에 신속한 사용이 쉽지 않습니다. 누군가 비슷한 접근법을 제안 할 수 있습니까? 코드가 컴파일되어 있는지는 신경 쓰지 않습니다. 그래도 빌드 체계를 기반으로 기능을 게이트하고 싶습니다.

답변:


468

Swift에서는 Apple 문서에 따라 여전히 "# if / # else / # endif"전 처리기 매크로를 사용할 수 있습니다 (더 제한적 임) . 예를 들면 다음과 같습니다.

#if DEBUG
    let a = 2
#else
    let a = 3
#endif

이제 "DEBUG"기호를 다른 곳에 설정해야합니다. "Swift Compiler-Custom Flags"섹션, "Other Swift Flags"라인에서 설정하십시오. -D DEBUG항목 과 함께 DEBUG 기호를 추가합니다 .

(빌드 설정-> 스위프트 컴파일러-사용자 정의 플래그) 여기에 이미지 설명을 입력하십시오

일반적으로 디버그 또는 릴리스시 다른 값을 설정할 수 있습니다.

실제 코드로 테스트했습니다. 놀이터에서 인식되지 않는 것 같습니다.


5
#elseif 줄을 사용하여 더 많은 테스트를 추가 할 수도 있습니다. 흥미롭게도 정의에 액세스 할 수 있지만 정의에서 아무것도 추출 할 수는 없습니다. 즉, -DDEBUG = 5 (또는 = "FOO")를 정의한 다음 "println (DEBUG is (DEBUG)" ")을 사용하여 인쇄 해보십시오. 해당 줄은 오류는 없지만 아무 것도하지 않습니다
David H

10
참고 : "기본"빌드 설정에는 "내장 설정-> 스위프트 컴파일러-> 사용자 정의 플래그"가 표시되지 않습니다. "모두"빌드 설정을 표시해야합니다.
levibostian

7
@EugeneDubinin $(inherited)은 프로젝트 설정을 상속하기 위해 대상 설정에 사용 되어야하기 때문일 수 있습니다 .
DanSkeel

2
@ DanSkeel 멋진 캐치, 추가 $(inherited)하면 내 의견이 무의미합니다. 감사합니다!
Yevhen Dubinin

10
Xcode 8의 "Swift Compiler-Custom Flags"섹션에 "Active Compilation Conditions"설정도 있습니다. -D가 필요없이 여기에 플래그를 추가 할 수 있습니다
Marcus

32

우리는 신속한 컴파일러 플래그를 설정하고 싶지 않다는 문제를 겪었습니다. 왜냐하면 우리는 플래그를 설정하고 다른 대상 등을 위해 최신 상태로 유지하고 싶지 않기 때문입니다. 또한 혼합 코드베이스에서 우리는 기억하고 싶지 않았습니다. 각 언어에 대해 항상 플래그를 적절하게 설정합니다.

우리는 ObjC에서 파일을 선언했습니다.

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

.m에서

PreProcessorMacros.m

#ifdef DEBUG
    BOOL const DEBUG_BUILD = YES;
#else
    BOOL const DEBUG_BUILD = NO;
#endif

그런 다음 Objective-C 브리지 헤더에서

#import "PreProcessorMacros.h"

이제 Swift 코드베이스에서 이것을 사용하십시오.

if DEBUG_BUILD {
    println("debug")
} else {
    println("release")
}

이것은 확실히 해결 방법이지만 문제를 해결하여 도움이되기를 희망하여 여기에 게시했습니다. 기존 답변이 유효하지 않다고 제안하는 것은 아닙니다.


11
매크로의 핵심은 빌드 구성에 따라 코드를 변경하는 것입니다. if를 런타임으로 다시 가져 오면 매크로가 필요하지 않습니다.
Berik

18
@Berik-특히 다국어 프로젝트 에서이 문제의 측면을 해결하려는 다른 사람들에게 도움이되기를 희망하는 유효한 솔루션을 게시했습니다. 문제가 특정 코드를 컴파일하지 않아도되면 괜찮습니다. 또한 왜 이것이 이것이 해결책이 아닌지에 대해 교육 할 때 주석이 좋습니다. 또한이 접근법의 한계에 대한 답변을 적어달라고 요청하십시오. 다운 보팅은 불필요하며 유사한 문제를 해결하는 다른 사람들에게 도움이 될 수있는 대체 솔루션을 권장하지 않습니다. 또한 op는 "코드가 컴파일 되어도 상관 없다"고 말합니다.
Logan

5

Logans 방법에 대한보다 신속한 솔루션. 설정 -D DEBUG에서 Other Swift FlagsSwift Compiler - Custom Flags대상의 빌드 설정 섹션을 참조하십시오.

그런 다음 전역 범위에서 다음 메소드를 선언하십시오.

#if DEBUG
let isDebugMode = true
#else
let isDebugMode = false
#endif

이제 다음과 같이 사용하십시오.

if isDebugMode {
    // Do debug stuff
}

1

나를 위해 " Active Compilation Condition " 의 디버그 항목 을 "DEBUG"로 설정했습니다.

그런 다음 #IF에서 DEBGU 키 작업을 사용하면 디버그 모드에서 작동하고 #ELSE는 릴리스 모드에서 작동합니다.

  1. 대상을 선택하십시오
  2. 빌드 설정 탭에서 "활성 컴파일 조건"을 검색하십시오.
  3. "Debug"항목의 값을 "YourKeyWord"로 설정하십시오.
  4. 다음과 같이 간단하게 사용하십시오.

    #if DEBUG
        print("You'r running in DEBUG mode!")
    #else
        print("You'r running in RELEASE mode!")
    #endif

0

obj-c 코드가 매크로를 사용하여 디버그 메시지를 콘솔에 보내는 혼합 언어 코드베이스에서 작업하고 있습니다 (그리고 그 매크로는 디버그 전 처리기 플래그에 의존합니다). 신속한 코드에서 동일한 매크로를 호출 할 수 있기를 원했습니다 ...

  1. 매크로 주위의 래퍼 인 obj-c 클래스 중 하나에 클래스 메서드를 만들었습니다.
  2. obj-c 헤더를 브리지 헤더 파일에 추가했습니다.
  3. 이제 내 빠른 코드는 해당 클래스 메서드를 obj-c 매크로에 대한 "프록시"로 호출합니다.

스위프트 코드에서 매크로를 바로 호출 할 수 없다는 것은 약간 성가시다. 그러나 적어도 지금은 프로젝트에서 디버그 플래그를 켜고 끄는 것에 대해 걱정할 곳이 한 곳 밖에 없다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.