gpt4 book ai didi

ios - 如何检测当前正在运行的应用程序是否是从应用程序商店安装的?

转载 作者:IT王子 更新时间:2023-10-29 07:57:36 32 4
gpt4 key购买 nike

在 iOS 中有没有办法以编程方式检查当前正在运行的应用程序是否是从 iOS App Store 安装的?这与通过 Xcode、TestFlight 或任何非官方分发源运行的应用形成对比。

这是在无法访问应用源代码的 SDK 的上下文中。

要清楚 - 我正在寻找一些签名,可以这么说,给应用程序(大概是苹果),在不依赖任何预处理器标志或其他构建配置的情况下,任何应用程序都可以在运行时访问.

最佳答案

从 App Store 下载的应用程序有一个商店添加的 iTunesMetadata.plist 文件:

NSString *file=[NSHomeDirectory() stringByAppendingPathComponent:@"iTunesMetadata.plist"];
if ([[NSFileManager defaultManager] fileExistsAtPath:file]) {
// probably a store app
}

也许您可能想检查此文件是否存在。

更新:

在 iOS8 中,应用程序包已被移动。根据 @silyevsk 的说法,plist 现在比 [新应用程序主包路径] 高一级,位于/private/var/mobile/Containers/Bundle/Application/4A74359F-E6CD-44C9-925D-AC82E‌‌ B5EA837/iTunesMetadata.plist,不幸的是,无法从应用程序访问它(权限被拒绝)

2015 年 11 月 4 日更新:

看来检查收据名称会有帮助。必须注意,此解决方案略有不同:它不返回我们是否正在运行 App Store 应用程序,而是返回我们是否正在运行测试版 Testflight 应用程序。这可能有用也可能没用,具体取决于您的上下文。

最重要的是,这是一个非常脆弱的解决方案,因为收据名称可能随时更改。无论如何我都会报告它,以防你没有其他选择:

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

基于 HockeyKit 类的可能的 Swift 类可能是:

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

}

要点:GitHub - mvarie/WhereAmIRunning.swift

2016 年 12 月 9 日更新:

用户 halileohalilei 报告说“这不再适用于 iOS10 和 Xcode 8”。我没有验证这一点,但请检查更新的 HockeyKit 源代码(参见函数 bit_currentAppEnvironment):

来源:GitHub - bitstadium/HockeySDK-iOS - BITHockeyHelper.m

随着时间的推移,上面的类已经被修改,它似乎也可以处理 iOS10。

2020 年 10 月 6 日更新:

Hockey 已被弃用/放弃,取而代之的是 Microsoft 的 AppCenter SDK。

这是他们的 App Store/Testflight 构建检测类(链接到代码下方的存储库):

MSUtility+Environment.h :

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#import <Foundation/Foundation.h>

#import "MSUtility.h"

/*
* Workaround for exporting symbols from category object files.
*/
extern NSString *MSUtilityEnvironmentCategory;

/**
* App environment
*/
typedef NS_ENUM(NSInteger, MSEnvironment) {

/**
* App has been downloaded from the AppStore.
*/
MSEnvironmentAppStore = 0,

/**
* App has been downloaded from TestFlight.
*/
MSEnvironmentTestFlight = 1,

/**
* App has been installed by some other mechanism.
* This could be Ad-Hoc, Enterprise, etc.
*/
MSEnvironmentOther = 99
};

/**
* Utility class that is used throughout the SDK.
* Environment part.
*/
@interface MSUtility (Environment)

/**
* Detect the environment that the app is running in.
*
* @return the MSEnvironment of the app.
*/
+ (MSEnvironment)currentAppEnvironment;

@end

MSUtility+Environment.m :

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#import "MSUtility+Environment.h"

/*
* Workaround for exporting symbols from category object files.
*/
NSString *MSUtilityEnvironmentCategory;

@implementation MSUtility (Environment)

+ (MSEnvironment)currentAppEnvironment {
#if TARGET_OS_SIMULATOR || TARGET_OS_OSX || TARGET_OS_MACCATALYST
return MSEnvironmentOther;
#else

// MobilePovision profiles are a clear indicator for Ad-Hoc distribution.
if ([self hasEmbeddedMobileProvision]) {
return MSEnvironmentOther;
}

/**
* TestFlight is only supported from iOS 8 onwards and as our deployment target is iOS 8, we don't have to do any checks for
* floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1).
*/
if ([self isAppStoreReceiptSandbox]) {
return MSEnvironmentTestFlight;
}

return MSEnvironmentAppStore;
#endif
}

+ (BOOL)hasEmbeddedMobileProvision {
BOOL hasEmbeddedMobileProvision = !![[NSBundle mainBundle] pathForResource:@"embedded" ofType:@"mobileprovision"];
return hasEmbeddedMobileProvision;
}

+ (BOOL)isAppStoreReceiptSandbox {
#if TARGET_OS_SIMULATOR
return NO;
#else
if (![NSBundle.mainBundle respondsToSelector:@selector(appStoreReceiptURL)]) {
return NO;
}
NSURL *appStoreReceiptURL = NSBundle.mainBundle.appStoreReceiptURL;
NSString *appStoreReceiptLastComponent = appStoreReceiptURL.lastPathComponent;

BOOL isSandboxReceipt = [appStoreReceiptLastComponent isEqualToString:@"sandboxReceipt"];
return isSandboxReceipt;
#endif
}

@end

来源:GitHub - microsoft/appcenter-sdk-apple - MSUtility+Environment.m

关于ios - 如何检测当前正在运行的应用程序是否是从应用程序商店安装的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18282326/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com