2011-12-27 29 views
7

Tengo una aplicación que necesita para obtener la lista de aplicaciones instaladas (otras, tal vez de terceros) en el dispositivo. ¿Cómo puede hacerse esto? ¿O se puede hacer en absoluto?obtener lista de aplicaciones instaladas en iphone objetivo-c

+2

Este es uno duplicado, consulte siguiente thread- http://stackoverflow.com/questions/4614114/get-list-of-installed-apps- on-iphone – rishi

+0

¿Existen bibliotecas de terceros para hacer este truco? – Oleg

+0

gracias @rishi. Me lo perdí. Por favor responde mi pregunta con tu comentario. – Oleg

Respuesta

3

Dudo si hay algo disponible (si algún iPhone tiene jailbreak y el usuario puede acceder al sistema de archivos, entonces será posible, pero no estoy al tanto de esto), pero puede usar el siguiente link y con la ayuda de esto puede verificar qué aplicaciones están presentes y puede personalizarlas con algunas de sus necesidades.

5

no hay ninguna API pública de manzana en busca de dicha lista desde el dispositivo iOS (iPod Touch/iPhone/iPad)

6
-(NSArray *) installedApps 
{ 
    BOOL isDir enter code here= NO; 
    NSDictionary *cacheDienter code herect; 
    NSDictionary *user; 
    static NSString *const cacheFileName = @"com.apple.mobile.installation.plist"; 
    NSString *relativeCachePath = [[@"Library" stringByAppendingPathComponent: @"Caches"] stringByAppendingPathComponent: cacheFileName]; 
    NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent: @"../.."] stringByAppendingPathComponent: relativeCachePath]; 
    if ([[NSFileManager defaultManager] fileExistsAtPath: path isDirectory: &isDir] && !isDir) // Ensure that file exists 
    { 
     cacheDict = [NSDictionary dictionaryWithContentsOfFile: path]; 
     user = [cacheDict objectForKey: @"System"]; // Then all the user (App Store /var/mobile/Applications) apps 
    } 



    //NSLog(@"Installed Applications = %@",[user allKeys]); 
    //return [user allKeys]; 
    return nil; 
} 

esto le dará la matriz del nombre de la aplicación instalada usando API privada

+2

No funciona en iOS 6 en el dispositivo. El archivo no existe. –

16

Puede escanear todas sus aplicaciones a través del marco privado de Apple "MobileInstallationInstall".

El método es, como a continuación:

NSDictionary *options = [NSDictionary dictionaryWithKeyAndValues:@"ApplicationType",@"Any",nil] 
NSDictionary *apps = MobileInstallationLookup(options); 

que sólo se puede utilizar en dispositivos JB.

+1

En realidad. También podría usarse en dispositivos encarcelados. Sin embargo, no puedes obtener una aplicación con este código para AppStore, porque es una API privada. –

+0

¿Cómo puedo obtener los encabezados para MobileInstallationInstall? – EwyynTomato

+0

@EwyynTomato: los encabezados se pueden encontrar como ejemplos aquí: https://github.com/Cykey/ios-reversed-headers/blob/master/MobileInstallation/MobileInstallation.h –

2

Esto no proporciona la Lista de aplicaciones instaladas, pero puede obtener la Lista de aplicaciones que se ejecutan en segundo plano y sus procesos afectados por este código.

llamada de viewDidLoad -

[self printProcessInfo]; 

.

-(NSMutableString*) printProcessInfo { 
int mib[5]; 
struct kinfo_proc *procs = NULL, *newprocs; 
int i, st, nprocs; 
size_t miblen, size; 

/* Set up sysctl MIB */ 
mib[0] = CTL_KERN; 
mib[1] = KERN_PROC; 
mib[2] = KERN_PROC_ALL; 
mib[3] = 0; 
miblen = 4; 

/* Get initial sizing */ 
st = sysctl(mib, miblen, NULL, &size, NULL, 0); 

/* Repeat until we get them all ... */ 
do { 
     /* Room to grow */ 
     size += size/10; 
     newprocs = realloc(procs, size); 
     if (!newprocs) { 
      if (procs) { 
       free(procs); 
      } 
      perror("Error: realloc failed."); 
      return (0); 
     } 
     procs = newprocs; 
     st = sysctl(mib, miblen, procs, &size, NULL, 0); 
} while (st == -1 && errno == ENOMEM); 

if (st != 0) { 
     perror("Error: sysctl(KERN_PROC) failed."); 
     return (0); 
} 

/* Do we match the kernel? */ 
assert(size % sizeof(struct kinfo_proc) == 0); 

nprocs = size/sizeof(struct kinfo_proc); 

if (!nprocs) { 
     perror("Error: printProcessInfo."); 
     return(0); 
} 
printf(" PID\tName\n"); 
printf("-----\t--------------\n"); 
self.lists = [[NSMutableString alloc] init]; 
NSMutableString *localStr = [[NSMutableString alloc] init]; 
for (i = nprocs-1; i >=0; i--) { 
     // printf("%5d\t%s\n",(int)procs[i].kp_proc.p_pid, procs[i].kp_proc.p_comm); 


     localStr = [NSString stringWithFormat:@"%@,\nPID:-%5d,\tPROCESS_NAME:-%s\n",localStr,(int)procs[i].kp_proc.p_pid, procs[i].kp_proc.p_comm ]; 
     NSString *pathStr = [self print_argv_of_pid:(int)procs[i].kp_proc.p_pid]; 
     //NSString *pathStr = print_argv_of_pid:(((int)procs[i].kp_proc.p_pid)); 
     localStr = [NSString stringWithFormat:@"%@,\n%@\n",localStr,pathStr ]; 
    // [self getAttributesOfProcess]; 
     //printf("%s",path); 


} 
NSLog(@"%@",lists); 

free(procs); 
return localStr; 
//return (0); 
} 



