get list of installed applications on iphone objective-c
Asked Answered
O

6

6

I have an application that needs to get the list of installed (other, maybe third party) applications on the device. How can it be done? Or can it be done at all?

Ounce answered 27/12, 2011 at 13:51 Comment(5)
This is duplicate one, please refer following thread- #4614614Petepetechia
Does exist any third-party libraries to do this trick?Ounce
thanks @rishi. I missed that. Please answer my question with your comment.Ounce
I doubt if something is available, but you can use following link- iphonedevsdk.com/forum/iphone-sdk-development/… and with the help of this you can check what all app are present.Petepetechia
Please, answer my question with your comment (it will be marked as accepted)Ounce
P
3

I doubt if something is available(if some iphone is jailbreaked and user can access file system, then it will be possible, but i am not aware of this.), but you can use following link and with the help of this you can check what all app are present and you can customize with some of your needs.

Petepetechia answered 27/12, 2011 at 15:7 Comment(0)
F
17

You could scan all your apps through apple private framework "MobileInstallationInstall".

The method is like below:

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

it can only be used in JB devices.

Falcate answered 24/10, 2012 at 8:2 Comment(3)
Actually. It could be used on jailed device too. However, you can't get an app with this code to AppStore, because it's private API.Jotham
How can I get the headers for MobileInstallationInstall?Candiecandied
@EwyynTomato: Headers could be found as example here: github.com/Cykey/ios-reversed-headers/blob/master/…Jotham
S
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;
}

this will give you the array of name of installed app using private API

Supremacist answered 27/12, 2011 at 15:5 Comment(1)
Doesn't work under iOS 6 on the device. The file doesn't exist.Posthumous
C
5

there is no public API from apple to fetch such list from iOS device (iPod Touch/iPhone/iPad)

Cotten answered 27/12, 2011 at 13:54 Comment(0)
P
3

I doubt if something is available(if some iphone is jailbreaked and user can access file system, then it will be possible, but i am not aware of this.), but you can use following link and with the help of this you can check what all app are present and you can customize with some of your needs.

Petepetechia answered 27/12, 2011 at 15:7 Comment(0)
D
2

This WONT give List of installed apps but You can get List of applications running in background and their concerned processes by this code.

call from 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);

}
Duplication answered 14/12, 2012 at 7:35 Comment(0)
S
0

So magicd's answer and Victor's comment with the link to the header file helped me solve this.

I did want to add that you have to add the MobileInstallation.framework to the "Linked Frameworks and Libraries" in Xcode. I found that framework here:

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

I can confirm that this does work on a non-jailbroken device. The app store is not a concern for me.

Here's the code I used:

NSDictionary *options = [NSDictionary dictionaryWithObject:@"Any" forKey:@"ApplicationType"];
NSDictionary *apps = (__bridge NSDictionary *) MobileInstallationLookup((__bridge CFDictionaryRef) options);
Summersummerhouse answered 25/4, 2014 at 21:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.