繁体   English   中英

是否有可能获得有关iPhone上安装的所有应用程序的信息?

[英]Is it possible to get information about all apps installed on iPhone?

是否可以获取有关iPhone / iPod上已安装的所有应用程序的信息(应用程序图标,应用程序名称,应用程序位置)?

在iPhone中安装应用程序的另一种方法是调用:

NSString *rootAppPath = @"/Applications";
NSArray *listApp = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:rootAppPath error:nil];

然后,您可以在每个应用程序中访问它们的字典Info.plist以了解有关这些应用程序的更多信息。

更新:显然,此方法不再起作用(对于iOS8)导致我们的应用程序无权查看/ Applications的内容

当设备是Jailbroken时,你肯定可以这样做,这样你就可以伸出sandBox了。 您可以通过分析位于每个路径“/ var / mobile / Applications /”的每个.app中的 Info.plist来获取所需的信息,例如“/ var / mobile / Applications / /*.app/Info.plist “这是我的代码。

- (void)scan
{

    NSString *pathOfApplications = @"/var/mobile/Applications";

    NSLog(@"scan begin");

    // all applications
    NSArray *arrayOfApplications = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pathOfApplications error:nil];
    for (NSString *applicationDir in arrayOfApplications) {
        // path of an application
        NSString *pathOfApplication = [pathOfApplications stringByAppendingPathComponent:applicationDir];
        NSArray *arrayOfSubApplication = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pathOfApplication error:nil];
        // seek for *.app
        for (NSString *applicationSubDir in arrayOfSubApplication) {
            if ([applicationSubDir hasSuffix:@".app"]) {// *.app
                NSString *path = [pathOfApplication stringByAppendingPathComponent:applicationSubDir];

                path = [path stringByAppendingPathComponent:@"Info.plist"];

                // so you get the Info.plist in the dict
                NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
                // code to analyzing the dict.
            }
        }
    }

    NSLog(@"scan end");
}

以下是Info.plist的示例内容。 因此,获取您关心的任何密钥的值。

{
BuildMachineOSBuild = 11G63;
CFBundleDevelopmentRegion = "zh_CN";
CFBundleDisplayName = "\U4e50\U89c6\U5f71\U89c6HD";
CFBundleExecutable = LetvIpadClient;
CFBundleIconFile = "icon.png";
CFBundleIconFiles =     (
    "icon.png",
    "icon@2x.png"
);
CFBundleIdentifier = "com.letv.ipad.hdclient";
CFBundleInfoDictionaryVersion = "6.0";
CFBundleName = LetvIpadClient;
CFBundlePackageType = APPL;
CFBundleResourceSpecification = "ResourceRules.plist";
CFBundleShortVersionString = "3.1";
CFBundleSignature = "????";
CFBundleSupportedPlatforms =     (
    iPhoneOS
);
CFBundleURLTypes =     (
            {
        CFBundleURLName = "m.letv.com";
        CFBundleURLSchemes =             (
            letvIPad
        );
    }
);
CFBundleVersion = "3.1";
DTCompiler = "com.apple.compilers.llvmgcc42";
DTPlatformBuild = 10A403;
DTPlatformName = iphoneos;
DTPlatformVersion = "6.0";
DTSDKBuild = 10A403;
DTSDKName = "iphoneos6.0";
DTXcode = 0450;
DTXcodeBuild = 4G182;
LSRequiresIPhoneOS = 0;
MinimumOSVersion = "4.3";
UIDeviceFamily =     (
    2
);
"UILaunchImageFile~ipad" =     (
    "Default.png",
    "Default@2x.png"
);
UIPrerenderedIcon = 1;
UIStatusBarHidden = 1;
UISupportedInterfaceOrientations =     (
    UIInterfaceOrientationPortrait,
    UIInterfaceOrientationPortraitUpsideDown,
    UIInterfaceOrientationLandscapeLeft,
    UIInterfaceOrientationLandscapeRight
);
"UISupportedInterfaceOrientations~ipad" =     (
    UIInterfaceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeLeft
);
}

有一种方法可以检查是否安装了应用程序,但是,它确实违反了沙盒规则,Apple *可能会拒绝您的应用程序使用它。 但是之前App Store中提供的其他应用程序已经完成,所以请随意尝试

有时您可能想要检查设备上是否安装了特定的应用程序,以防您使用需要安装其他应用程序的自定义URL方案(您可能只是灰显/禁用某些按钮)。 不幸的是,Apple显然没有任何功能可以为你检查这个,所以我鞭打了一个。 它不会枚举每个应用程序,而是使用MobileInstallation缓存,它始终与SpringBoard保持同步,并保存所有已安装应用程序的信息词典。 虽然您并不“应该”访问缓存,但App Store应用程序可以读取它。 这是我的代码,至少与模拟器2.2.1完全一致:代码:

// Declaration
BOOL APCheckIfAppInstalled(NSString *bundleIdentifier); // Bundle identifier (eg. com.apple.mobilesafari) used to track apps

// Implementation

BOOL APCheckIfAppInstalled(NSString *bundleIdentifier)
{
    static NSString *const cacheFileName = @"com.apple.mobile.installation.plist";
    NSString *relativeCachePath = [[@"Library" stringByAppendingPathComponent: @"Caches"] stringByAppendingPathComponent: cacheFileName];
    NSDictionary *cacheDict = nil;
    NSString *path = nil;
    // Loop through all possible paths the cache could be in
    for (short i = 0; 1; i++)
    {

        switch (i) {
    case 0: // Jailbroken apps will find the cache here; their home directory is /var/mobile
        path = [NSHomeDirectory() stringByAppendingPathComponent: relativeCachePath];
        break;
    case 1: // App Store apps and Simulator will find the cache here; home (/var/mobile/) is 2 directories above sandbox folder
        path = [[NSHomeDirectory() stringByAppendingPathComponent: @"../.."] stringByAppendingPathComponent: relativeCachePath];
        break;
    case 2: // If the app is anywhere else, default to hardcoded /var/mobile/
        path = [@"/var/mobile" stringByAppendingPathComponent: relativeCachePath];
        break;
    default: // Cache not found (loop not broken)
        return NO;
        break; }

        BOOL isDir = NO;
        if ([[NSFileManager defaultManager] fileExistsAtPath: path isDirectory: &isDir] && !isDir) // Ensure that file exists
            cacheDict = [NSDictionary dictionaryWithContentsOfFile: path];

        if (cacheDict) // If cache is loaded, then break the loop. If the loop is not "broken," it will return NO later (default: case)
            break;
    }

    NSDictionary *system = [cacheDict objectForKey: @"System"]; // First check all system (jailbroken) apps
    if ([system objectForKey: bundleIdentifier]) return YES;
    NSDictionary *user = [cacheDict objectForKey: @"User"]; // Then all the user (App Store /var/mobile/Applications) apps
    if ([user objectForKey: bundleIdentifier]) return YES;

    // If nothing returned YES already, we'll return NO now
    return NO;
}

下面是一个示例,假设您的应用程序名为“yourselfmadeapp”,并且是应用程序商店中的应用程序。 码:

NSArray *bundles2Check = [NSArray arrayWithObjects: @"com.apple.mobilesafari", @"com.yourcompany.yourselfmadeapp", @"com.blahblah.nonexistent", nil];
for (NSString *identifier in bundles2Check)
    if (APCheckIfAppInstalled(identifier))
        NSLog(@"App installed: %@", identifier);
    else
        NSLog(@"App not installed: %@", identifier);

日志输出:代码:

2009-01-30 12:19:20.250 SomeApp [266:20b] App安装:com.apple.mobilesafari 2009-01-30 12:19:20.254 SomeApp [266:20b] App安装:com.yourcompany.yourselfmadeapp 2009- 01-30 12:19:20.260 SomeApp [266:20b] App未安装:com.blahblah.nonexistent

在使用它之前试试这个,我认为Apple改变了MobileInstallation.plist所在的位置,如果你确实改变了它,可以在实际的设备而不是模拟器上试试。 祝好运!

http://www.iphonedevsdk.com/forum/iphone-sdk-development/37103-finding-out-what-apps-installed.html

PK

试试这个,它甚至可以用于非越狱设备

#include <objc/runtime.h>
Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
SEL selector=NSSelectorFromString(@"defaultWorkspace");
NSObject* workspace = [LSApplicationWorkspace_class performSelector:selector];

SEL selectorALL = NSSelectorFromString(@"allApplications");
NSLog(@"apps: %@", [workspace performSelector:selectorALL]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM