|
Nimbus
0.9.3 - Nimbus is proudly hosted on Github
An iOS framework whose growth is bounded by O(documentation).
|
00001 // 00002 // Copyright 2011 Jeff Verkoeyen 00003 // 00004 // Licensed under the Apache License, Version 2.0 (the "License"); 00005 // you may not use this file except in compliance with the License. 00006 // You may obtain a copy of the License at 00007 // 00008 // http://www.apache.org/licenses/LICENSE-2.0 00009 // 00010 // Unless required by applicable law or agreed to in writing, software 00011 // distributed under the License is distributed on an "AS IS" BASIS, 00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 // See the License for the specific language governing permissions and 00014 // limitations under the License. 00015 // 00016 00017 #import "NIDeviceInfo.h" 00018 00019 #import "NimbusCore.h" 00020 00021 #import <mach/mach.h> 00022 #import <mach/mach_host.h> 00023 00024 // Static local state. 00025 static BOOL sIsCaching = NO; 00026 static BOOL sLastUpdateResult = NO; 00027 static vm_size_t sPageSize = 0; 00028 static vm_statistics_data_t sVMStats; 00029 static NSDictionary* sFileSystem = nil; 00030 00031 00033 NSString* NIStringFromBytes(unsigned long long bytes) { 00034 static const void* sOrdersOfMagnitude[] = { 00035 @"bytes", @"KB", @"MB", @"GB" 00036 }; 00037 00038 // Determine what magnitude the number of bytes is by shifting off 10 bits at a time 00039 // (equivalent to dividing by 1024). 00040 NSInteger magnitude = 0; 00041 unsigned long long highbits = bytes; 00042 unsigned long long inverseBits = ~((unsigned long long)0x3FF); 00043 while ((highbits & inverseBits) 00044 && magnitude + 1 < (sizeof(sOrdersOfMagnitude) / sizeof(void *))) { 00045 // Shift off an order of magnitude. 00046 highbits >>= 10; 00047 magnitude++; 00048 } 00049 00050 if (magnitude > 0) { 00051 unsigned long long dividend = 1024 << (magnitude - 1) * 10; 00052 double result = ((double)bytes / (double)(dividend)); 00053 return [NSString stringWithFormat:@"%.2f %@", 00054 result, 00055 sOrdersOfMagnitude[magnitude]]; 00056 00057 } else { 00058 // We don't need to bother with dividing bytes. 00059 return [NSString stringWithFormat:@"%lld %@", bytes, sOrdersOfMagnitude[magnitude]]; 00060 } 00061 } 00062 00063 00067 @implementation NIDeviceInfo 00068 00069 00071 + (void)initialize { 00072 [[UIDevice currentDevice] setBatteryMonitoringEnabled:YES]; 00073 memset(&sVMStats, 0, sizeof(sVMStats)); 00074 } 00075 00076 00078 + (BOOL)updateHostStatistics { 00079 mach_port_t host_port = mach_host_self(); 00080 mach_msg_type_number_t host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); 00081 host_page_size(host_port, &sPageSize); 00082 return (host_statistics(host_port, HOST_VM_INFO, (host_info_t)&sVMStats, &host_size) 00083 == KERN_SUCCESS); 00084 } 00085 00086 00088 + (BOOL)updateFileSystemAttributes { 00089 NI_RELEASE_SAFELY(sFileSystem); 00090 00091 NSError* error = nil; 00092 // This path could be any path that is on the device's local disk. 00093 NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 00094 00095 // Fetch the file system information based on the path given (the user's documents directory). 00096 sFileSystem = 00097 [[[NSFileManager defaultManager] attributesOfFileSystemForPath: [paths lastObject] 00098 error: &error] retain]; 00099 return (nil == error); 00100 } 00101 00102 00105 #pragma mark - 00106 #pragma mark Public Methods 00107 00108 00110 + (unsigned long long)bytesOfFreeMemory { 00111 if (!sIsCaching && ![self updateHostStatistics]) { 00112 return 0; 00113 } 00114 unsigned long long mem_free = ((unsigned long long)sVMStats.free_count 00115 * (unsigned long long)sPageSize); 00116 return mem_free; 00117 } 00118 00119 00121 + (unsigned long long)bytesOfTotalMemory { 00122 if (!sIsCaching && ![self updateHostStatistics]) { 00123 return 0; 00124 } 00125 unsigned long long mem_free = (((unsigned long long)sVMStats.free_count 00126 + (unsigned long long)sVMStats.active_count 00127 + (unsigned long long)sVMStats.inactive_count 00128 + (unsigned long long)sVMStats.wire_count) 00129 * (unsigned long long)sPageSize); 00130 return mem_free; 00131 } 00132 00133 00135 + (unsigned long long)bytesOfFreeDiskSpace { 00136 if (!sIsCaching && ![self updateFileSystemAttributes]) { 00137 return 0; 00138 } 00139 unsigned long long bytes = 0; 00140 00141 NSNumber* number = [sFileSystem objectForKey:NSFileSystemFreeSize]; 00142 bytes = [number unsignedLongLongValue]; 00143 00144 return bytes; 00145 } 00146 00147 00149 + (unsigned long long)bytesOfTotalDiskSpace { 00150 if (!sIsCaching && ![self updateFileSystemAttributes]) { 00151 return 0; 00152 } 00153 unsigned long long bytes = 0; 00154 00155 NSNumber* number = [sFileSystem objectForKey:NSFileSystemSize]; 00156 bytes = [number unsignedLongLongValue]; 00157 00158 return bytes; 00159 } 00160 00161 00163 + (CGFloat)batteryLevel { 00164 return [[UIDevice currentDevice] batteryLevel]; 00165 } 00166 00167 00169 + (UIDeviceBatteryState)batteryState { 00170 return [[UIDevice currentDevice] batteryState]; 00171 } 00172 00173 00176 #pragma mark - 00177 #pragma mark Caching 00178 00179 00181 + (BOOL)beginCachedDeviceInfo { 00182 if (!sIsCaching) { 00183 sIsCaching = YES; 00184 00185 sLastUpdateResult = [self updateHostStatistics]; 00186 sLastUpdateResult = ([self updateFileSystemAttributes] && sLastUpdateResult); 00187 } 00188 00189 return sLastUpdateResult; 00190 } 00191 00192 00194 + (void)endCachedDeviceInfo { 00195 sIsCaching = NO; 00196 } 00197 00198 00199 @end