Çalışma zamanında bir iOS uygulamasının TestFlight Beta yüklemesiyle çalışıp çalışmadığını nasıl anlarsınız?


123

Çalışma zamanında, bir uygulamanın TestFlight Beta (iTunes Connect aracılığıyla gönderilir) aracılığıyla App Store üzerinden yüklendiğini tespit etmek mümkün müdür? Tek bir uygulama paketi gönderebilir ve her ikisinde de kullanılabilir hale getirebilirsiniz. Hangi şekilde yüklendiğini algılayabilen bir API var mı? Veya makbuz bunun belirlenmesine izin veren bilgiler içeriyor mu?


4
Açık olmak gerekirse, iTunes Connect aracılığıyla yeni TestFlight beta testinden bahsediyorsunuz? Yoksa doğrudan TestFlight'a ne zaman yüklediğinizden mi bahsediyorsunuz?
keji

Yeni TestFlight beta, netleşecek
kombinasyon

1
Görünüşe göre - [NSString containsString:] bir ios8 eklemesidir. App Store otomatik testi onu ios7'de çalıştırmayı denerse, devam etmeyin. ([ReceiptURLString rangeOfString: @ "sandboxReceipt"]. location! = NSNotFound) hile yapmalı.
rgeorge

@rgeorge teşekkürler, bu aptalca bir hataydı!
kombinatoryal

2
AppStoreReceiptURL içermeyen iOS 6'da algılama hakkında soru soracaktım, ancak TestFlight uygulamasının yalnızca iOS 8 olduğu anlaşılıyor; yani - [NSString containsString] iyi olabilir. Bu nedenle uygulama mağazası beta testini beklemeye aldım, ancak sanırım bazı insanlar eski testler için Ad-Hoc ve genel beta için AppStore beta ile karma bir test stratejisi kullanıyor olabilir, bu nedenle rangeOfString hala kazanıyor.
Gordon Dove

Yanıtlar:


118

TestFlight Beta aracılığıyla yüklenen bir uygulama için makbuz dosyası StoreKit\sandboxReceipther zamanki gibi adlandırılır StoreKit\receipt. Kullanarak [NSBundle appStoreReceiptURL], URL'nin sonunda sandboxReceipt'i arayabilirsiniz.

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSString *receiptURLString = [receiptURL path];
BOOL isRunningTestFlightBeta =  ([receiptURLString rangeOfString:@"sandboxReceipt"].location != NSNotFound);

Bu sandboxReceiptaynı zamanda derlemeleri yerel olarak çalıştırırken ve simülatörde çalıştırılan derlemeler için makbuz dosyasının adıdır.


7
Belirtildiği gibi, bu, simülatörde değil cihazda yerel test için işe yarar. # İf TARGET_IPHONE_SIMULATOR isRunningInTestMode = YES gibi bir şey ekledim; #endif Açıkçası, bunun için # ithalat <TargetConditionals.h> gerekiyor
Gordon Dove

13
Kompakt sürüm: [[[[NSBundle mainBundle] appStoreReceiptURL] lastPathComponent] isEqualToString:@"sandboxReceipt"](TestFlight dağıtılmış ikili dosyası çalıştırılıyorsa doğrudur) Supertop / Haddad
Nick

2
Makbuz yalnızca ana bilgisayar paketi için mevcut olduğundan, bu yöntem uzantı paketlerinde kullanılamaz.
jeeeyul

2
İOS 8 StoreKit/sandboxReceipttestim, cihazda veya simülatörde Xcode aracılığıyla bir hata ayıklama derlemesi olarak yüklendiğinde sonuçlanıyor . Dolayısıyla bu, test uçuşu yapılarını diğer tüm yapılardan tam olarak ayırt etmeyebilir .
pkamb

3
Ayrıca, Ad Hoc dağıtımıyla bir yapı kurarken EVET döndürüyor gibi görünüyor.
Keller

75

Kombinasyonun cevabına dayanarak aşağıdaki SWIFT yardımcı sınıfını oluşturdum. Bu sınıfla, bunun bir hata ayıklama, test uçuşu veya uygulama mağazası derlemesi olup olmadığını belirleyebilirsiniz.

enum AppConfiguration {
  case Debug
  case TestFlight
  case AppStore
}

struct Config {
  // This is private because the use of 'appConfiguration' is preferred.
  private static let isTestFlight = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"
  
  // This can be used to add debug statements.
  static var isDebug: Bool {
    #if DEBUG
      return true
    #else
      return false
    #endif
  }

  static var appConfiguration: AppConfiguration {
    if isDebug {
      return .Debug
    } else if isTestFlight {
      return .TestFlight
    } else {
      return .AppStore
    }
  }
}

Ortam başına farklı izleme kimlikleri veya bağlantı dizeleri sağlamak için bu yöntemleri projemizde kullanıyoruz :

  func getURL(path: String) -> String {    
    switch (Config.appConfiguration) {
    case .Debug:
      return host + "://" + debugBaseUrl + path
    default:
      return host + "://" + baseUrl + path
    }
  }

