1

Many people use the Launcher app. enter image description here

I'm curious about how Laucher be able to get the list of installed apps of my iPhone?


I have found some way to do similar thing, but all of them are not perfect.

1.use canOpenUrl:, this api requires a lot of url-schemes of apps.

2.search the plist file /private/var/mobile/Library/Caches/com.apple.mobile.installation.plist, which is not available in non-jailbreak iPhone. Also this plist file is not exist anymore in ios9.

3.search /Applications, which is not available in non-jailbreak iPhone.


Question is that, how can Launcher be able to search my iPhone and get the list of installed apps?

Ankit Srivastava
  • 12,347
  • 11
  • 63
  • 115
pinchwang
  • 353
  • 1
  • 2
  • 13

2 Answers2

5

So I downloaded Launcher into iTunes and had a look at its info.plist. It turns out that it does what you first suggested, queries canOpenURL: a lot of times to work out what you have installed.

Here is the contents of LSApplicationQuerySchemes from version 1.3.6:

https://gist.github.com/liamnichols/53069b01da032498bd04

All 4561 of them

liamnichols
  • 12,419
  • 2
  • 43
  • 62
  • developer.apple.com/videos/play/wwdc2015-703 says that LSApplicationQuerySchemes has a maximum number of 50, so how can the 4561 schemes work? – pinchwang Jan 08 '16 at 03:40
  • I believe the 50 limit is if you still compile against the iOS 8 SDKs but run your app on iOS 9 (and not putting any schemes in the info.plist). I haven't watched the video though so I don't know exactly what they have said. This is what the Launcher app does though so if it works, it must be fine ¯\_(ツ)_/¯ – liamnichols Jan 08 '16 at 07:05
  • @liamnichols so i suppose LSApplicationQuerySchemes has no limit, as you say. Then another question occurs, i think LSApplicationQuerySchemes is meaning to restrict app use `openUrl:` api to open any other app they would like to. If i can add as much LSApplicationQuerySchemes as i wish, what is the significance of it? – pinchwang Jan 08 '16 at 09:38
  • @pinchwang It forces you to declare what applications you want to know about up front. This stops ad providers (who use webviews etc) from being able to "hijack" the device and open an app/ the app store without the developers permission up front. – liamnichols Jan 08 '16 at 10:47
0

Recently I found out the solution using predefined Apple classes LSApplicationWorkspace_class and LSApplicationProxy we can achieve this.

Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");

NSObject* workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];

for (LSApplicationProxy *apps in [workspace performSelector:@selector(allApplications)])
{ 
    NSString *localizedName = apps.localizedName;

    if([apps.applicationType isEqualToString:@"User"])
    {
        NSLog(@"\nlocalizedName: %@",localizedName);
        NSLog(@"minimumSystemVersion: %@",apps.minimumSystemVersion);
        NSLog(@"fileSharingEnabled: %d",apps.fileSharingEnabled);
        NSLog(@"sdkVersion: %@",apps.sdkVersion);
    }
}