Does LSApplicationWorkspace not work on iOS 11?

2020-05-19 02:02发布

问题:

I have an app in private which need to scan all applications and schemes and get it by using private API LSApplicationWorkspace defaultWorkspace with others functional method, such as privateURLSchemes allInstalledApplications. This app works good and I can get all I need from the private API before iOS 11, but in this version I only got some warning and an empty array. It seems Apple limits private API that developer can't use in private in iOS 11.

So my question is what alternative ways can achieve my need in iOS 11?

回答1:

UPDATE: This method does not work on iOS 12 - entitlement required

There is a way to find if a specific application is installed, its not a list of all apps like allInstalledApplications returned but its useful to query for a specific bundle id

Here is an example, the method receives bundle id and return true if it's installed on the device:

- (BOOL)checkIfAppInstalled: (NSString*)bundleID {
    dlopen("/System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager",RTLD_NOW);
    Class MBAppManager = NSClassFromString(@"MCMAppDataContainer");
    NSError  * error ;
    id contentApp = [MBAppManager performSelector:@selector(containerWithIdentifier:error:) withObject:bundleID withObject:error];
    return contentApp != nil;
}


回答2:

Private API is just that—private API. Using it is completely unsupported, and as such, you cannot rely on a private API continuing to work in future versions of the OS.

In addition, I would be highly surprised if an app that used private API were able to get into the App Store, since it's one of the things Apple's reviewers scan for.



回答3:

In enterprise you can use Apple Mobile Device Management (MDM) Protocol ManagedApplicationList commands to get the status of managed applications



回答4:

From this post. From the comment of @ovo under the original question, it seems works.

Using MobileContainerManager.framework it's possible to check if an app is installed by using bundle id.

//If the device is iOS11
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 11.0) {
        NSBundle *container = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
        if ([container load]) {
            Class appContainer = NSClassFromString(@"MCMAppContainer");

            id test = [appContainer performSelector:@selector(containerWithIdentifier:error:) withObject:bundleId withObject:nil];
            NSLog(@"%@",test);
            if (test) {
                return YES;
            } else {
                return NO;
            }
        }
        return NO;

    } else {
           //Usual way
    }


回答5:

i got same Apple Reject.

Apple Says

Your app uses or references the following non-public APIs:

LSApplicationWorkspace

The use of non-public APIs is not permitted on the App Store because it can lead to a poor user experience should these APIs change.

Continuing to use or conceal non-public APIs in future submissions of this app may result in the termination of your Apple Developer account, as well as removal of all associated apps from the App Store.

Solutions

To find out which library or code is causing this problem use the below code snipped.

1-) Open the terminal in macbook (cmd+ space) and than write terminal

2-) change the project directory with the below code

cd  /Users/emreg/Documents/{your project url}

3-) To search appropriate word

grep -r LSApplicationWorkspace .
grep -r allApplications .

in my case, Blesh SDK has included LSApplicationWorkspace and allApplications keyword which is not permitted by Apple. When i upteded SDK, my problem is solved.

i hope, this answer will help someone.