Swift: API anahtarlarını uygulamak için PREPROCESSOR Bayrakları ("#if DEBUG" gibi) nasıl kullanılır?


95

İçinde Objective-Cbazen alternatif API anahtarlarını tanımlamak için statik dize sabitlerini kullanmak yararlı oldu (örneğin, MixPanel, Flurry veya Crashlytics gibi analitik paketleri için RELEASE ve DEBUG anahtarlarını ayırt etmek için):

#if DEBUG
static NSString *const API_KEY = @"KEY_A";
#else
static NSString *const API_KEY = @"KEY_B";
#endif

ve sonra...

[Analytics startSession:API_KEY];

Swift derleyicisi artık bir ön işlemci kullanmadığına göre, bu Swift'e nasıl çevrilir?

Yanıtlar:


161

Apple, Xcode 8'den itibaren Swift ön işlemci bayrakları için tam destek içeriyordu , bu nedenle artık bu değerleri "Diğer Swift Bayrakları" nda ayarlamak gerekli değil.

Yeni ayar, önişlemci bayraklarının Swift eşdeğeri için üst düzey destek sağlayan "Etkin Derleme Koşulları" olarak adlandırılır. "Diğer Swift Bayrakları" ile tamamen aynı şekilde kullanırsınız, ancak değerin başına "-D" koymanıza gerek yoktur (yani sadece biraz daha temizdir).

Gönderen Xcode 8 sürüm notları :

Active Compilation Conditionskoşullu derleme bayraklarını Swift derleyicisine geçirmek için yeni bir yapı ayarıdır. Bu ayarın değerinin her bir öğesi -, aynı önek ile clang'a Preprocessor Macrospass öğelerinde olduğu gibi, önünde D bulunan swiftc'e geçer . (22457329)

görüntü açıklamasını buraya girin

Yukarıdaki ayarı şu şekilde kullanırsınız:

#if DEBUG
    let accessToken = "DebugAccessToken"
#else
    let accessToken = "ProductionAccessToken"
#endif

2
Not: gerekir değil = 1 ya da başka herhangi = değerini belirtmek. Bunun yerine, sadece bayrak adını belirtmeniz gerekir. :]
JRG-Developer

@ JRG-Developer Katılmıyorum, ancak yorumunuzun burada nasıl geçerli olduğundan emin değilim.
Dan Loewenherz

9
Bu yararlı bir cevap, ancak bir Objective-C arka planından gelince (birçok iOS geliştiricisinin öyle olduğunu düşündüğüm gibi), belirtmem gerektiğini =1düşündüm ... Neden çalışmadığını anlamaya çalışırken biraz zaman kaybettim yaptığım zaman. Bu yüzden, bir sonraki adama yardımcı olmak için bu haberleri paylaşacağımı düşündüm. :] Neyse, cevabınız için burada teşekkürler!
JRG-Developer

1
@ JRG-Geliştirici, @Dan Loewenherz ben her iki belirledik DEBUGiçinde Active Compilation Conditionsve DEBUG=1içinde Preprocessor Macrosve bu yapılandırma hiç çalışmaz. Kaldırmalı mıyım DEBUG=1? Yukarıdaki yorumlardan net değil.
Bhavin_m

2
@DanLoewenherz Kesinlikle haklısınız. Hedef ayarlarımda arşiv yapılandırması için "DEBUG" ayarlamıştım, bu nedenle her defasında bir Debug deyimi çalıştırdığında ve yayın koşulunu asla çalıştırmaz. Sorunla karşılaşan varsa lütfen Build Configurationönce hedefinizi kontrol edin . Daha fazla bilgi için bu yanıtı stackoverflow.com/questions/9063100/… kontrol edin .
Bhavin_m

131

GÜNCELLENDİ: Xcode 8 artık bunu otomatik olarak destekliyor, bkz. @ DanLoewenherz'in yukarıdaki yanıtı.

Xcode 8'den önce, Makroları aynı şekilde kullanmaya devam edebiliyordunuz:

#if DEBUG
let apiKey = "KEY_A"
#else
let apiKey = "KEY_B"
#endif

Ancak Swift tarafından alınabilmeleri için hedefinizin Yapı Ayarlarında "Diğer Swift Bayrakları" ayarlamanız gerekir:

  • Hedefiniz için Yapı Ayarlarını açın
  • "Diğer hızlı bayrakları" arayın
  • Kullanmak istediğiniz makroları, önüne -Dbayrak ekleyin

görüntü açıklamasını buraya girin


günümü gün ettin! benim için -DÖnek olmadan işe yaramadı
nomnom

5

Bir takip gözlemi olarak, api anahtarlarını / sırlarını depoda düz metin olarak tutmamaya çalışın. Anahtarları / sırları kullanıcının ortam değişkenlerine yüklemek için bir gizli anahtar yönetim sistemi kullanın. Aksi takdirde, eğer kabul edilebilirse, 1. adım gereklidir.

  1. "Sırları" çevreleyen bilgi havuzunun yukarısındaki bir düz metin dosyasına koyun
  2. Aşağıdakileri ../set_keys.shiçeren bir liste oluşturun export API_KEY_A='<plaintext_key_aef94c5l6>'(değerlendirmeyi önlemek için tek alıntı kullanın)
  3. source ../set_keys.shYürütme sırasının en üstüne taşıyabilecek ve taşıyabilecek bir Çalıştır komut dosyası aşaması ekleyin
  4. Derleme Ayarları> Önişlemci Makrolarında, aşağıdaki gibi gerekli tanımlara ekleyin: API_KEY_A="$API_KEY_A"

Bu, ortam değişkenini daha sonra her kaynak dosya için her clang çağrısında kullanılan derleyici tanımına yakalar.

Örnek dizin yapısı

[10:33:15] ~/code/memo yes? tree -L 2 .
.
├── Memo
│   ├── Memo
│   ├── Memo.xcodeproj
│   ├── Memo.xcworkspace
│   ├── Podfile
│   ├── Podfile.lock
│   └── Pods
└── keys

0

Hızlı paketleri size bu iç yapmak zorunda swiftSettingsiçin argüman .targetsizin de Package.swiftdosyaya. Kullanım defineyöntemi (Elma belgeler) veya Swift belgelerine

targets: [
.target(name: String,
            dependencies: [Target.Dependency],
            path: String?,
            exclude: [String]?,
            sources: [String]?,,
            cSettings: [CSetting]?,
            cxxSettings: [CXXSetting]?,
            swiftSettings: [SwiftSetting]?,
            linkerSettings: [LinkerSetting]?),

Benimki buna benziyor ve işe yarıyor!

            swiftSettings: [
               .define("VAPOR")
            ]

benim kodumda bunu kullanarak koşullu olarak derleyebilirim:

#if VAPOR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.