रनटाइम पर कैसे बताएं कि क्या iOS ऐप टेस्टफलाइट बीटा इंस्टॉल के माध्यम से चल रहा है


123

क्या रनटाइम पर यह पता लगाना संभव है कि ऐप स्टोर में टेस्टफलाइट बीटा (आईट्यून्स कनेक्ट के माध्यम से प्रस्तुत) के माध्यम से एक एप्लिकेशन इंस्टॉल किया गया है? आप एकल ऐप बंडल जमा कर सकते हैं और यह दोनों के माध्यम से उपलब्ध है। क्या कोई एपीआई है जो यह पता लगा सकता है कि यह किस तरह से स्थापित किया गया था? या क्या रसीद में ऐसी जानकारी है जो इसे निर्धारित करने की अनुमति देती है?


4
बस स्पष्ट होना चाहिए कि आप iTunes Test के माध्यम से नए TestFlight बीटा परीक्षण के बारे में बात कर रहे हैं? या आप के बारे में बात कर रहे हैं जब आप सीधे TestFlight पर अपलोड किया है?
केजी

नई TestFlight बीटा, स्पष्ट करेगी
मिश्रित

1
लगता है - [NSString में शामिल हैं:] एक ios8 जोड़ है। यदि ऐप स्टोर ऑटो परीक्षण ios7 पर इसे चलाने की कोशिश करता है, तो कोई भी नहीं। ([receurLString rangeOfString: @ "sandboxReceipt"] स्थान। = NSNotFound) को ट्रिक करना चाहिए।
राजगृह

@ सर्ज धन्यवाद, यह एक गूंगा गलती थी!
कॉम्बिनेटरियल

2
मैं iOS 6 पर पता लगाने के बारे में पूछने जा रहा था, जिसमें appStoreReceiptURL नहीं है, लेकिन ऐसा लगता है कि TestFlight ऐप केवल iOS 8 है; तो - [NSString में शामिल है] सब के बाद ठीक हो सकता है। मैंने ऐप स्टोर बीटा परीक्षण को इस वजह से होल्ड पर रखा है, लेकिन मुझे लगता है कि कुछ लोग हाइब्रिड परीक्षण रणनीति का उपयोग कर रहे होंगे, जो कि लीगेसी परीक्षण के लिए Ad-Hoc और सार्वजनिक बीटा के लिए AppStore बीटा के साथ हो सकता है, इसलिए RangeOfString अभी भी जीतता है।
गॉर्डन डोव

जवाबों:


117

TestFlight Beta के माध्यम से इंस्टॉल किए गए एप्लिकेशन के लिए रसीद फ़ाइल को StoreKit\sandboxReceiptसामान्य रूप से नामित किया गया है StoreKit\receipt। उपयोग करने से [NSBundle appStoreReceiptURL]आप URL के अंत में sandboxReceipt की तलाश कर सकते हैं।

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

ध्यान दें कि sandboxReceiptस्थानीय रूप से और सिम्युलेटर में चलने वाले बिल्ड के लिए रसीद फ़ाइल का नाम भी है।


7
जैसा कि उल्लेख किया गया है, यह डिवाइस पर स्थानीय परीक्षण के लिए काम करता है, लेकिन सिम्युलेटर पर नहीं। मैंने कुछ जोड़ा जैसे #if TARGET_IPHONE_SIMULATOR isRunningInTestMode = YES; #endif जाहिर है, इसके लिए #import <targetConditionals.h> की जरूरत है
गॉर्डन डव

13
कॉम्पैक्ट संस्करण: [[[[NSBundle mainBundle] appStoreReceiptURL] lastPathComponent] isEqualToString:@"sandboxReceipt"](सच है अगर टेस्टफलाइट चलाने वाला बाइनरी वितरित करता है) Supertop / Haddad के
Nick

2
एक्सटेंशन बंडल में इस विधि का उपयोग नहीं किया जा सकता है क्योंकि रसीद केवल होस्ट बंडल के लिए मौजूद है।
जियाउल

2
StoreKit/sandboxReceiptजब डिवाइस या सिम्युलेटर पर Xcode के माध्यम से डिबग बिल्ड के रूप में स्थापित किया जाता है तो मेरा iOS 8 परीक्षण परिणाम । तो यह अन्य सभी बिल्ड से टेस्टफ़लाइट बिल्ड को सटीक रूप से अलग नहीं कर सकता है।
pkamb

3
Ad Hoc वितरण के साथ बिल्ड स्थापित करते समय YES को वापस करना भी अच्छा लगता है।
केलर

75

कॉम्बीनेटरियल के उत्तर के आधार पर मैंने निम्नलिखित स्विफ्ट हेल्पर क्लास बनाई। इस वर्ग के साथ आप यह निर्धारित कर सकते हैं कि यह डिबग, टेस्टफलाइट या ऐपस्टोर बिल्ड है या नहीं।

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
    }
  }
}

हम अपने प्रोजेक्ट में इन विधियों का उपयोग विभिन्न ट्रैकिंग आईडी या कनेक्शन स्ट्रिंग प्रति वातावरण की आपूर्ति करने के लिए करते हैं :

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

या:

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

अद्यतन 05-02-2016: #if DEBUG जैसे प्रीप्रोसेसर मैक्रो का उपयोग करने के लिए कुछ स्विफ्ट कम्पाइलर कस्टम फ्लैग सेट करना आवश्यक है। इस उत्तर में अधिक जानकारी: https://stackoverflow.com/a/24112024/639227