VEYA:

  static var trackingKey: String {
    switch (Config.appConfiguration) {
    case .Debug:
      return debugKey
    case .TestFlight:
      return testflightKey
    default:
      return appstoreKey
    }
  }

GÜNCELLEME 05-02-2016: # if DEBUG gibi bir önişlemci makrosu kullanmanın ön koşulu, bazı Swift Derleyici Özel Bayraklarını ayarlamaktır. Bu cevapta daha fazla bilgi: https://stackoverflow.com/a/24112024/639227


1
@Urkman -D DEBUGBayrağı ayarladığınızdan emin olun . Daha fazla bilgiyi burada bulabilirsiniz .
Caleb

Thnx @Caleb, cevaba ön koşullar hakkında daha fazla açıklama ekledim.
LorenzoValentijn

1
Cevabınız için teşekkürler, çok yararlı buldum! Ayrıca #if targetEnvironment(simulator), bir simülatörde çalışıp çalışmadığınızı belirlemek de yararlıdır. Bu yüzden Simulator / TestFlight / AppStore seçeneklerine sahibim (benim durumumda tercih edilen Debug) :-)
JeroenJK

39

Simülatörleri açıklayan modern Swift sürümü (kabul edilen cevaba göre):

private func isSimulatorOrTestFlight() -> Bool {
    guard let path = Bundle.main.appStoreReceiptURL?.path else {
        return false
    }
    return path.contains("CoreSimulator") || path.contains("sandboxReceipt")
}

Simülatörü eklemek güzel, ancak artık tüm durumlar için geçerli olmadığından işlev adını değiştirmek isteyebilirsiniz.
dbn

2
VAOV! İşe yarıyor! Müthiş! Aynı derleme için TestFlight için DOĞRU ve AppStore için YANLIŞ döndürür (tek bir sağlama ile tek bir şemada derlenmiş bir derleme). Mükemmel! Teşekkür ederim!
Argus

@dbn bunun neden artık tüm durumlar için geçerli olmadığını açıklayabilir misiniz?
Ethan

1
@Ethan bu cevap benim yorumumu yaptıktan sonra düzenlendi; yöntem adı eskidenisTestFlight()
dbn


2

Bundle+isProductionSwift 5.2'de uzantı kullanıyorum :

import Foundation

extension Bundle {
    var isProduction: Bool {
        #if DEBUG
            return false
        #else
            guard let path = self.appStoreReceiptURL?.path else {
                return true
            }
            return !path.contains("sandboxReceipt")
        #endif
    }
}

Sonra:

if Bundle.main.isProduction {
    // do something
}

-3

Projelerim için kullanmanın bir yolu var. İşte adımlar.

Xcode'da proje ayarlarına gidin (proje, hedef değil) ve listeye "beta" yapılandırmasını ekleyin:

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



Ardından, projeyi "beta" yapılandırmasında çalıştıracak yeni bir şema oluşturmanız gerekir. Şema oluşturmak için buraya gidin:

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



Bu şemayı istediğiniz gibi adlandırın. Bu şema için ayarları düzenlemelisiniz. Bunu yapmak için buraya dokunun:

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



Seçebileceğiniz Arşiv sekmesini seçin Build configuration

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



Ardından , proje bilgileri özellik listesine aşağıdaki gibi Configdeğer içeren bir anahtar eklemeniz gerekir $(CONFIGURATION):

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



O halde, beta sürümüne özgü bir şey yapmak için kodda neye ihtiyacınız olduğu önemli:

let config = Bundle.main.object(forInfoDictionaryKey: "Config") as! String
if config == "Debug" {
  // app running in debug configuration
}
else if config == "Release" {
  // app running in release configuration
}
else if config == "Beta" {
  // app running in beta configuration
}

6
Bu yararlı bir teknik olsa da soruyu cevaplamaz. Tek bir ikili program App Store'a gönderilir ve TestFlight aracılığıyla indirmeden veya daha sonra App Store'dan indirildikten sonra onaylanan çalıştırmadan sonra çalıştırılabilir. Soru, hangi sürümün çalıştığını tespit etmekle ilgilidir.
kombinatoryal

İlk etapta 2 arşiv yapma seçeneği var mı? biri uygulama mağazası için test uçuşu için.
Klemen

Mümkün, ancak farklı yapı numaralarına sahip olmaları gerekiyor. Ve bu, bir yerine iki yapıyı yönetmek anlamına gelir.
kombinatoryal

tamam, bence buna değer. Özellikle sürekli entegrasyon araçları kullanıyorsanız.
Klemen

@KlemenZagar, yaklaşımınız iyi bilinen ve iyi bir yaklaşım ama soruya cevap vermiyor.
Stanislav Pankevich
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.