iOS开发如何获取同一AppGroup下所有关联应用的bundleID列表
核心结论
苹果没有提供公开API可以直接查询指定App Group ID关联的所有应用Bundle ID,原查询关联Bundle ID的实现思路无法实现,可使用以下替代方案满足卸载判定需求。
替代实现方案(无需额外配置info.plist)
方案逻辑:
- 所有接入通用库、使用同一App Group的App,每次启动/进入前台时,自动向App Group共享的UserDefaults中写入自身Bundle ID对应的最新活跃时间戳
- 需判定应用是否卸载时,读取共享UserDefaults中存储的所有Bundle ID活跃记录,时间戳超过设定阈值的即可判定为已卸载(应用被卸载后无法再更新时间戳)
Swift 实现代码
// 上报当前App最新活跃状态,建议在App启动/进入前台时调用 func updateAppActiveStatus(appGroupID: String) { guard let sharedDefaults = UserDefaults(suiteName: appGroupID), let currentBundleID = Bundle.main.bundleIdentifier else { return } sharedDefaults.set(Date().timeIntervalSince1970, forKey: "active_\(currentBundleID)") sharedDefaults.synchronize() } // 获取所有存活的关联App Bundle ID列表,阈值默认7天可自定义 func getActiveAssociatedBundleIDs(appGroupID: String, expireThreshold: TimeInterval = 7*24*3600) -> [String] { guard let sharedDefaults = UserDefaults(suiteName: appGroupID) else { return [] } let allKeys = sharedDefaults.dictionaryRepresentation().keys var activeBundleIDs = [String]() let currentTimestamp = Date().timeIntervalSince1970 for key in allKeys { guard key.hasPrefix("active_"), let activeTimestamp = sharedDefaults.object(forKey: key) as? Double, currentTimestamp - activeTimestamp <= expireThreshold else { continue } activeBundleIDs.append(String(key.dropFirst(7))) } return activeBundleIDs }
Objective-C 实现代码
// 上报当前App最新活跃状态,建议在App启动/进入前台时调用 - (void)updateAppActiveStatusWithAppGroupID:(NSString *)appGroupID { NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:appGroupID]; NSString *currentBundleID = [NSBundle mainBundle].bundleIdentifier; if (!sharedDefaults || !currentBundleID) return; [sharedDefaults setDouble:[NSDate.date timeIntervalSince1970] forKey:[NSString stringWithFormat:@"active_%@", currentBundleID]]; [sharedDefaults synchronize]; } // 获取所有存活的关联App Bundle ID列表,阈值默认7天可自定义 - (NSArray<NSString *> *)getActiveAssociatedBundleIDsWithAppGroupID:(NSString *)appGroupID expireThreshold:(NSTimeInterval)expireThreshold { if (expireThreshold <= 0) { expireThreshold = 7 * 24 * 3600; } NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:appGroupID]; if (!sharedDefaults) return @[]; NSMutableArray *activeBundleIDs = [NSMutableArray array]; NSTimeInterval currentTimestamp = [NSDate.date timeIntervalSince1970]; for (NSString *key in sharedDefaults.dictionaryRepresentation.allKeys) { if (![key hasPrefix:@"active_"]) continue; NSTimeInterval activeTimestamp = [sharedDefaults doubleForKey:key]; if (currentTimestamp - activeTimestamp <= expireThreshold) { [activeBundleIDs addObject:[key substringFromIndex:7]]; } } return activeBundleIDs.copy; }
方案说明
- 全程不需要在info.plist中新增任何配置,仅依赖已配置的App Group权限即可运行
- 可根据业务需求调整阈值,需要更高精度的卸载判定可将阈值设置为1天,同时在App每次进入前台时都调用上报活跃状态的接口
- 应用被卸载后重装会重新写入对应活跃记录,不会出现误判
内容的提问来源于stack exchange,提问作者taikichi
相关产品推荐
相关产品推荐

