]> git.cameronkatri.com Git - tweaks.git/blob - QuickActions/QuickActionsPrefs/LSApplicationProxy+AltList.m
Fix iOS 15+
[tweaks.git] / QuickActions / QuickActionsPrefs / LSApplicationProxy+AltList.m
1 #import <Foundation/Foundation.h>
2 #import "LSApplicationProxy+AltList.h"
3
4 @implementation LSApplicationProxy (AltList)
5 // the tag " hidden " is also valid, so we need to check if any strings contain "hidden" instead
6 BOOL tagArrayContainsTag(NSArray* tagArr, NSString* tag)
7 {
8 if(!tagArr || !tag) return NO;
9
10 __block BOOL found = NO;
11
12 [tagArr enumerateObjectsUsingBlock:^(NSString* tagToCheck, NSUInteger idx, BOOL* stop)
13 {
14 if(![tagToCheck isKindOfClass:[NSString class]])
15 {
16 return;
17 }
18
19 if([tagToCheck rangeOfString:tag options:0].location != NSNotFound)
20 {
21 found = YES;
22 *stop = YES;
23 }
24 }];
25
26 return found;
27 }
28
29 // always returns NO on iOS 7
30 - (BOOL)atl_isHidden
31 {
32 NSArray* appTags;
33 NSArray* recordAppTags;
34 NSArray* sbAppTags;
35
36 BOOL launchProhibited = NO;
37
38 if([self respondsToSelector:@selector(correspondingApplicationRecord)])
39 {
40 // On iOS 14, self.appTags is always empty but the application record still has the correct ones
41 LSApplicationRecord* record = [self correspondingApplicationRecord];
42 recordAppTags = record.appTags;
43 launchProhibited = record.launchProhibited;
44 }
45 if([self respondsToSelector:@selector(appTags)])
46 {
47 appTags = self.appTags;
48 }
49 if(!launchProhibited && [self respondsToSelector:@selector(isLaunchProhibited)])
50 {
51 launchProhibited = self.launchProhibited;
52 }
53
54 NSURL* bundleURL = self.bundleURL;
55 if(bundleURL && [bundleURL checkResourceIsReachableAndReturnError:nil])
56 {
57 NSBundle* bundle = [NSBundle bundleWithURL:bundleURL];
58 sbAppTags = [bundle objectForInfoDictionaryKey:@"SBAppTags"];
59 }
60
61 BOOL isWebApplication = ([self.bundleIdentifier rangeOfString:@"com.apple.webapp" options:NSCaseInsensitiveSearch].location != NSNotFound);
62 return tagArrayContainsTag(appTags, @"hidden") || tagArrayContainsTag(recordAppTags, @"hidden") || tagArrayContainsTag(sbAppTags, @"hidden") || isWebApplication || launchProhibited;
63 }
64
65 // Getting the display name is slow (up to 2ms) because it uses an IPC call
66 // this stacks up if you do it for every single application
67 // This method provides a faster way (around 0.5ms) to get the display name
68 // This reduces the overall time needed to sort the applications from ~230 to ~120ms on my test device
69 - (NSString*)atl_fastDisplayName
70 {
71 NSString* cachedDisplayName = [self valueForKey:@"_localizedName"];
72 if(cachedDisplayName && ![cachedDisplayName isEqualToString:@""])
73 {
74 return cachedDisplayName;
75 }
76
77 NSString* localizedName;
78
79 NSURL* bundleURL = self.bundleURL;
80 if(!bundleURL || ![bundleURL checkResourceIsReachableAndReturnError:nil])
81 {
82 localizedName = self.localizedName;
83 }
84 else
85 {
86 NSBundle* bundle = [NSBundle bundleWithURL:bundleURL];
87
88 localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleDisplayName"];
89 if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
90 if(!localizedName || [localizedName isEqualToString:@""])
91 {
92 localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleName"];
93 if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
94 if(!localizedName || [localizedName isEqualToString:@""])
95 {
96 localizedName = [bundle objectForInfoDictionaryKey:@"CFBundleExecutable"];
97 if(![localizedName isKindOfClass:[NSString class]]) localizedName = nil;
98 if(!localizedName || [localizedName isEqualToString:@""])
99 {
100 //last possible fallback: use slow IPC call
101 localizedName = self.localizedName;
102 }
103 }
104 }
105 }
106
107 [self setValue:localizedName forKey:@"_localizedName"];
108 return localizedName;
109 }
110
111 - (NSString*)atl_nameToDisplay
112 {
113 NSString* localizedName = [self atl_fastDisplayName];
114
115 if([self.bundleIdentifier rangeOfString:@"carplay" options:NSCaseInsensitiveSearch].location != NSNotFound)
116 {
117 if([localizedName rangeOfString:@"carplay" options:NSCaseInsensitiveSearch range:NSMakeRange(0, localizedName.length) locale:[NSLocale currentLocale]].location == NSNotFound)
118 {
119 return [localizedName stringByAppendingString:@" (CarPlay)"];
120 }
121 }
122
123 return localizedName;
124 }
125 @end