123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240 |
- //
- // UIApplication+YYAdd.m
- // YYKit <https://github.com/ibireme/YYKit>
- //
- // Created by ibireme on 13/4/4.
- // Copyright (c) 2015 ibireme.
- //
- // This source code is licensed under the MIT-style license found in the
- // LICENSE file in the root directory of this source tree.
- //
- #import "UIApplication+YYAdd.h"
- #import "NSArray+YYAdd.h"
- #import "NSObject+YYAdd.h"
- #import "YYKitMacro.h"
- #import "UIDevice+YYAdd.h"
- #import <sys/sysctl.h>
- #import <mach/mach.h>
- #import <objc/runtime.h>
- YYSYNTH_DUMMY_CLASS(UIApplication_YYAdd)
- #define kNetworkIndicatorDelay (1/30.0)
- @interface _YYUIApplicationNetworkIndicatorInfo : NSObject
- @property (nonatomic, assign) NSInteger count;
- @property (nonatomic, strong) NSTimer *timer;
- @end
- @implementation _YYUIApplicationNetworkIndicatorInfo
- @end
- @implementation UIApplication (YYAdd)
- - (NSURL *)documentsURL {
- return [[[NSFileManager defaultManager]
- URLsForDirectory:NSDocumentDirectory
- inDomains:NSUserDomainMask] lastObject];
- }
- - (NSString *)documentsPath {
- return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
- }
- - (NSURL *)cachesURL {
- return [[[NSFileManager defaultManager]
- URLsForDirectory:NSCachesDirectory
- inDomains:NSUserDomainMask] lastObject];
- }
- - (NSString *)cachesPath {
- return [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
- }
- - (NSURL *)libraryURL {
- return [[[NSFileManager defaultManager]
- URLsForDirectory:NSLibraryDirectory
- inDomains:NSUserDomainMask] lastObject];
- }
- - (NSString *)libraryPath {
- return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
- }
- - (BOOL)isPirated {
- if ([[UIDevice currentDevice] isSimulator]) return YES; // Simulator is not from appstore
-
- if (getgid() <= 10) return YES; // process ID shouldn't be root
-
- if ([[[NSBundle mainBundle] infoDictionary] objectForKey:@"SignerIdentity"]) {
- return YES;
- }
-
- if (![self _yy_fileExistInMainBundle:@"_CodeSignature"]) {
- return YES;
- }
-
- if (![self _yy_fileExistInMainBundle:@"SC_Info"]) {
- return YES;
- }
-
- //if someone really want to crack your app, this method is useless..
- //you may change this method's name, encrypt the code and do more check..
- return NO;
- }
- - (BOOL)_yy_fileExistInMainBundle:(NSString *)name {
- NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
- NSString *path = [NSString stringWithFormat:@"%@/%@", bundlePath, name];
- return [[NSFileManager defaultManager] fileExistsAtPath:path];
- }
- - (NSString *)appBundleName {
- return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleName"];
- }
- - (NSString *)appBundleID {
- return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"];
- }
- - (NSString *)appVersion {
- return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
- }
- - (NSString *)appBuildVersion {
- return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
- }
- - (BOOL)isBeingDebugged {
- size_t size = sizeof(struct kinfo_proc);
- struct kinfo_proc info;
- int ret = 0, name[4];
- memset(&info, 0, sizeof(struct kinfo_proc));
-
- name[0] = CTL_KERN;
- name[1] = KERN_PROC;
- name[2] = KERN_PROC_PID; name[3] = getpid();
-
- if (ret == (sysctl(name, 4, &info, &size, NULL, 0))) {
- return ret != 0;
- }
- return (info.kp_proc.p_flag & P_TRACED) ? YES : NO;
- }
- - (int64_t)memoryUsage {
- struct task_basic_info info;
- mach_msg_type_number_t size = sizeof(info);
- kern_return_t kern = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&info, &size);
- if (kern != KERN_SUCCESS) return -1;
- return info.resident_size;
- }
- - (float)cpuUsage {
- kern_return_t kr;
- task_info_data_t tinfo;
- mach_msg_type_number_t task_info_count;
-
- task_info_count = TASK_INFO_MAX;
- kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
- if (kr != KERN_SUCCESS) {
- return -1;
- }
-
- thread_array_t thread_list;
- mach_msg_type_number_t thread_count;
-
- thread_info_data_t thinfo;
- mach_msg_type_number_t thread_info_count;
-
- thread_basic_info_t basic_info_th;
-
- kr = task_threads(mach_task_self(), &thread_list, &thread_count);
- if (kr != KERN_SUCCESS) {
- return -1;
- }
-
- long tot_sec = 0;
- long tot_usec = 0;
- float tot_cpu = 0;
- int j;
-
- for (j = 0; j < thread_count; j++) {
- thread_info_count = THREAD_INFO_MAX;
- kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
- (thread_info_t)thinfo, &thread_info_count);
- if (kr != KERN_SUCCESS) {
- return -1;
- }
-
- basic_info_th = (thread_basic_info_t)thinfo;
-
- if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
- tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
- tot_usec = tot_usec + basic_info_th->system_time.microseconds + basic_info_th->system_time.microseconds;
- tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE;
- }
- }
-
- kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
- assert(kr == KERN_SUCCESS);
-
- return tot_cpu;
- }
- YYSYNTH_DYNAMIC_PROPERTY_OBJECT(networkActivityInfo, setNetworkActivityInfo, RETAIN_NONATOMIC, _YYUIApplicationNetworkIndicatorInfo *);
- - (void)_delaySetActivity:(NSTimer *)timer {
- NSNumber *visiable = timer.userInfo;
- if (self.networkActivityIndicatorVisible != visiable.boolValue) {
- //modify by leo
- [self setNetworkActivityIndicatorVisible:visiable.boolValue];
- }
- [timer invalidate];
- }
- - (void)_changeNetworkActivityCount:(NSInteger)delta {
- @synchronized(self){
- dispatch_async_on_main_queue(^{
- _YYUIApplicationNetworkIndicatorInfo *info = [self networkActivityInfo];
- if (!info) {
- info = [_YYUIApplicationNetworkIndicatorInfo new];
- [self setNetworkActivityInfo:info];
- }
- NSInteger count = info.count;
- count += delta;
- info.count = count;
- [info.timer invalidate];
- info.timer = [NSTimer timerWithTimeInterval:kNetworkIndicatorDelay target:self selector:@selector(_delaySetActivity:) userInfo:@(info.count > 0) repeats:NO];
- [[NSRunLoop mainRunLoop] addTimer:info.timer forMode:NSRunLoopCommonModes];
- });
- }
- }
- - (void)incrementNetworkActivityCount {
- [self _changeNetworkActivityCount:1];
- }
- - (void)decrementNetworkActivityCount {
- [self _changeNetworkActivityCount:-1];
- }
- + (BOOL)isAppExtension {
- static BOOL isAppExtension = NO;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- Class cls = NSClassFromString(@"UIApplication");
- if(!cls || ![cls respondsToSelector:@selector(sharedApplication)]) isAppExtension = YES;
- if ([[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"]) isAppExtension = YES;
- });
- return isAppExtension;
- }
- + (UIApplication *)sharedExtensionApplication {
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wundeclared-selector"
- return [self isAppExtension] ? nil : [UIApplication performSelector:@selector(sharedApplication)];
- #pragma clang diagnostic pop
- }
- @end
|