1
@ Urkman सुनिश्चित करें कि आप -D DEBUGध्वज सेट कर रहे हैं । अधिक जानकारी यहां पाई जा सकती है
कालेब

Thnx @ कालेब, मैंने उत्तर के लिए पूर्वापेक्षाओं पर अधिक स्पष्टीकरण जोड़ा।
लोरेंजो वालेंटीजन

1
आपके उत्तर के लिए धन्यवाद, मुझे यह बहुत मददगार लगा! यह जानने के लिए भी अच्छा है कि #if targetEnvironment(simulator)आप यह निर्धारित करते हैं कि आप सिम्युलेटर में चल रहे हैं या नहीं। इसलिए मेरे पास विकल्प सिम्युलेटर / टेस्टफ़लाइट / AppStore (जो मेरे मामले में पसंदीदा है Debug) :-)
JeroenJK

39

आधुनिक स्विफ्ट संस्करण, जो सिमुलेटर के लिए खाता है (स्वीकृत उत्तर के आधार पर):

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

सिम्युलेटर को शामिल करना अच्छा है, लेकिन आप फ़ंक्शन का नाम बदलना चाहते हैं क्योंकि यह सभी मामलों के लिए सही नहीं है।
dbn

2
वाह! यह काम करता हैं! बहुत बढ़िया! एक ही बिल्ड (एक प्रावधान के साथ एक योजना में निर्मित एक) के लिए AppStore के लिए TestFlight और FALSE के लिए TRUE लौटाता है। उत्तम! धन्यवाद!
अर्गस

@dbn क्या आप इसका विस्तार कर सकते हैं कि यह सभी मामलों के लिए सही क्यों नहीं है?
एथन

1
@ यह उत्तर मुझे अपनी टिप्पणी के बाद संपादित किया गया था; विधि का नाम इस्तेमाल किया जा रहा हैisTestFlight()
dbn

6

अपडेट करें

यह किसी भी अधिक काम नहीं करता है। अन्य विधि का प्रयोग करें।

मूल उत्तर

यह भी काम करता है:

if NSBundle.mainBundle().pathForResource("embedded", ofType: "mobileprovision") != nil {
    // TestFlight
} else {
    // App Store (and Apple reviewers too)
}

अगर आईओएस ऐप को ऐप्पल की टेस्टफलाइट से डाउनलोड किया जाता है तो डिटेक्ट में पाया जाता है


2

मैं Bundle+isProductionस्विफ्ट 5.2 पर एक्सटेंशन का उपयोग करता हूं :

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
    }
}

फिर:

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

-3

एक तरीका है कि मैं इसे अपनी परियोजनाओं के लिए उपयोग करता हूं। यहाँ कदम हैं।

Xcode में, प्रोजेक्ट सेटिंग्स पर जाएं (प्रोजेक्ट, लक्ष्य नहीं) और सूची में "बीटा" कॉन्फ़िगरेशन जोड़ें:

यहाँ छवि विवरण दर्ज करें



फिर आपको नई योजना बनाने की आवश्यकता है जो "बीटा" कॉन्फ़िगरेशन में प्रोजेक्ट चलाएगी। योजना बनाने के लिए यहां जाएं:

यहाँ छवि विवरण दर्ज करें



इस योजना का नाम जो आप चाहते हैं। आपको इस योजना के लिए सेटिंग्स संपादित करनी चाहिए। ऐसा करने के लिए, यहां टैप करें:

यहाँ छवि विवरण दर्ज करें



जहाँ आप चयन कर सकते हैं आर्क टैब चुनें Build configuration

यहाँ छवि विवरण दर्ज करें



तो फिर तुम इस तरह की संपत्ति जानकारी की सूची के Configमूल्य $(CONFIGURATION)के साथ एक कुंजी जोड़ने की जरूरत है :

यहाँ छवि विवरण दर्ज करें



फिर इसका सिर्फ यह मामला है कि आपको बीटा बिल्ड के लिए कुछ विशिष्ट करने के लिए कोड में क्या चाहिए:

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
जबकि यह एक सहायक तकनीक है यह सवाल का जवाब नहीं देता है। एक एकल बाइनरी ऐप स्टोर में सबमिट किया जाता है और इसे या तो टेस्टफलाइट के माध्यम से डाउनलोड करने से या बाद में ऐप स्टोर से डाउनलोड करने के बाद अनुमोदित रन से चलाया जा सकता है। सवाल यह पता लगाने के बारे में है कि कौन सा संस्करण चल रहा है।
मिश्रित

क्या पहली जगह में 2 अभिलेखागार बनाने का विकल्प है। ऐप स्टोर के लिए एक परीक्षण के लिए एक।
क्लेमेन

यह संभव है, लेकिन उनके पास अलग-अलग बिल्ड नंबर होने चाहिए। और इसका मतलब है कि एक के बजाय दो बिल्ड का प्रबंधन करना।
मिश्रित

ठीक है, मेरी राय में यह इसके लायक है। खासकर यदि आप निरंतर एकीकरण उपकरण का उपयोग करते हैं।
क्लेमेन

@ क्लेमेनजागर, आपका दृष्टिकोण एक प्रसिद्ध और अच्छा है लेकिन यह सवाल का जवाब नहीं देता है।
स्टैनिस्लाव पानकेविच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.