iOS 檢測(cè)手機(jī)中是否安裝某個(gè)應(yīng)用

應(yīng)用場(chǎng)景:

產(chǎn)品要求在APP中檢測(cè)手機(jī)是否安裝其他數(shù)個(gè)APP,并提供了APP對(duì)應(yīng)的bundleID;

網(wǎng)上看了一些,大多分為兩種形式:通過(guò)URLScheme判斷是否可以打開(kāi);通過(guò)bundleID直接打開(kāi)APP。第一種方法需要在對(duì)應(yīng)APP的info.plist文件中找scheme,而且有些info.plist文件是找不到scheme的。所以我直接選擇了后者。

由于我們的APP不用考慮上架問(wèn)題,所以就開(kāi)干吧~

通過(guò)bundleID直接打開(kāi)APP:

+ (BOOL) OpenAppWithBundle:(NSString *)bundleID{
Class LSApplicationWorkspace_class = NSClassFromString([@"LSApplicati" stringByAppendingString:@"onWorkspace"]);
SEL defaultWspc = NSSelectorFromString([@"defaultW" stringByAppendingString:@"orkspace"]);
SEL opensdasadkl = NSSelectorFromString([@"openApplicatio" stringByAppendingString:@"nWithBundleID:"]);
NSObject * workspace = [LSApplicationWorkspace_class performSelector:defaultWspc];
BOOL isopen = [workspace performSelector:opensdasadkl withObject:bundleID];
 return isopen;
}

這個(gè)方法有一個(gè)弊端,就是如果手機(jī)里面裝有對(duì)應(yīng)的APP,會(huì)直接跳轉(zhuǎn)并打開(kāi)APP。并不滿足我的需求。我的不需要跳轉(zhuǎn),只需要把是否存在的狀態(tài)通過(guò)接口告訴后臺(tái)即可。so又找了另外一種方式,通過(guò)get手機(jī)安裝的所有APP,遍歷查找:

  NSBundle *container = [NSBundle bundleWithPath:@"/System/Library/PrivateFrameworks/MobileContainerManager.framework"];
    if ([container load]) {
    Class appContainer = NSClassFromString(@"MCMAppContainer");
    #pragma clang diagnostic push
   #pragma clang diagnostic ignored "-Wundeclared-selector"
           id container = [appContainer performSelector:@selector(containerWithIdentifier:error:) withObject:bundleID withObject:nil];
  #pragma clang diagnostic pop
       NSLog(@"====== ::: %@", [container performSelector:@selector(identifier)]);
        if (container) {
            return YES;
          } else {
              return NO;
           }
       }
      return NO;

但是這個(gè)方法我試了,目前是獲取不到任何APP。所以還是不推薦。最后找到了與第二種方法類(lèi)似的另外一種形式解決了

通過(guò)plugin的形式,直接上代碼:

+ (BOOL) verifyAppWithBundle:(NSString *)bundleID{
  __block BOOL isInstall = NO;
    
    if ([[UIDevice currentDevice].systemVersion floatValue] >= 11.0) {

                 //iOS12間接獲取辦法

           if ([[UIDevice currentDevice].systemVersion floatValue] >= 12.0){

               

                    Class lsawsc = objc_getClass("LSApplicationWorkspace");

    

                    NSObject* workspace = [lsawsc performSelector:NSSelectorFromString(@"defaultWorkspace")];

    

                    NSArray *plugins = [workspace performSelector:NSSelectorFromString(@"installedPlugins")]; //列出所有plugins
               
                    DLOG(@"installedPlugins:%@",plugins);
           
                    [plugins enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                    NSString *pluginID = [obj performSelector:(@selector(pluginIdentifier))];
                        NSLog(@"pluginID:%@",pluginID);
                        if([pluginID containsString:bundleID]){
                            isInstall = YES;
                            return;
                        }
               }];

               return isInstall;

           }else{
                   //iOS11獲取辦法
                   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;
                            }

                    }else{
                        return NO;
                    }

               }

       }else{

       //iOS10及以下獲取辦法
           Class lsawsc = objc_getClass("LSApplicationWorkspace");

           NSObject* workspace = [lsawsc performSelector:NSSelectorFromString(@"defaultWorkspace")];

           NSArray *appList = [workspace performSelector:@selector(allApplications)];

           Class LSApplicationProxy_class = object_getClass(@"LSApplicationProxy");

           for (LSApplicationProxy_class in appList)

           {
              //這里可以查看一些信息

               NSString *bundleID = [LSApplicationProxy_class performSelector:@selector(applicationIdentifier)];

               NSString *version =  [LSApplicationProxy_class performSelector:@selector(bundleVersion)];

               NSString *shortVersionString =  [LSApplicationProxy_class performSelector:@selector(shortVersionString)];

               if ([bundleID isEqualToString:bundleID]) {
                   return  YES;
               }
           }
           return NO;

       }
    return NO;

}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容