приложения, загруженные из App Store есть iTunesMetadata.plist
файл добавлен в магазин:
NSString *file=[NSHomeDirectory() stringByAppendingPathComponent:@"iTunesMetadata.plist"];
if ([[NSFileManager defaultManager] fileExistsAtPath:file]) {
// probably a store app
}
Может быть, вы могли бы хотеть, чтобы проверить, существует ли этот файл.
Update:
В iOS8, расслоение приложение было перемещено. Согласно @silyevsk, , plist теперь находится на одном уровне выше [путь основного пула приложений], на/private/var/mobile/Containers/Bundle/Application/4A74359F-E6CD-44C9-925D-AC82E B5EA837/iTunesMetadata .plist, и, к сожалению, это не может получить доступ из приложения (доступ запрещен)
Update Nov 4th 2015:
Вероятно, что проверка имени квитанций может помочь. Следует отметить, что это решение немного отличается: оно не возвращает, работает ли приложение App Store, а работает ли приложение для бета-тестирования. Это может быть или не быть полезным в зависимости от вашего контекста.
Кроме того, это очень хрупкое решение, поскольку имя квитанции может измениться в любое время. Я все равно буду сообщать об этом, в случае, если у вас нет других вариантов:
// Objective-C
BOOL isRunningTestFlightBeta = [[[[NSBundle mainBundle] appStoreReceiptURL] lastPathComponent] isEqualToString:@"sandboxReceipt"];
// Swift
let isRunningTestFlightBeta = NSBundle.mainBundle().appStoreReceiptURL?.lastPathComponent=="sandboxReceipt"
Источник: Detect if iOS App is Downloaded from Apple's Testflight
Как HockeyKit делает
Комбинируя различные проверки вы можете догадаться, является ли приложение работает в симуляторе, в сборке Testflight или в сборке AppStore.
Вот сегмент от HockeyKit:
BOOL bit_isAppStoreReceiptSandbox(void) {
#if TARGET_OS_SIMULATOR
return NO;
#else
NSURL *appStoreReceiptURL = NSBundle.mainBundle.appStoreReceiptURL;
NSString *appStoreReceiptLastComponent = appStoreReceiptURL.lastPathComponent;
BOOL isSandboxReceipt = [appStoreReceiptLastComponent isEqualToString:@"sandboxReceipt"];
return isSandboxReceipt;
#endif
}
BOOL bit_hasEmbeddedMobileProvision(void) {
BOOL hasEmbeddedMobileProvision = !![[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
return hasEmbeddedMobileProvision;
}
BOOL bit_isRunningInTestFlightEnvironment(void) {
#if TARGET_OS_SIMULATOR
return NO;
#else
if (bit_isAppStoreReceiptSandbox() && !bit_hasEmbeddedMobileProvision()) {
return YES;
}
return NO;
#endif
}
BOOL bit_isRunningInAppStoreEnvironment(void) {
#if TARGET_OS_SIMULATOR
return NO;
#else
if (bit_isAppStoreReceiptSandbox() || bit_hasEmbeddedMobileProvision()) {
return NO;
}
return YES;
#endif
}
BOOL bit_isRunningInAppExtension(void) {
static BOOL isRunningInAppExtension = NO;
static dispatch_once_t checkAppExtension;
dispatch_once(&checkAppExtension, ^{
isRunningInAppExtension = ([[[NSBundle mainBundle] executablePath] rangeOfString:@".appex/"].location != NSNotFound);
});
return isRunningInAppExtension;
}
Источник: GitHub - bitstadium/HockeySDK-iOS - BITHockeyHelper.m
Возможный Swift класс, основанный на классе HockeyKit, в может быть:
//
// WhereAmIRunning.swift
// https://gist.github.com/mvarie/63455babc2d0480858da
//
// ### Detects whether we're running in a Simulator, TestFlight Beta or App Store build ###
//
// Based on https://github.com/bitstadium/HockeySDK-iOS/blob/develop/Classes/BITHockeyHelper.m
// Inspired by https://stackoverflow.com/questions/18282326/how-can-i-detect-if-the-currently-running-app-was-installed-from-the-app-store
// Created by marcantonio on 04/11/15.
//
import Foundation
class WhereAmIRunning {
// MARK: Public
func isRunningInTestFlightEnvironment() -> Bool{
if isSimulator() {
return false
} else {
if isAppStoreReceiptSandbox() && !hasEmbeddedMobileProvision() {
return true
} else {
return false
}
}
}
func isRunningInAppStoreEnvironment() -> Bool {
if isSimulator(){
return false
} else {
if isAppStoreReceiptSandbox() || hasEmbeddedMobileProvision() {
return false
} else {
return true
}
}
}
// MARK: Private
private func hasEmbeddedMobileProvision() -> Bool{
if let _ = NSBundle.mainBundle().pathForResource("embedded", ofType: "mobileprovision") {
return true
}
return false
}
private func isAppStoreReceiptSandbox() -> Bool {
if isSimulator() {
return false
} else {
if let appStoreReceiptURL = NSBundle.mainBundle().appStoreReceiptURL,
let appStoreReceiptLastComponent = appStoreReceiptURL.lastPathComponent
where appStoreReceiptLastComponent == "sandboxReceipt" {
return true
}
return false
}
}
private func isSimulator() -> Bool {
#if arch(i386) || arch(x86_64)
return true
#else
return false
#endif
}
}
Gist: GitHub - mvarie/WhereAmIRunning.swift
U pdate 9 декабря 2016 года:
Пользователь halileohalilei сообщает, что «это больше не работает с iOS10 и Xcode 8.». Я не проверял это, но, пожалуйста, проверьте обновленный источник HockeyKit (см функции bit_currentAppEnvironment
) по адресу:
Источник: GitHub - bitstadium/HockeySDK-iOS - BITHockeyHelper.m
Со времени, выше класс был изменен, и это, кажется, для обработки iOS10, а также.
Просьба уточнить. Что вы подразумеваете под SDK? Вы строите библиотеку? Вы строите SDK, который выводит приложение à la Titanium? В этом случае вы все равно строите приложение, так что, хотя вам может быть запрещено получать доступ к исходному коду вашего суб-приложения, вы определенно контролируете запущенное приложение. – magma
Чтобы быть ясным - вы ищете какую-либо подпись, если можно так выразиться, приложение (предположительно, Apple), которое будет независимо от каких-либо препроцессорных флагов или других конфигураций сборки быть доступным для любого приложения во время выполнения? –
@CarlVeazey Да, это точно есть. – kevlar