iOS Device System Utilities: Network, Memory, and Battery Information

This article demonstrates an implementation of core system utility functions for iOS devices, providing capabilities to retrieve device information, network addresses, memory statistics, and battery status.

System Information Header

//
//  DeviceSystem.h
//  PhoneManager
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

#import <mach/mach.h>
#include <ifaddrs.h>
#include <sys/socket.h>
#include <net/if.h>

typedef enum {
    kFirmwareVersion_iPhone4_3_3,
    kFirmwareVersion_iPhone4_3_2,
    kFirmwareVersion_iPhone4_3_1,
    kFirmwareVersion_iPhone4_3,
    kFirmwareVersion_iPhone4_2_1,
    kFirmwareVersion_iPhone4_1,
    kFirmwareVersion_iPhone4_0_2,
    kFirmwareVersion_iPhone4_0_1,
    kFirmwareVersion_iPhone4_0,
    kFirmwareVersion_iPhone3_1_3,
    kFirmwareVersion_iPhone3_1_2,
    kFirmwareVersion_iPhone3_1,
    kFirmwareVersion_iPhone3_0_1,
    kFirmwareVersion_iPhone3_0,
    kFirmwareVersion_iPhone2_2_1,
    kFirmwareVersion_iPhone2_2,
    kFirmwareVersion_iPhone2_1,
    kFirmwareVersion_iPhone2_0_2,
    kFirmwareVersion_iPhone2_0_1,
    kFirmwareVersion_iPhone2_0,
    kFirmwareVersion_iPhone1_1_4,
    kFirmwareVersion_iPhone1_1_3,
    kFirmwareVersion_iPhone1_1_2,
    kFirmwareVersion_iPhone1_1_1,
    kFirmwareVersion_iPhone1_0_2,
    kFirmwareVersion_iPhone1_0_1,
    kFirmwareVersion_iPhone1_0
} FirmwareVersion;

@interface UIDevice (Extended)
- (NSString *)retrieveSystemVersion;
@end

NSString * fetchApplicationVersion(void);
NSString * fetchWiFiIPAddress(void);
NSString * fetchCellularIPAddress(void);
NSString * fetchDeviceHostname(void);
BOOL collectMemoryStatistics(vm_statistics_data_t *);
NSDate * retrieveSystemBootTime(void);
float retrieveBatteryPercentage(void);
uint32_t calculateWiFiTrafficBytes(void);
uint32_t calculateCellularTrafficBytes(void);
NSString * formatBytesToHumanReadable(uint32_t);
CGFloat * convertStringArrayToFloatArray(NSArray *);

System Information Implementation

//
//  DeviceSystem.m
//  PhoneManager
//

#import "DeviceSystem.h"
#import "ifaddrs.h"
#import "arpa/inet.h"
#import <SystemConfiguration/SCSchemaDefinitions.h>
#import <sys/sysctl.h>

static NSDictionary * firmwareMapping(void) {
    static NSDictionary *mapping = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mapping = @{
            @"4.3.3": @"8J2",
            @"4.3.2": @"8H7",
            @"4.3.1": @"8G4",
            @"4.3": @"8F190",
            @"4.2.1": @"8C148",
            @"4.1": @"8B117",
            @"4.0.2": @"8A400",
            @"4.0.1": @"8A306",
            @"4.0": @"8A293",
            @"3.1.3": @"7E18",
            @"3.1.2": @"7D11",
            @"3.1": @"7C144",
            @"3.0.1": @"7A400",
            @"3.0": @"7A341",
            @"2.2.1": @"5H11",
            @"2.2": @"5G77",
            @"2.1": @"5F136",
            @"2.0.2": @"5C1",
            @"2.0.1": @"5B108",
            @"2.0": @"5A347",
            @"1.1.4": @"4A102",
            @"1.1.3": @"4A93",
            @"1.1.2": @"3B48b",
            @"1.1.1": @"3A109a",
            @"1.0.2": @"1C28",
            @"1.0.1": @"1C25",
            @"1.0": @"1A543a"
        };
    });
    return mapping;
}

@implementation UIDevice (Extended)
- (NSString *)retrieveSystemVersion {
    NSString *systemVersion = [[UIDevice currentDevice] systemVersion];
    NSDictionary *firmwareMap = firmwareMapping();
    NSString *firmwareIdentifier = firmwareMap[systemVersion];
    
    if (firmwareIdentifier) {
        return [NSString stringWithFormat:@"%@(%@)", systemVersion, firmwareIdentifier];
    }
    return systemVersion;
}
@end

