Is there a way to programmatically detect iOS version's build number,
For example iOS version 9.0.2(13A452).
I know how to detect iOS version eg: 9.0.2.
Is there any API to detect 13A452?
Thanks in advance.
Figured I'd put the code up incase anyone needs it (works at run time), since it's slightly tricky to process!
MAKE SURE YOU #include <sys/sysctl.h>
//make sure you `#include <sys/sysctl.h>`
NSString *ctlKey = #"kern.osversion";
BOOL buildValueFound;
NSString *buildValue;
size_t size = 0;
if (sysctlbyname([ctlKey UTF8String], NULL, &size, NULL, 0) == -1) {
buildValueFound = NO;
} else {
char *machine = calloc( 1, size );
sysctlbyname([ctlKey UTF8String], machine, &size, NULL, 0);
NSString *ctlValue = [NSString stringWithCString:machine encoding:[NSString defaultCStringEncoding]];
free(machine);
buildValue = ctlValue;
buildValueFound = YES;
}
if (buildValueFound) {
NSLog(#"%#", buildValue);
} else {
NSLog(#"No build value found");
}
I have figured this out. Using KERN_OSVERSION on function sysctl returns iOS build number.
In my app, I have about 300 NSData objects 0.5 MB in size, and I'm writing them all sequentially into a file with essentially this code (which writes a single 0.5 MB object 300 times):
- (void)createFile {
// create .5 MB block to write
int size = 500000;
Byte *bytes = malloc(size);
for (int i = 0; i < size; i++) {
bytes[i] = 42;
}
NSData *data = [NSData dataWithBytesNoCopy:bytes length:size
freeWhenDone:YES];
// temp output file
NSUUID *uuid = [NSUUID UUID];
NSString *path = [[NSTemporaryDirectory()
stringByAppendingPathComponent:[uuid UUIDString]]
stringByAppendingPathExtension:#"dat"];
NSOutputStream *outputStream = [[NSOutputStream alloc]
initToFileAtPath:path append:NO];
[outputStream open];
double startTime = CACurrentMediaTime();
NSInteger totalBytesWritten;
NSInteger bytesWritten;
Byte *readPtr;
for (int i = 0; i < 300; i++) {
// reset read pointer to block we're writing to the output
readPtr = (Byte *)[data bytes];
totalBytesWritten = 0;
// write the block
while (totalBytesWritten < size) {
bytesWritten = [outputStream write:readPtr maxLength:size
- totalBytesWritten];
readPtr += bytesWritten;
totalBytesWritten += bytesWritten;
}
}
double duration = CACurrentMediaTime() - startTime;
NSLog(#"duration = %f", duration);
[outputStream close];
}
On both my iPod (5th gen) and my iPhone 6, this process takes about 3 seconds, and I was wondering if there was any faster way to do this. I've tried using NSFileManager and NSFileHandle approaches, but they take about the same length of time, which leads me to suppose that this is a fundamental I/O limit I'm running into.
Is there any way to do this faster (this code should compile and run on any device)?
Here's the highest performance I was able to achieve, using mmap & memcpy.
It takes on average about 0.2 seconds to run on my iPhone 6, with some variation up to around 0.5s. YMMV, however, as it would appear that the iPhone 6 has two different flash storage providers - one is TLC and the other is MLC - those with TLC will get significantly better results.
This of course assumes that you are OK with async I/O. If you truly need something synchronous, look for other solutions.
- (IBAction)createFile {
NSData *data = [[self class] dataToCopy];
// temp output file
NSUUID *uuid = [NSUUID UUID];
NSString *path = [[NSTemporaryDirectory()
stringByAppendingPathComponent:[uuid UUIDString]]
stringByAppendingPathExtension:#"dat"];
NSUInteger size = [data length];
NSUInteger count = 300;
NSUInteger file_size = size * count;
int fd = open([path UTF8String], O_CREAT | O_RDWR, 0666);
ftruncate(fd, file_size);
void *addr = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
double startTime = CACurrentMediaTime();
static dispatch_queue_t concurrentDataQueue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
concurrentDataQueue = dispatch_queue_create("test.concurrent", DISPATCH_QUEUE_CONCURRENT);
});
for (int i = 0; i < count; i++) {
dispatch_async(concurrentDataQueue, ^{
memcpy(addr + (i * size), [data bytes], size);
});
}
dispatch_barrier_async(concurrentDataQueue, ^{
fsync(fd);
double duration = CACurrentMediaTime() - startTime;
NSLog(#"duration = %f", duration);
munmap(addr, file_size);
close(fd);
unlink([path UTF8String]);
});
}
Two performance tips that I can recommend are: try turning off file-system caching or checking the IO buffer size.
"When reading data that you are certain you won’t need again soon, such as streaming a large multimedia file, tell the file system not to add that data to the file-system caches.
Apps can call the BSD fcntl function with the F_NOCACHE flag to enable or disable caching for a file. For more information about this function, see fcntl."~Performance Tips
or "read much or all of the data into memory before processing it" ~Performance Tips
iPhone 6 uses 16Gb SK hynix flash storage~[Teardown] and the theoretical limit for sequential write is around 40 to 70 Mb/s~[NAND flash].
300 * 0.5 / 3 = 50MB/s for 150MB of data looks fast enough. I suppose you hit the flash storage WRITE speed limit. I believe you run this code in a background thread, so the issue is not in blocking of UI
i want to create an app that show all app installed on the device and info about network usage of that app. Is there api for get infor about network usage?
Your own app can find out how much data the device as a how as used by using the code below, but there's no way of knowing how much each particular app has used. Apps like My Data Manager used to give you a breakdown per app but a) that wasn't totally accurate and b) it now longer does this now with iOS 7. There's another app that sends the data through VPN to its server and in the screenshots on the app store makes it look like it can give a breakdown per app, but that's spin but in reality it just can't except for a few and with some interaction from the user. Basically there is no guaranteed accurate way of doing it per every app.
Also there is no guaranteed accurate way of knowing all installed apps. There are some mechanisms to do a good guess of what is installed based against a database but no way of knowing definitely what is installed
#include <arpa/inet.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <net/if_dl.h>
- (void) getDataUsage
{
NSTimeInterval elapsedTime = [[NSDate date] timeIntervalSinceDate: self.timeThatDataMonitoringStarted];
NSLog(#"********* GETTING DATA USAGE. Elapsed time: %f **************",elapsedTime);
NSArray *data = [self getDataCounters];
NSNumber *wifiSentSinceBoot = (NSNumber*)data[0];
NSNumber *wifiReceivedSinceBoot = (NSNumber*)data[1];
NSNumber *wwanSentSinceBoot = (NSNumber*)data[2];
NSNumber *wwanReceivedSinceBoot = (NSNumber*)data[3];
int wifiSentSinceBootAsInt = [wifiSentSinceBoot intValue];
int wifiReceivedSinceBootAsInt = [wifiReceivedSinceBoot intValue];
int wWanSentSinceBootAsInt = [wwanSentSinceBoot intValue];
int wWanReceivedSinceBootAsInt = [wwanReceivedSinceBoot intValue];
static int initialWifiSent;
static int initialWifiReceived;
static int initialWWanSent;
static int initialWWanReceived;
if (!self.initialDataValuesSet)
{
self.initialDataValuesSet = YES;
initialWifiSent = wifiSentSinceBootAsInt;
initialWifiReceived = wifiReceivedSinceBootAsInt;
initialWWanSent = wWanSentSinceBootAsInt;
initialWWanReceived = wWanReceivedSinceBootAsInt;
}
int wifiSentSinceLastRetrieval = wifiSentSinceBootAsInt - initialWifiSent;
int wifiReceivedSinceLastRetrieval = wifiReceivedSinceBootAsInt - initialWifiReceived;
int wWanSentSinceLastRetrieval = wWanSentSinceBootAsInt - initialWWanSent;
int wWanReceivedSinceLastRetrieval = wWanReceivedSinceBootAsInt - initialWWanReceived;
uint dataUsed = wifiSentSinceLastRetrieval + wifiReceivedSinceLastRetrieval + wWanSentSinceLastRetrieval + wWanReceivedSinceLastRetrieval;
NSLog(#"Total data: %d", dataUsed);
}
- (NSArray *) getDataCounters
{
BOOL success;
struct ifaddrs *addrs;
const struct ifaddrs *cursor;
const struct if_data *networkStatisc;
int WiFiSent = 0;
int WiFiReceived = 0;
int WWANSent = 0;
int WWANReceived = 0;
NSString *name=[[NSString alloc]init];
success = getifaddrs(&addrs) == 0;
if (success)
{
cursor = addrs;
while (cursor != NULL)
{
name=[NSString stringWithFormat:#"%s",cursor->ifa_name];
// NSLog(#"ifa_name %s == %#\n", cursor->ifa_name,name);
// names of interfaces: en0 is WiFi ,pdp_ip0 is WWAN
if (cursor->ifa_addr->sa_family == AF_LINK)
{
if ([name hasPrefix:#"en"])
{
networkStatisc = (const struct if_data *) cursor->ifa_data;
WiFiSent+=networkStatisc->ifi_obytes;
WiFiReceived+=networkStatisc->ifi_ibytes;
// NSLog(#"WiFiSent %d ==%d",WiFiSent,networkStatisc->ifi_obytes);
// NSLog(#"WiFiReceived %d ==%d",WiFiReceived,networkStatisc->ifi_ibytes);
}
if ([name hasPrefix:#"pdp_ip"])
{
networkStatisc = (const struct if_data *) cursor->ifa_data;
WWANSent+=networkStatisc->ifi_obytes;
WWANReceived+=networkStatisc->ifi_ibytes;
// NSLog(#"WWANSent %d ==%d",WWANSent,networkStatisc->ifi_obytes);
// NSLog(#"WWANReceived %d ==%d",WWANReceived,networkStatisc->ifi_ibytes);
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return [NSArray arrayWithObjects:[NSNumber numberWithInt:WiFiSent], [NSNumber numberWithInt:WiFiReceived],[NSNumber numberWithInt:WWANSent],[NSNumber numberWithInt:WWANReceived], nil];
}
There is an app called "Activity Monitor Touch" in the App Store, which displays background processes as well as free memory.
So there MUST be an public API to access this information. The evidence:
I'm already searching for days but can't find any good starting point. How can this app figure all this stuff out without any jailbreaking / hacking / etc.?
Until recently I was sure that something like this is absolutely impossible on iOS.
I've found this code snippet:
- (NSArray *)runningProcesses {
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t miblen = 4;
size_t size;
int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;
do {
size += size / 10;
newprocess = realloc(process, size);
if (!newprocess){
if (process){
free(process);
}
return nil;
}
process = newprocess;
st = sysctl(mib, miblen, process, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
if (st == 0){
if (size % sizeof(struct kinfo_proc) == 0){
int nprocess = size / sizeof(struct kinfo_proc);
if (nprocess){
NSMutableArray * array = [[NSMutableArray alloc] init];
for (int i = nprocess - 1; i >= 0; i--){
NSString * processID = [[NSString alloc] initWithFormat:#"%d", process[i].kp_proc.p_pid];
NSString * processName = [[NSString alloc] initWithFormat:#"%s", process[i].kp_proc.p_comm];
NSDictionary * dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName, nil]
forKeys:[NSArray arrayWithObjects:#"ProcessID", #"ProcessName", nil]];
[processID release];
[processName release];
[array addObject:dict];
[dict release];
}
free(process);
return [array autorelease];
}
}
}
return nil;
}
But I can't make it run on the iPhone. Xcode doesn't know these symbols:
CTL_KERN, KERN_PROC, KERN_PROC_ALL
So of course I must import a header file or library. Does anyone know where these belong to, and how the headers must be imported to make this work?
Works like a charm:
#import <sys/sysctl.h>
sysctl is no longer accessible to sandboxed iOS 9 apps.
From WWDC 2015 session 703 Privacy and Your App:
In iOS 9, the sandbox now prevents a process from accessing the
kern.proc, kern.procargs, and kern.procargs2 values for other
processes
and
iOS apps are not permitted to see what other apps are running
So even if you find a way, you are likely to get rejected from the App Store.
https://developer.apple.com/videos/play/wwdc2015-703/
Using the method described in this question, I can get a list of apps running on an iOS device.
I know PIDs and have access to their kinfo_proc structures.
How can I determine which are foreground processes and which are background (assuming my app is background)?
I tried to find this out base on information in kinfo_proc (see 1st link), via kp_proc.p_priority, but it looks like it is not possible to infer background/foreground state from priority.
I don't really care if this works correctly for AppStore Review but I would prefer a method that will work without a jailbreak(i.e. Private APIs are ok but which ones?). I want this to work at least on iOS 5
I considered writing a simple MobileSubstrate extension, injecting it into all apps and just hook everyone's applicationDidBecomeActive, but this requires a jailbreak and is too invasive.
Well, looks like some usage of nm and IDA on SpringBoardServices binary from simulator helped me on this.
Following code works on iOS 5.0.1 running on iPod Touch 4, iPhone 4 and iPad1 WiFi(all non-JB)
Of course you should never try to submit that to AppStore
- (NSArray*) getActiveApps
{
mach_port_t *p;
void *uikit = dlopen(UIKITPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() =
dlsym(uikit, "SBSSpringBoardServerPort");
p = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(uikit);
void *sbserv = dlopen(SBSERVPATH, RTLD_LAZY);
NSArray* (*SBSCopyApplicationDisplayIdentifiers)(mach_port_t* port, BOOL runningApps,BOOL debuggable) =
dlsym(sbserv, "SBSCopyApplicationDisplayIdentifiers");
//SBDisplayIdentifierForPID - protype assumed,verification of params done
void* (*SBDisplayIdentifierForPID)(mach_port_t* port, int pid,char * result) =
dlsym(sbserv, "SBDisplayIdentifierForPID");
//SBFrontmostApplicationDisplayIdentifier - prototype assumed,verification of params done,don't call this TOO often(every second on iPod touch 4G is 'too often,every 5 seconds is not)
void* (*SBFrontmostApplicationDisplayIdentifier)(mach_port_t* port,char * result) =
dlsym(sbserv, "SBFrontmostApplicationDisplayIdentifier");
//Get frontmost application
char frontmostAppS[256];
memset(frontmostAppS,sizeof(frontmostAppS),0);
SBFrontmostApplicationDisplayIdentifier(p,frontmostAppS);
NSString * frontmostApp=[NSString stringWithFormat:#"%s",frontmostAppS];
//NSLog(#"Frontmost app is %#",frontmostApp);
//get list of running apps from SpringBoard
NSArray *allApplications = SBSCopyApplicationDisplayIdentifiers(p,NO, NO);
//Really returns ACTIVE applications(from multitasking bar)
/* NSLog(#"Active applications:");
for(NSString *identifier in allApplications) {
// NSString * locName=SBSCopyLocalizedApplicationNameForDisplayIdentifier(p,identifier);
NSLog(#"Active Application:%#",identifier);
}
*/
//get list of all apps from kernel
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t miblen = 4;
size_t size;
int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;
do {
size += size / 10;
newprocess = realloc(process, size);
if (!newprocess){
if (process){
free(process);
}
return nil;
}
process = newprocess;
st = sysctl(mib, miblen, process, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
if (st == 0){
if (size % sizeof(struct kinfo_proc) == 0){
int nprocess = size / sizeof(struct kinfo_proc);
if (nprocess){
NSMutableArray * array = [[NSMutableArray alloc] init];
for (int i = nprocess - 1; i >= 0; i--){
int ruid=process[i].kp_eproc.e_pcred.p_ruid;
int uid=process[i].kp_eproc.e_ucred.cr_uid;
//short int nice=process[i].kp_proc.p_nice;
//short int u_prio=process[i].kp_proc.p_usrpri;
short int prio=process[i].kp_proc.p_priority;
NSString * processID = [[NSString alloc] initWithFormat:#"%d", process[i].kp_proc.p_pid];
NSString * processName = [[NSString alloc] initWithFormat:#"%s", process[i].kp_proc.p_comm];
BOOL systemProcess=YES;
if (ruid==501)
systemProcess=NO;
char * appid[256];
memset(appid,sizeof(appid),0);
int intID,intID2;
intID=process[i].kp_proc.p_pid,appid;
SBDisplayIdentifierForPID(p,intID,appid);/
NSString * appId=[NSString stringWithFormat:#"%s",appid];
if (systemProcess==NO)
{
if ([appId isEqualToString:#""])
{
//final check.if no appid this is not springboard app
NSLog(#"(potentially system)Found process with PID:%# name %#,isSystem:%d,Priority:%d",processID,processName,systemProcess,prio);
}
else
{
BOOL isFrontmost=NO;
if ([frontmostApp isEqualToString:appId])
{
isFrontmost=YES;
}
NSNumber *isFrontmostN=[NSNumber numberWithBool:isFrontmost];
NSDictionary * dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName,appId,isFrontmostN, nil]
forKeys:[NSArray arrayWithObjects:#"ProcessID", #"ProcessName",#"AppID",#"isFrontmost", nil]];
NSLog(#"PID:%#, name: %#, AppID:%#,isFrontmost:%d",processID,processName,appId,isFrontmost);
[array addObject:dict];
}
}
}
free(process);
return array;
}
}
}
dlclose(sbserv);
}
Of course 2nd loop is not strictly necessary but I needed non-localized names & PIDs too.
Great answer! But there is a small typo in your code, it should be:
First make sure that SBSERVPATH is defined and the correct header files are included:
#import <sys/sysctl.h>
#import <dlfcn.h>
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
Then first find the correct SB port:
mach_port_t *port;
void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() =
dlsym(lib, "SBSSpringBoardServerPort");
port = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(lib);
And then find the active app:
mach_port_t * port = [self getSpringBoardPort];
// open springboard lib
void *lib = dlopen(SBSERVPATH, RTLD_LAZY);
// retrieve function SBFrontmostApplicationDisplayIdentifier
void *(*SBFrontmostApplicationDisplayIdentifier)(mach_port_t *port, char *result) =
dlsym(lib, "SBFrontmostApplicationDisplayIdentifier");
// reserve memory for name
char appId[256];
memset(appId, 0, sizeof(appId));
// retrieve front app name
SBFrontmostApplicationDisplayIdentifier(port, appId);
// close dynlib
dlclose(lib);
This is what works for me on all IOS devices:
#define UIKITPATH "/System/Library/Framework/UIKit.framework/UIKit"
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
- (NSArray*) getActiveApps
{
mach_port_t *p;
void *uikit = dlopen(UIKITPATH, RTLD_LAZY);
int (*SBSSpringBoardServerPort)() =
dlsym(uikit, "SBSSpringBoardServerPort");
p = (mach_port_t *)SBSSpringBoardServerPort();
dlclose(uikit);
if(self.frameWorkPath == nil || self.frameWorkPath.length == 0)
{
self.frameWorkPath = #SBSERVPATH;
self.frameWorkPath = [self.frameWorkPath stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
}
const char *cString = [self.frameWorkPath cStringUsingEncoding:NSUTF8StringEncoding];
//const char *bar = [self.frameWorkPath UTF8String];
void *sbserv = dlopen(cString, RTLD_LAZY);
NSArray* (*SBSCopyApplicationDisplayIdentifiers)(mach_port_t* port, BOOL runningApps,BOOL debuggable) =
dlsym(sbserv, "SBSCopyApplicationDisplayIdentifiers");
//SBDisplayIdentifierForPID - protype assumed,verification of params done
void* (*SBDisplayIdentifierForPID)(mach_port_t* port, int pid,char * result) =
dlsym(sbserv, "SBDisplayIdentifierForPID");
//SBFrontmostApplicationDisplayIdentifier - prototype assumed,verification of params done,don't call this TOO often(every second on iPod touch 4G is 'too often,every 5 seconds is not)
void* (*SBFrontmostApplicationDisplayIdentifier)(mach_port_t* port,char * result) =
dlsym(sbserv, "SBFrontmostApplicationDisplayIdentifier");
//Get frontmost application
char frontmostAppS[512];
memset(frontmostAppS,sizeof(frontmostAppS),0);
SBFrontmostApplicationDisplayIdentifier(p,frontmostAppS);
NSString * frontmostApp=[NSString stringWithFormat:#"%s",frontmostAppS];
if([self iOsMajorVersion] >= 7){
NSNumber *topmost = [NSNumber numberWithBool:YES];
NSMutableDictionary * dict = [[NSMutableDictionary alloc] init];
NSMutableArray * splitted = [frontmostApp componentsSeparatedByString:#"."];
if(frontmostApp.length > 0 && splitted != nil && splitted.count > 1 && topmost.boolValue == YES){
NSString *appname = [splitted lastObject];
[dict setObject:[appname capitalizedString] forKey:#"ProcessName"];
[dict setObject:frontmostApp forKey:#"ProcessID"];
[dict setObject:frontmostApp forKey:#"AppID"];
[dict setObject:topmost forKey:#"isFrontmost"];
NSLog(#"Running TOPMOST App %#",dict);
return #[dict];
}
else{
return nil;
}
}
//NSLog(#"Frontmost app is %#",frontmostApp);
//get list of running apps from SpringBoard
NSArray *allApplications = SBSCopyApplicationDisplayIdentifiers(p,NO, NO);
//Really returns ACTIVE applications(from multitasking bar)
NSLog(#"Active applications:");
for(NSString *identifier in allApplications) {
// NSString * locName=SBSCopyLocalizedApplicationNameForDisplayIdentifier(p,identifier);
NSLog(#"Active Application:%#",identifier);
}
//get list of all apps from kernel
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t miblen = 4;
size_t size;
int st = sysctl(mib, miblen, NULL, &size, NULL, 0);
struct kinfo_proc * process = NULL;
struct kinfo_proc * newprocess = NULL;
do {
size += size / 10;
newprocess = realloc(process, size);
if (!newprocess){
if (process){
free(process);
}
return nil;
}
process = newprocess;
st = sysctl(mib, miblen, process, &size, NULL, 0);
} while (st == -1 && errno == ENOMEM);
if (st == 0){
if (size % sizeof(struct kinfo_proc) == 0){
int nprocess = size / sizeof(struct kinfo_proc);
if (nprocess){
NSMutableArray * array = [[NSMutableArray alloc] init];
for (int i = nprocess - 1; i >= 0; i--){
int ruid=process[i].kp_eproc.e_pcred.p_ruid;
int uid=process[i].kp_eproc.e_ucred.cr_uid;
//short int nice=process[i].kp_proc.p_nice;
//short int u_prio=process[i].kp_proc.p_usrpri;
short int prio=process[i].kp_proc.p_priority;
NSString * processID = [[NSString alloc] initWithFormat:#"%d", process[i].kp_proc.p_pid];
NSString * processName = [[NSString alloc] initWithFormat:#"%s", process[i].kp_proc.p_comm];
BOOL systemProcess=YES;
if (ruid==501){
systemProcess=NO;
}
char * appid[256];
memset(appid,sizeof(appid),0);
int intID,intID2;
intID=process[i].kp_proc.p_pid,appid;
SBDisplayIdentifierForPID(p,intID,appid);
NSString * appId=[NSString stringWithFormat:#"%s",appid];
if (systemProcess==NO)
{
if ([appId isEqualToString:#""])
{
//final check.if no appid this is not springboard app
//NSLog(#"(potentially system)Found process with PID:%# name %#,isSystem:%d,Priority:%d",processID,processName,systemProcess,prio);
}
else
{
BOOL isFrontmost=NO;
if ([frontmostApp isEqualToString:appId])
{
isFrontmost=YES;
}
NSNumber *isFrontmostN=[NSNumber numberWithBool:isFrontmost];
NSDictionary * dict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:processID, processName,appId,isFrontmostN, nil]
forKeys:[NSArray arrayWithObjects:#"ProcessID", #"ProcessName",#"AppID",#"isFrontmost", nil]];
NSLog(#"PID:%#, name: %#, AppID:%#,isFrontmost:%d",processID,processName,appId,isFrontmost);
[array addObject:dict];
}
}
}
free(process);
return array;
}
}
}
dlclose(sbserv);
}