获取IOS应用安装列表


当两天没事儿,突然想起这么一个命题:获取IOS应用安装列表。

研究来研究去最后也没有得出个所以然来。这不今天上网,发现这篇儿文章。晾这说有三种方法。也就顺便总结一下,边转载边补充。

ok,说是三种方法,靠谱的两种:

1.openURL

我们知道可以给应用设置URL Scheme,这样别的应用就可以通过这个地址打开咱们的应用。其实还有一个apicanOpenURL.这样如果咱们知道要检查的IOS应用列表的URL Scheme的话,就可以用canOpenURL检查一下。

2.获取运行程序列表

// .h

@interface UIDevice (ProcessesAdditions)
- (NSArray *)runningProcesses;
@end

// .m
#import <sys/sysctl.h>

@implementation UIDevice (ProcessesAdditions)

- (NSArray *)runningProcesses {
    
    int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
    size_t miblen = 4;
    
    size_t size;
    int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
    
    struct kinfo_proc * process = NULL;
    struct kinfo_proc * newprocess = NULL;
    
    do {
        
        size += size / 10;
        newprocess = realloc(process, size);
        
        if (!newprocess){
            
            if (process){
                free(process);
            }
            
            return nil;
        }
        
        process = newprocess;
        st = sysctl(mib, miblen, process, &size, NULL, 0);
        
    } while (st == -1 && errno == ENOMEM);
    
    if (st == 0){
        
        if (size % sizeof(struct kinfo_proc) == 0){
            int nprocess = size / sizeof(struct kinfo_proc);
            
            if (nprocess){
                
                NSMutableArray * array = [[NSMutableArray alloc] init];
                
                for (int i = nprocess - 1; i >= 0; i--){
                    
                    NSString * processID = [[NSString alloc] initWithFormat:@"%d", process[i].kp_proc.p_pid];
                    NSString * processName = [[NSString alloc] initWithFormat:@"%s", process[i].kp_proc.p_comm];
                    
                    NSDictionary * dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName, nil]
                                                                        forKeys:[NSArray arrayWithObjects:@"ProcessID", @"ProcessName", nil]];
                    [processID release];
                    [processName release];
                    [array addObject:dict];
                    [dict release];
                }
                
                free(process);
                return [array autorelease];
            }
        }
    }
    
    return nil;
}

@end

// Example usage.
NSArray * processes = [[UIDevice currentDevice] runningProcesses];
for (NSDictionary * dict in processes){
    NSLog(@"%@ - %@", [dict objectForKey:@"ProcessID"], [dict objectForKey:@"ProcessName"]);
}


这种方法是获取运行中的应用列表。如果应用没被运行过或不在后台,就得不到喽。


比起上面两个方法要靠谱一点儿的就是私有API了。

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;
    NSLog(@"relativeCachePath:%@",relativeCachePath);
    // 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;
        NSLog(@"path:%@",path);
        // Ensure that file exists
        if ([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isDir] && !isDir){
            cacheDict = [NSDictionary dictionaryWithContentsOfFile: path];
        }
        
        // If cache is loaded, then break the loop. If the loop is not "broken," it will return NO later (default: case)
        if (cacheDict){
            NSLog(@"cacheDict:%@",cacheDict);
            break;
        }
        
    }
    
    NSLog(@"gggg");
    // First check all system (jailbroken) apps
    NSDictionary *system = [cacheDict objectForKey: @"System"];
    NSLog(@"system:%@",system);
    if ([system objectForKey: bundleIdentifier]){
        return YES;
    }
    
    // Then all the user (App Store /var/mobile/Applications) apps
    NSDictionary *user = [cacheDict objectForKey: @"User"];
    NSLog(@"user:%@",user);
    if ([user objectForKey: bundleIdentifier]){
        return YES;
    }
    
    // If nothing returned YES already, we'll return NO now
    return NO;
}



不过这种方法需要机器已经越狱,还需要你的应用不在沙盒里,由于后一条笔者还不大会搞,所以没试成功:)


转自鸟哥:http://blog.cnrainbird.com/index.php/2012/04/19/guan_yu_huo_qu_ios_ying_yong_lie_biao/



你可能感兴趣的:(获取IOS应用安装列表)