NSString * fetchApplicationVersion(void) {
    return [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
}

NSString * fetchWiFiIPAddress(void) {
    struct ifaddrs *networkInterfaces = NULL;
    
    if (getifaddrs(&networkInterfaces) == 0) {
        const struct ifaddrs *interface = networkInterfaces;
        
        while (interface != NULL) {
            if (interface->ifa_addr->sa_family == AF_INET) {
                NSString *interfaceName = [NSString stringWithUTF8String:interface->ifa_name];
                
                if ([interfaceName isEqualToString:@"en0"]) {
                    const struct sockaddr_in *address = (struct sockaddr_in *)interface->ifa_addr;
                    NSString *ipAddress = [NSString stringWithUTF8String:inet_ntoa(address->sin_addr)];
                    freeifaddrs(networkInterfaces);
                    return ipAddress;
                }
            }
            interface = interface->ifa_next;
        }
        freeifaddrs(networkInterfaces);
    }
    return @"N/A";
}

NSString * fetchCellularIPAddress(void) {
    struct ifaddrs *networkInterfaces = NULL;
    
    if (getifaddrs(&networkInterfaces) == 0) {
        const struct ifaddrs *interface = networkInterfaces;
        
        while (interface != NULL) {
            if (interface->ifa_addr->sa_family == AF_INET) {
                NSString *interfaceName = [NSString stringWithUTF8String:interface->ifa_name];
                
                if ([interfaceName isEqualToString:@"pdp_ip0"]) {
                    const struct sockaddr_in *address = (struct sockaddr_in *)interface->ifa_addr;
                    NSString *ipAddress = [NSString stringWithUTF8String:inet_ntoa(address->sin_addr)];
                    freeifaddrs(networkInterfaces);
                    return ipAddress;
                }
            }
            interface = interface->ifa_next;
        }
        freeifaddrs(networkInterfaces);
    }
    return @"N/A";
}

NSString * fetchDeviceHostname(void) {
    char hostnameBuffer[256];
    int result = gethostname(hostnameBuffer, sizeof(hostnameBuffer));
    
    if (result != 0) {
        return nil;
    }
    hostnameBuffer[255] = '\0';
    
#if TARGET_IPHONE_SIMULATOR
    return [NSString stringWithUTF8String:hostnameBuffer];
#else
    return [NSString stringWithFormat:@"%s.local", hostnameBuffer];
#endif
}

BOOL collectMemoryStatistics(vm_statistics_data_t *vmStats) {
    mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
    kern_return_t status = host_statistics(mach_host_self(), 
                                            HOST_VM_INFO, 
                                            (host_info_t)vmStats, 
                                            &infoCount);
    return status == KERN_SUCCESS;
}

void displayMemoryStatistics(void) {
    vm_statistics_data_t memoryStats;
    
    if (collectMemoryStatistics(&memoryStats)) {
        uint32_t pageSize = vm_page_size;
        NSLog(@"Memory Info - Free: %u, Active: %u, Inactive: %u, Wired: %u",
              memoryStats.free_count * pageSize,
              memoryStats.active_count * pageSize,
              memoryStats.inactive_count * pageSize,
              memoryStats.wire_count * pageSize);
    }
}

uint32_t aggregateInterfaceTrafficBytes(const char *targetInterface) {
    struct ifaddrs *interfaceList = NULL;
    
    if (getifaddrs(&interfaceList) == -1) {
        return 0;
    }
    
    uint32_t totalBytes = 0;
    const struct ifaddrs *currentInterface = interfaceList;
    
    while (currentInterface != NULL) {
        if (currentInterface->ifa_addr->sa_family == AF_LINK) {
            if ((currentInterface->ifa_flags & IFF_UP) && 
                (currentInterface->ifa_flags & IFF_RUNNING) &&
                currentInterface->ifa_data != NULL) {
                
                if (strncmp(currentInterface->ifa_name, targetInterface, strlen(targetInterface)) == 0) {
                    const struct if_data *networkData = (struct if_data *)currentInterface->ifa_data;
                    totalBytes += networkData->ifi_ibytes + networkData->ifi_obytes;
                }
            }
        }
        currentInterface = currentInterface->ifa_next;
    }
    
    freeifaddrs(interfaceList);
    return totalBytes;
}

uint32_t calculateWiFiTrafficBytes(void) {
    return aggregateInterfaceTrafficBytes("en0");
}

uint32_t calculateCellularTrafficBytes(void) {
    return aggregateInterfaceTrafficBytes("pdp_ip0");
}

NSDate * retrieveSystemBootTime(void) {
    struct timeval bootTime;
    size_t timeSize = sizeof(bootTime);
    
    int mibParameter[2] = {CTL_KERN, KERN_BOOTTIME};
    sysctl(mibParameter, 2, &bootTime, &timeSize, NULL, 0);
    
    return [NSDate dateWithTimeIntervalSince1970:bootTime.tv_sec];
}

float retrieveBatteryPercentage(void) {
    UIDevice *device = [UIDevice currentDevice];
    [device setBatteryMonitoringEnabled:YES];
    return [device batteryLevel];
}

NSString * formatBytesToHumanReadable(uint32_t bytes) {
    if (bytes < 1024) {
        return [NSString stringWithFormat:@"%d B", bytes];
    } else if (bytes < 1024 * 1024) {
        return [NSString stringWithFormat:@"%.1f KB", (double)bytes / 1024.0];
    } else if (bytes < 1024 * 1024 * 1024) {
        return [NSString stringWithFormat:@"%.2f MB", (double)bytes / (1024.0 * 1024.0)];
    } else {
        return [NSString stringWithFormat:@"%.3f GB", (double)bytes / (1024.0 * 1024.0 * 1024.0)];
    }
}

CGFloat * convertStringArrayToFloatArray(NSArray *stringArray) {
    NSUInteger count = [stringArray count];
    CGFloat *floatArray = (CGFloat *)calloc(count, sizeof(CGFloat));
    
    for (NSUInteger index = 0; index < count; index++) {
        floatArray[index] = [[stringArray objectAtIndex:index] floatValue];
    }
    
    return floatArray;
}

The implementation provides several key functionalities for iOS device monitoring. The firmware version mapping uses a dictionary-based approach for cleaner lookup and maintenance. Network interface detection leverages the getifaddrs function to enumerate available network interfaces and extract IP addresses for WiFi (en0) and cellular (pdp_ip0) connections.

Memory statistics collection uses the Mach kernel API to retrieve virtual memory information including free, active, inactive, and wired pages. The traffic monitoring functions aggregate both incoming and outgoing bytes for specified network interfaces, providing network usage monitoring capabiliites.

Battery level retrieval utilizes UIDevice's battery monitoring API, and the byte formatting function converts raw byte counts into human-readable formats (B, KB, MB, GB) for display purposes.

Tags: Objective-C iOS mach-kernel network-programming memory-management

Posted on Sun, 31 May 2026 17:51:49 +0000 by nepeaNMedia