iOS12 어플리케이션 설치 여부 판단

2989 단어
일반적으로 응용 프로그램의 설치 여부를 판단하는 것은 URL schemes를 통해 판단하지만 이런 방식에는 두 가지 뚜렷한 문제가 있다
  • iOS9이상은 백명단 설정이 필요합니다. info.plist에 추가
  • 도 중요한 점이다. 우리는 다른 앱에 같은 URL schemes를 설정하는 방식으로 사기를 칠 수 있다.예를 들어 다른 앱에 위챗의 URL인 schemes weixin://를 부착하면 위챗 앱이 설치되지 않은 상태에서도 시스템에 위챗이 설치되어 있다고 판단할 수 있다.

  • 일반적으로 URL schemes를 통해 판단하는 것은 큰 문제가 없지만, 일부 안전 수준이 높은 경우 정확한 판정을 위해서는 개인 API 방법이 필요하다.
    인터넷에는 개인 API 방법으로 설치 여부를 판단하는 방식을 소개하는 글이 많다.iOS10 이전에 LSApplicationWorkspac을 통해 설치 응용 프로그램 목록을 받는 방식으로 모든 응용 프로그램의 bundleID를 받습니다
    Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
    
    NSObject* workspace = [LSApplicationWorkspace_class performSelector:@selector(defaultWorkspace)];
    NSArray *allApplications = [workspace performSelector:@selector(allApplications)];
    for (NSString *appStr in allApplications) {
          NSString *app = [NSString stringWithFormat:@"%@",appStr];
            NSRange range = [app rangeOfString:@"    App bundle ID"];
             if (range.length > 1) {
                NSLog(@"   ");
            }
    }
    

    iOS11에 이르러 이러한 방식은 이미 효력을 상실하였으며, 개인 MCMAPpContainer의 방식을 통해 bundID가 설치되었는지 아닌지를 판단하였다.
    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]; 
      if (test) { 
        return YES; 
      }else{ 
        return NO; 
      } 
    } 
    return NO;
    

    안타깝게도 iOS12에 이르러 이런 방식도 권한 문제로 금지되었다.그럼 다른 방법으로 판단할 수 있는 방법이 있나요?
    연구를 통해 LSApplicationWorkspace 클래스의 all Applications 방법은 iOS10 이후 더 이상 사용할 수 없게 되었다.하지만 한 가지 방법installedPlugins을 사용할 수 있다.이 방법은 현재 시스템에 설치된 모든 extension 플러그인을 되돌려줍니다. 구체적인 코드는 다음과 같습니다.
    Class lsawsc = objc_getClass("LSApplicationWorkspace");   
    NSObject* workspace = [lsawsc performSelector:NSSelectorFromString(@"defaultWorkspace")];
    NSArray *plugins = [workspace performSelector:NSSelectorFromString(@"installedPlugins")]; //    plugins
    [plugins enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString *pluginID = [obj performSelector:(@selector(pluginIdentifier))];
        NSLog(@"%@",pluginID);
    }];
    

    예를 들어 위챗: iOS12의 경우 세 개의 플러그인com을 되돌릴 수 있습니다.tencent.xin.siriext com.tencent.xin.siriextensionui com.tencent.xin.sharetimeline 이름에 따라 공유 플러그인 하나,siri 플러그인 두 개.
    이렇게 하면 응용 프로그램의 설치 여부를 판단할 수 있지만, 아직 두 가지 작은 문제가 존재한다
  • 일부 오래된 버전의 응용 프로그램에 플러그인이 있는지, 예를 들어 시스템에 설치된 위챗 버전이 너무 낡았는지, 이 세 개의 플러그인이 있는지 여부.사실 이 문제는 다행히 현재 iOS12의 시스템에서만 이런 방식으로 판단하고 있는데 원래의 시스템 버전은 예전의 방식으로 판단하면 시스템 버전이 업데이트되고 앱이 업데이트되지 않는 사람은 없을 것이다.
  • 더 중요한 문제는 역시 사유 API의 문제이다. 물론 원래 버전의 판단 방법도 사유 API로 방법명이 혼동되는 등 방식으로 처리되었다.

  • 현재 iOS12 새 버전 판단 앱 설치는 이런 옆에서 두드리는 방법만 찾았을 뿐 더 좋은 방법이 있다면 알려주세요.

    좋은 웹페이지 즐겨찾기