判断App是否安装
一、需求判断游戏是否已经安装
iOS新版本的系统上苹果已经不允许通过scheme判断app是否安装,可以通过以下手段判断一个app是否安装
二、下面的方法调用的私有api,如果需要提交appstore使用的话,需要对selector进行混淆
使用过程中需要注意线程安全问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // // LAApplicationHelper.h // App // // Created by qqvipfunction on 2017/4/1. // Copyright © 2017年 SZ. All rights reserved. // #import <Foundation/Foundation.h> @interface LAApplicationHelper : NSObject + (instancetype)shareInstance; - ( void )refreshInstalledList; - ( BOOL )isAppInstalled:( NSString *)appBundleID; - ( NSArray < NSString *> *)appList; @end |
实现文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | // // LAApplicationHelper.m // App // // Created by qqvipfunction on 2017/4/1. // Copyright © 2017年 SZ. All rights reserved. // #import "LAApplicationHelper.h" #import <objc/runtime.h> @interface LAApplicationHelper () @property ( nonatomic , strong) NSMutableArray * appList; @property ( nonatomic , strong) NSMutableArray * appNameList; @end @implementation LAApplicationHelper + (instancetype)shareInstance { static dispatch_once_t onceToken; static LAApplicationHelper *instance = nil ; dispatch_once(&onceToken, ^{ instance = [[LAApplicationHelper alloc] init]; }); return instance; } - (instancetype)init { if ( self = [ super init]) { _appList = [[ NSMutableArray alloc] init]; _appNameList = [[ NSMutableArray alloc] init]; [ self loadInstalledApps]; } return self ; } - ( void )refreshInstalledList { [ self loadInstalledApps]; } - ( void )loadInstalledApps { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wundeclared-selector" [_appList removeAllObjects]; [_appNameList removeAllObjects]; Class LSApplicationWorkspace_class = objc_getClass( "LSApplicationWorkspace" ); NSObject * workspace = [LSApplicationWorkspace_class performSelector: @selector (defaultWorkspace)]; NSArray *arr = [workspace performSelector: @selector (allApplications)]; if ([arr count] > 0) { for ( NSObject * obj in arr) { [_appList addObject:obj]; NSArray *itemArr = [[obj description] componentsSeparatedByString:@ " " ]; if ([itemArr count] > 2) { NSString *appName = itemArr[2]; if ([appName length] > 0) { [_appNameList addObject:appName]; } } } } #pragma clang diagnostic pop } - ( BOOL )isAppInstalled:( NSString *)appBundleID { for ( NSString *bundleID in self .appNameList) { if ([appBundleID isEqual:bundleID]) return YES ; } return NO ; } - ( NSArray < NSString *> *)appList { return [ self .appNameList copy ]; } @end |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
2015-04-01 Talking Ben App砸壳记
2015-04-01 IOS 中会发生crash的操作
2015-04-01 Objetive-C 中的相等比较