iOS 11下如何通过私有API获取其他应用的版本与构建号?
iOS 11+ 获取其他应用版本号和构建号(私有API方案)
嘿,我刚好研究过iOS 11之后替代LSWorkspace/LSApplicationProxy旧方案的方法,既然你的应用不上架App Store,用私有API完全没问题,给你几个经过验证的可行路子:
方法一:更新版LSApplicationWorkspace + LSApplicationProxy
iOS 11之后,LSApplicationWorkspace的部分方法签名有变化,但核心的应用信息获取逻辑依然可用,只是可能需要额外的权限配置。
代码示例:
#import <CoreServices/CoreServices.h> #import <MobileCoreServices/MobileCoreServices.h> // 获取默认Workspace实例 LSApplicationWorkspace *workspace = [LSApplicationWorkspace defaultWorkspace]; // 获取所有已安装应用(参数0表示所有类型) NSArray<LSApplicationProxy *> *installedApps = [workspace applicationsOfType:0]; // 遍历查找目标应用 for (LSApplicationProxy *appProxy in installedApps) { if ([appProxy.bundleIdentifier isEqualToString:@"你的目标Bundle ID"]) { // 版本号(对应CFBundleShortVersionString) NSString *versionNumber = appProxy.shortVersionString; // 构建号(对应CFBundleVersion) NSString *buildNumber = appProxy.bundleVersion; NSLog(@"目标应用版本:%@,构建号:%@", versionNumber, buildNumber); break; } }
注意事项:
- 需要添加私有 entitlement:
com.apple.lsapplicationworkspace.access,否则在非越狱环境下会被系统拒绝访问。 - 如果是越狱环境,直接调用即可,无需额外配置。
方法二:通过辅助功能框架AXUIElement获取
这个方法依赖Accessibility框架,需要开启辅助功能权限,适合企业级应用或越狱场景。
代码示例:
#import <Accessibility/Accessibility.h> // 根据Bundle ID获取进程ID pid_t targetPID; if (pid_for_bundle_id("你的目标Bundle ID", &targetPID) == 0) { // 创建对应应用的AXUIElement实例 AXUIElementRef appElement = AXUIElementCreateApplication(targetPID); // 获取版本号(公开属性) CFStringRef publicVersion = NULL; AXUIElementCopyAttributeValue(appElement, kAXApplicationVersionAttribute, (CFTypeRef *)&publicVersion); // 获取构建号(私有属性,注意属性名是私有字符串) CFStringRef privateBuild = NULL; AXUIElementCopyAttributeValue(appElement, CFSTR("AXApplicationBuildVersion"), (CFTypeRef *)&privateBuild); // 输出结果 if (publicVersion) { NSLog(@"版本号:%@", (__bridge NSString *)publicVersion); CFRelease(publicVersion); } if (privateBuild) { NSLog(@"构建号:%@", (__bridge NSString *)privateBuild); CFRelease(privateBuild); } CFRelease(appElement); }
注意事项:
- 需要在设备设置中为你的应用开启「辅助功能」权限,否则会返回权限错误。
- 越狱环境下可以通过hook绕过权限检查,无需用户手动开启。
方法三:直接读取目标应用的Info.plist
如果能访问目标应用的沙盒路径,可以直接读取其Info.plist文件获取版本和构建号,但iOS 11之后沙盒隔离更严格,仅适用于越狱环境。
代码示例:
#import <CoreServices/CoreServices.h> LSApplicationWorkspace *workspace = [LSApplicationWorkspace defaultWorkspace]; LSApplicationProxy *targetProxy = [workspace applicationProxyForBundleIdentifier:@"你的目标Bundle ID"]; if (targetProxy) { // 拼接Info.plist路径 NSURL *infoPlistURL = [targetProxy.bundleURL URLByAppendingPathComponent:@"Info.plist"]; NSDictionary *infoDict = [NSDictionary dictionaryWithContentsOfURL:infoPlistURL]; if (infoDict) { NSString *version = infoDict[@"CFBundleShortVersionString"]; NSString *build = infoDict[@"CFBundleVersion"]; NSLog(@"版本:%@,构建号:%@", version, build); } }
注意事项:
- 非越狱环境下,系统会阻止你访问其他应用的沙盒路径,此方法仅在越狱设备上可行。
总结
优先推荐方法一,它的兼容性最好,只要配置好对应的私有entitlement,在iOS 11到最新版本的非越狱环境都能正常工作;如果是越狱场景,三个方法都可以灵活选用。
内容的提问来源于stack exchange,提问作者Jasmin
相关产品推荐
相关产品推荐

