1.openURL
我們知道可以給應用設定URL Scheme,這樣別的應用就可以通過這個地址開啟咱們的應用。其實還有一個api叫canOpenURL.這樣如果咱們知道要檢查的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;
}
代碼方式
還有另外一種擷取app列表的方法,代碼在 https://github.com/danielamitay/iHasApp
它是利用application的openurl函數,遍曆一個5000個app id列表,一個一個在你的iphone上嘗試開啟這些app,這種實現方式會很快把你的iphone變成暖手寶,只能當個joke。
原文:點擊開啟連結
不過這種方法需要機器已經越獄,還需要你的應用不在沙箱裡,由於後一條筆者還不大會搞,所以沒試成功:)