-(NSString*) print_argv_of_pid:(int) pid { 

char path[1000]; 
printf("%d\n", pid); 
int mib[3], argmax, nargs, c = 0; 
size_t size; 
char *procargs, *sp, *np, *cp; 
extern int eflg; 
int show_args = 1; 

mib[0] = CTL_KERN; 
mib[1] = KERN_ARGMAX; 

size = sizeof(argmax); 
if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1) { 
     return @""; 
     //goto ERROR_A; 
} 

/* Allocate space for the arguments. */ 
procargs = (char *)malloc(argmax); 
if (procargs == NULL) { 
     return @""; 
     //goto ERROR_A; 
} 


/* 
    * Make a sysctl() call to get the raw argument space of the process. 
    * The layout is documented in start.s, which is part of the Csu 
    * project. In summary, it looks like: 
    * 
    * /---------------\ 0x00000000 
    * :    : 
    * :    : 
    * |---------------| 
    * | argc   | 
    * |---------------| 
    * | arg[0]  | 
    * |---------------| 
    * :    : 
    * :    : 
    * |---------------| 
    * | arg[argc - 1] | 
    * |---------------| 
    * | 0    | 
    * |---------------| 
    * | env[0]  | 
    * |---------------| 
    * :    : 
    * :    : 
    * |---------------| 
    * | env[n]  | 
    * |---------------| 
    * | 0    | 
    * |---------------| <-- Beginning of data returned by sysctl() is here. 
    * | argc   | 
    * |---------------| 
    * | exec_path  | 
    * |:::::::::::::::| 
    * |    | 
    * | String area. | 
    * |    | 
    * |---------------| <-- Top of stack. 
    * :    : 
    * :    : 
    * \---------------/ 0xffffffff 
    */ 
mib[0] = CTL_KERN; 
mib[1] = KERN_PROCARGS2; 
mib[2] = pid; 


size = (size_t)argmax; 
if (sysctl(mib, 3, procargs, &size, NULL, 0) == -1) { 
     //goto ERROR_B; 
     return @""; 
} 

memcpy(&nargs, procargs, sizeof(nargs)); 
cp = procargs + sizeof(nargs); 

/* Skip the saved exec_path. */ 
for (; cp < &procargs[size]; cp++) { 
     if (*cp == '\0') { 
      /* End of exec_path reached. */ 
      break; 
     } 
} 
if (cp == &procargs[size]) { 
     //goto ERROR_B; 
     return @""; 
} 

/* Skip trailing '\0' characters. */ 
for (; cp < &procargs[size]; cp++) { 
     if (*cp != '\0') { 
      /* Beginning of first argument reached. */ 
      break; 
     } 
} 
if (cp == &procargs[size]) { 
     //goto ERROR_B; 
     return @""; 
} 
/* Save where the argv[0] string starts. */ 
sp = cp; 

/* 
    * Iterate through the '\0'-terminated strings and convert '\0' to ' ' 
    * until a string is found that has a '=' character in it (or there are 
    * no more strings in procargs). There is no way to deterministically 
    * know where the command arguments end and the environment strings 
    * start, which is why the '=' character is searched for as a heuristic. 
    */ 
for (np = NULL; c < nargs && cp < &procargs[size]; cp++) { 
     if (*cp == '\0') { 
      c++; 
      if (np != NULL) { 
       /* Convert previous '\0'. */ 
       *np = ' '; 
      } else { 
       /* *argv0len = cp - sp; */ 
      } 
      /* Note location of current '\0'. */ 
      np = cp; 

      if (!show_args) { 
       /* 
       * Don't convert '\0' characters to ' '. 
       * However, we needed to know that the 
       * command name was terminated, which we 
       * now know. 
       */ 
       break; 
      } 
     } 
} 

/* 
    * sp points to the beginning of the arguments/environment string, and 
    * np should point to the '\0' terminator for the string. 
    */ 
if (np == NULL || np == sp) { 
     /* Empty or unterminated string. */ 
     // goto ERROR_B; 
     return @""; 
} 

/* Make a copy of the string. */ 
// printf("%s\n", sp); 
//path = sp; 
memset(path,0,1000); 
strcpy(path, sp); 
NSString *pathStr = [NSString stringWithFormat:@"%s",path]; 
NSLog(@"%@",pathStr); 
// printf("%s\n", path); 
/* Clean up. */ 
free(procargs); 
return pathStr; 

ERROR_B: 
free(procargs); 
ERROR_A: 
printf("(%d)", pid); 

} 
0

Así que la respuesta de magicd y el comentario de Victor con el enlace al archivo de encabezado me ayudaron a resolver esto.

Quería agregar que tiene que agregar MobileInstallation.framework a "Frameworks vinculados y bibliotecas" en Xcode. He encontrado que el marco aquí:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/PrivateFrameworks

puedo confirmar que las esto funciona en un dispositivo sin jailbreak. La tienda de aplicaciones no es una preocupación para mí.

Aquí está el código que utilicé:

NSDictionary *options = [NSDictionary dictionaryWithObject:@"Any" forKey:@"ApplicationType"]; 
NSDictionary *apps = (__bridge NSDictionary *) MobileInstallationLookup((__bridge CFDictionaryRef) options); 
Cuestiones relacionadas