├── DeviceInfo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ ├── Jason.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── zego.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── Jason.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ ├── DeviceInfo.xcscheme │ │ └── xcschememanagement.plist │ └── zego.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── DeviceInfo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m ├── class │ ├── DeviceInfo.h │ └── DeviceInfo.m └── main.m ├── DeviceInfoTests ├── DeviceInfoTests.m └── Info.plist ├── LICENSE └── README.md /DeviceInfo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 962510841F286C9A0031FEE4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 962510831F286C9A0031FEE4 /* main.m */; }; 11 | 962510871F286C9A0031FEE4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 962510861F286C9A0031FEE4 /* AppDelegate.m */; }; 12 | 9625108A1F286C9A0031FEE4 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 962510891F286C9A0031FEE4 /* ViewController.m */; }; 13 | 9625108F1F286C9A0031FEE4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9625108E1F286C9A0031FEE4 /* Assets.xcassets */; }; 14 | 962510921F286C9A0031FEE4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 962510901F286C9A0031FEE4 /* LaunchScreen.storyboard */; }; 15 | 9625109D1F286C9A0031FEE4 /* DeviceInfoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9625109C1F286C9A0031FEE4 /* DeviceInfoTests.m */; }; 16 | 962510FD1F2893DA0031FEE4 /* DeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 962510FC1F2893DA0031FEE4 /* DeviceInfo.m */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXContainerItemProxy section */ 20 | 962510991F286C9A0031FEE4 /* PBXContainerItemProxy */ = { 21 | isa = PBXContainerItemProxy; 22 | containerPortal = 962510771F286C9A0031FEE4 /* Project object */; 23 | proxyType = 1; 24 | remoteGlobalIDString = 9625107E1F286C9A0031FEE4; 25 | remoteInfo = DeviceInfo; 26 | }; 27 | 962510A41F286C9A0031FEE4 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = 962510771F286C9A0031FEE4 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = 9625107E1F286C9A0031FEE4; 32 | remoteInfo = DeviceInfo; 33 | }; 34 | /* End PBXContainerItemProxy section */ 35 | 36 | /* Begin PBXFileReference section */ 37 | 9625107F1F286C9A0031FEE4 /* DeviceInfo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DeviceInfo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 38 | 962510831F286C9A0031FEE4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 39 | 962510851F286C9A0031FEE4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 40 | 962510861F286C9A0031FEE4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 41 | 962510881F286C9A0031FEE4 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 42 | 962510891F286C9A0031FEE4 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 43 | 9625108E1F286C9A0031FEE4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 44 | 962510911F286C9A0031FEE4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 45 | 962510931F286C9A0031FEE4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 46 | 962510981F286C9A0031FEE4 /* DeviceInfoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DeviceInfoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 9625109C1F286C9A0031FEE4 /* DeviceInfoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DeviceInfoTests.m; sourceTree = ""; }; 48 | 9625109E1F286C9A0031FEE4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 962510A31F286C9A0031FEE4 /* DeviceInfoUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DeviceInfoUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | 962510FB1F2893DA0031FEE4 /* DeviceInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DeviceInfo.h; sourceTree = ""; }; 51 | 962510FC1F2893DA0031FEE4 /* DeviceInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DeviceInfo.m; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 9625107C1F286C9A0031FEE4 /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | ); 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | 962510951F286C9A0031FEE4 /* Frameworks */ = { 63 | isa = PBXFrameworksBuildPhase; 64 | buildActionMask = 2147483647; 65 | files = ( 66 | ); 67 | runOnlyForDeploymentPostprocessing = 0; 68 | }; 69 | 962510A01F286C9A0031FEE4 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 962510761F286C9A0031FEE4 = { 80 | isa = PBXGroup; 81 | children = ( 82 | 962510811F286C9A0031FEE4 /* DeviceInfo */, 83 | 9625109B1F286C9A0031FEE4 /* DeviceInfoTests */, 84 | 962510801F286C9A0031FEE4 /* Products */, 85 | ); 86 | sourceTree = ""; 87 | }; 88 | 962510801F286C9A0031FEE4 /* Products */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 9625107F1F286C9A0031FEE4 /* DeviceInfo.app */, 92 | 962510981F286C9A0031FEE4 /* DeviceInfoTests.xctest */, 93 | 962510A31F286C9A0031FEE4 /* DeviceInfoUITests.xctest */, 94 | ); 95 | name = Products; 96 | sourceTree = ""; 97 | }; 98 | 962510811F286C9A0031FEE4 /* DeviceInfo */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 962510851F286C9A0031FEE4 /* AppDelegate.h */, 102 | 962510861F286C9A0031FEE4 /* AppDelegate.m */, 103 | 962510881F286C9A0031FEE4 /* ViewController.h */, 104 | 962510891F286C9A0031FEE4 /* ViewController.m */, 105 | 962510FA1F2893DA0031FEE4 /* class */, 106 | 9625108E1F286C9A0031FEE4 /* Assets.xcassets */, 107 | 962510901F286C9A0031FEE4 /* LaunchScreen.storyboard */, 108 | 962510931F286C9A0031FEE4 /* Info.plist */, 109 | 962510821F286C9A0031FEE4 /* Supporting Files */, 110 | ); 111 | path = DeviceInfo; 112 | sourceTree = ""; 113 | }; 114 | 962510821F286C9A0031FEE4 /* Supporting Files */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 962510831F286C9A0031FEE4 /* main.m */, 118 | ); 119 | name = "Supporting Files"; 120 | sourceTree = ""; 121 | }; 122 | 9625109B1F286C9A0031FEE4 /* DeviceInfoTests */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 9625109C1F286C9A0031FEE4 /* DeviceInfoTests.m */, 126 | 9625109E1F286C9A0031FEE4 /* Info.plist */, 127 | ); 128 | path = DeviceInfoTests; 129 | sourceTree = ""; 130 | }; 131 | 962510FA1F2893DA0031FEE4 /* class */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 962510FB1F2893DA0031FEE4 /* DeviceInfo.h */, 135 | 962510FC1F2893DA0031FEE4 /* DeviceInfo.m */, 136 | ); 137 | path = class; 138 | sourceTree = ""; 139 | }; 140 | /* End PBXGroup section */ 141 | 142 | /* Begin PBXNativeTarget section */ 143 | 9625107E1F286C9A0031FEE4 /* DeviceInfo */ = { 144 | isa = PBXNativeTarget; 145 | buildConfigurationList = 962510AC1F286C9A0031FEE4 /* Build configuration list for PBXNativeTarget "DeviceInfo" */; 146 | buildPhases = ( 147 | 9625107B1F286C9A0031FEE4 /* Sources */, 148 | 9625107C1F286C9A0031FEE4 /* Frameworks */, 149 | 9625107D1F286C9A0031FEE4 /* Resources */, 150 | ); 151 | buildRules = ( 152 | ); 153 | dependencies = ( 154 | ); 155 | name = DeviceInfo; 156 | productName = DeviceInfo; 157 | productReference = 9625107F1F286C9A0031FEE4 /* DeviceInfo.app */; 158 | productType = "com.apple.product-type.application"; 159 | }; 160 | 962510971F286C9A0031FEE4 /* DeviceInfoTests */ = { 161 | isa = PBXNativeTarget; 162 | buildConfigurationList = 962510AF1F286C9A0031FEE4 /* Build configuration list for PBXNativeTarget "DeviceInfoTests" */; 163 | buildPhases = ( 164 | 962510941F286C9A0031FEE4 /* Sources */, 165 | 962510951F286C9A0031FEE4 /* Frameworks */, 166 | 962510961F286C9A0031FEE4 /* Resources */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | 9625109A1F286C9A0031FEE4 /* PBXTargetDependency */, 172 | ); 173 | name = DeviceInfoTests; 174 | productName = DeviceInfoTests; 175 | productReference = 962510981F286C9A0031FEE4 /* DeviceInfoTests.xctest */; 176 | productType = "com.apple.product-type.bundle.unit-test"; 177 | }; 178 | 962510A21F286C9A0031FEE4 /* DeviceInfoUITests */ = { 179 | isa = PBXNativeTarget; 180 | buildConfigurationList = 962510B21F286C9A0031FEE4 /* Build configuration list for PBXNativeTarget "DeviceInfoUITests" */; 181 | buildPhases = ( 182 | 9625109F1F286C9A0031FEE4 /* Sources */, 183 | 962510A01F286C9A0031FEE4 /* Frameworks */, 184 | 962510A11F286C9A0031FEE4 /* Resources */, 185 | ); 186 | buildRules = ( 187 | ); 188 | dependencies = ( 189 | 962510A51F286C9A0031FEE4 /* PBXTargetDependency */, 190 | ); 191 | name = DeviceInfoUITests; 192 | productName = DeviceInfoUITests; 193 | productReference = 962510A31F286C9A0031FEE4 /* DeviceInfoUITests.xctest */; 194 | productType = "com.apple.product-type.bundle.ui-testing"; 195 | }; 196 | /* End PBXNativeTarget section */ 197 | 198 | /* Begin PBXProject section */ 199 | 962510771F286C9A0031FEE4 /* Project object */ = { 200 | isa = PBXProject; 201 | attributes = { 202 | LastUpgradeCheck = 0930; 203 | ORGANIZATIONNAME = "段志巍"; 204 | TargetAttributes = { 205 | 9625107E1F286C9A0031FEE4 = { 206 | CreatedOnToolsVersion = 8.3.3; 207 | DevelopmentTeam = 6795L8TDC8; 208 | ProvisioningStyle = Automatic; 209 | }; 210 | 962510971F286C9A0031FEE4 = { 211 | CreatedOnToolsVersion = 8.3.3; 212 | DevelopmentTeam = 97KXK82D47; 213 | ProvisioningStyle = Automatic; 214 | TestTargetID = 9625107E1F286C9A0031FEE4; 215 | }; 216 | 962510A21F286C9A0031FEE4 = { 217 | CreatedOnToolsVersion = 8.3.3; 218 | DevelopmentTeam = 97KXK82D47; 219 | ProvisioningStyle = Automatic; 220 | TestTargetID = 9625107E1F286C9A0031FEE4; 221 | }; 222 | }; 223 | }; 224 | buildConfigurationList = 9625107A1F286C9A0031FEE4 /* Build configuration list for PBXProject "DeviceInfo" */; 225 | compatibilityVersion = "Xcode 3.2"; 226 | developmentRegion = English; 227 | hasScannedForEncodings = 0; 228 | knownRegions = ( 229 | en, 230 | Base, 231 | ); 232 | mainGroup = 962510761F286C9A0031FEE4; 233 | productRefGroup = 962510801F286C9A0031FEE4 /* Products */; 234 | projectDirPath = ""; 235 | projectRoot = ""; 236 | targets = ( 237 | 9625107E1F286C9A0031FEE4 /* DeviceInfo */, 238 | 962510971F286C9A0031FEE4 /* DeviceInfoTests */, 239 | 962510A21F286C9A0031FEE4 /* DeviceInfoUITests */, 240 | ); 241 | }; 242 | /* End PBXProject section */ 243 | 244 | /* Begin PBXResourcesBuildPhase section */ 245 | 9625107D1F286C9A0031FEE4 /* Resources */ = { 246 | isa = PBXResourcesBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | 962510921F286C9A0031FEE4 /* LaunchScreen.storyboard in Resources */, 250 | 9625108F1F286C9A0031FEE4 /* Assets.xcassets in Resources */, 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | 962510961F286C9A0031FEE4 /* Resources */ = { 255 | isa = PBXResourcesBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | runOnlyForDeploymentPostprocessing = 0; 260 | }; 261 | 962510A11F286C9A0031FEE4 /* Resources */ = { 262 | isa = PBXResourcesBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | ); 266 | runOnlyForDeploymentPostprocessing = 0; 267 | }; 268 | /* End PBXResourcesBuildPhase section */ 269 | 270 | /* Begin PBXSourcesBuildPhase section */ 271 | 9625107B1F286C9A0031FEE4 /* Sources */ = { 272 | isa = PBXSourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 9625108A1F286C9A0031FEE4 /* ViewController.m in Sources */, 276 | 962510871F286C9A0031FEE4 /* AppDelegate.m in Sources */, 277 | 962510FD1F2893DA0031FEE4 /* DeviceInfo.m in Sources */, 278 | 962510841F286C9A0031FEE4 /* main.m in Sources */, 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | 962510941F286C9A0031FEE4 /* Sources */ = { 283 | isa = PBXSourcesBuildPhase; 284 | buildActionMask = 2147483647; 285 | files = ( 286 | 9625109D1F286C9A0031FEE4 /* DeviceInfoTests.m in Sources */, 287 | ); 288 | runOnlyForDeploymentPostprocessing = 0; 289 | }; 290 | 9625109F1F286C9A0031FEE4 /* Sources */ = { 291 | isa = PBXSourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | }; 297 | /* End PBXSourcesBuildPhase section */ 298 | 299 | /* Begin PBXTargetDependency section */ 300 | 9625109A1F286C9A0031FEE4 /* PBXTargetDependency */ = { 301 | isa = PBXTargetDependency; 302 | target = 9625107E1F286C9A0031FEE4 /* DeviceInfo */; 303 | targetProxy = 962510991F286C9A0031FEE4 /* PBXContainerItemProxy */; 304 | }; 305 | 962510A51F286C9A0031FEE4 /* PBXTargetDependency */ = { 306 | isa = PBXTargetDependency; 307 | target = 9625107E1F286C9A0031FEE4 /* DeviceInfo */; 308 | targetProxy = 962510A41F286C9A0031FEE4 /* PBXContainerItemProxy */; 309 | }; 310 | /* End PBXTargetDependency section */ 311 | 312 | /* Begin PBXVariantGroup section */ 313 | 962510901F286C9A0031FEE4 /* LaunchScreen.storyboard */ = { 314 | isa = PBXVariantGroup; 315 | children = ( 316 | 962510911F286C9A0031FEE4 /* Base */, 317 | ); 318 | name = LaunchScreen.storyboard; 319 | sourceTree = ""; 320 | }; 321 | /* End PBXVariantGroup section */ 322 | 323 | /* Begin XCBuildConfiguration section */ 324 | 962510AA1F286C9A0031FEE4 /* Debug */ = { 325 | isa = XCBuildConfiguration; 326 | buildSettings = { 327 | ALWAYS_SEARCH_USER_PATHS = NO; 328 | CLANG_ANALYZER_NONNULL = YES; 329 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 330 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 331 | CLANG_CXX_LIBRARY = "libc++"; 332 | CLANG_ENABLE_MODULES = YES; 333 | CLANG_ENABLE_OBJC_ARC = YES; 334 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 335 | CLANG_WARN_BOOL_CONVERSION = YES; 336 | CLANG_WARN_COMMA = YES; 337 | CLANG_WARN_CONSTANT_CONVERSION = YES; 338 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 339 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 340 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 341 | CLANG_WARN_EMPTY_BODY = YES; 342 | CLANG_WARN_ENUM_CONVERSION = YES; 343 | CLANG_WARN_INFINITE_RECURSION = YES; 344 | CLANG_WARN_INT_CONVERSION = YES; 345 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 346 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 347 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 348 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 349 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 350 | CLANG_WARN_STRICT_PROTOTYPES = YES; 351 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 352 | CLANG_WARN_UNREACHABLE_CODE = YES; 353 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 354 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 355 | COPY_PHASE_STRIP = NO; 356 | DEBUG_INFORMATION_FORMAT = dwarf; 357 | ENABLE_STRICT_OBJC_MSGSEND = YES; 358 | ENABLE_TESTABILITY = YES; 359 | GCC_C_LANGUAGE_STANDARD = gnu99; 360 | GCC_DYNAMIC_NO_PIC = NO; 361 | GCC_NO_COMMON_BLOCKS = YES; 362 | GCC_OPTIMIZATION_LEVEL = 0; 363 | GCC_PREPROCESSOR_DEFINITIONS = ( 364 | "DEBUG=1", 365 | "$(inherited)", 366 | ); 367 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 368 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 369 | GCC_WARN_UNDECLARED_SELECTOR = YES; 370 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 371 | GCC_WARN_UNUSED_FUNCTION = YES; 372 | GCC_WARN_UNUSED_VARIABLE = YES; 373 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 374 | MTL_ENABLE_DEBUG_INFO = YES; 375 | ONLY_ACTIVE_ARCH = YES; 376 | SDKROOT = iphoneos; 377 | TARGETED_DEVICE_FAMILY = "1,2"; 378 | }; 379 | name = Debug; 380 | }; 381 | 962510AB1F286C9A0031FEE4 /* Release */ = { 382 | isa = XCBuildConfiguration; 383 | buildSettings = { 384 | ALWAYS_SEARCH_USER_PATHS = NO; 385 | CLANG_ANALYZER_NONNULL = YES; 386 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 387 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 388 | CLANG_CXX_LIBRARY = "libc++"; 389 | CLANG_ENABLE_MODULES = YES; 390 | CLANG_ENABLE_OBJC_ARC = YES; 391 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 392 | CLANG_WARN_BOOL_CONVERSION = YES; 393 | CLANG_WARN_COMMA = YES; 394 | CLANG_WARN_CONSTANT_CONVERSION = YES; 395 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 396 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 397 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 398 | CLANG_WARN_EMPTY_BODY = YES; 399 | CLANG_WARN_ENUM_CONVERSION = YES; 400 | CLANG_WARN_INFINITE_RECURSION = YES; 401 | CLANG_WARN_INT_CONVERSION = YES; 402 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 403 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 404 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 405 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 406 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 407 | CLANG_WARN_STRICT_PROTOTYPES = YES; 408 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 409 | CLANG_WARN_UNREACHABLE_CODE = YES; 410 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 411 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 412 | COPY_PHASE_STRIP = NO; 413 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 414 | ENABLE_NS_ASSERTIONS = NO; 415 | ENABLE_STRICT_OBJC_MSGSEND = YES; 416 | GCC_C_LANGUAGE_STANDARD = gnu99; 417 | GCC_NO_COMMON_BLOCKS = YES; 418 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 419 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 420 | GCC_WARN_UNDECLARED_SELECTOR = YES; 421 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 422 | GCC_WARN_UNUSED_FUNCTION = YES; 423 | GCC_WARN_UNUSED_VARIABLE = YES; 424 | IPHONEOS_DEPLOYMENT_TARGET = 10.3; 425 | MTL_ENABLE_DEBUG_INFO = NO; 426 | SDKROOT = iphoneos; 427 | TARGETED_DEVICE_FAMILY = "1,2"; 428 | VALIDATE_PRODUCT = YES; 429 | }; 430 | name = Release; 431 | }; 432 | 962510AD1F286C9A0031FEE4 /* Debug */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 436 | DEVELOPMENT_TEAM = 6795L8TDC8; 437 | INFOPLIST_FILE = DeviceInfo/Info.plist; 438 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 439 | PRODUCT_BUNDLE_IDENTIFIER = com.DeviceInfo; 440 | PRODUCT_NAME = "$(TARGET_NAME)"; 441 | }; 442 | name = Debug; 443 | }; 444 | 962510AE1F286C9A0031FEE4 /* Release */ = { 445 | isa = XCBuildConfiguration; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | DEVELOPMENT_TEAM = 6795L8TDC8; 449 | INFOPLIST_FILE = DeviceInfo/Info.plist; 450 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 451 | PRODUCT_BUNDLE_IDENTIFIER = com.DeviceInfo; 452 | PRODUCT_NAME = "$(TARGET_NAME)"; 453 | }; 454 | name = Release; 455 | }; 456 | 962510B01F286C9A0031FEE4 /* Debug */ = { 457 | isa = XCBuildConfiguration; 458 | buildSettings = { 459 | BUNDLE_LOADER = "$(TEST_HOST)"; 460 | DEVELOPMENT_TEAM = 97KXK82D47; 461 | INFOPLIST_FILE = DeviceInfoTests/Info.plist; 462 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 463 | PRODUCT_BUNDLE_IDENTIFIER = dzw.DeviceInfoTests; 464 | PRODUCT_NAME = "$(TARGET_NAME)"; 465 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DeviceInfo.app/DeviceInfo"; 466 | }; 467 | name = Debug; 468 | }; 469 | 962510B11F286C9A0031FEE4 /* Release */ = { 470 | isa = XCBuildConfiguration; 471 | buildSettings = { 472 | BUNDLE_LOADER = "$(TEST_HOST)"; 473 | DEVELOPMENT_TEAM = 97KXK82D47; 474 | INFOPLIST_FILE = DeviceInfoTests/Info.plist; 475 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 476 | PRODUCT_BUNDLE_IDENTIFIER = dzw.DeviceInfoTests; 477 | PRODUCT_NAME = "$(TARGET_NAME)"; 478 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DeviceInfo.app/DeviceInfo"; 479 | }; 480 | name = Release; 481 | }; 482 | 962510B31F286C9A0031FEE4 /* Debug */ = { 483 | isa = XCBuildConfiguration; 484 | buildSettings = { 485 | DEVELOPMENT_TEAM = 97KXK82D47; 486 | INFOPLIST_FILE = DeviceInfoUITests/Info.plist; 487 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 488 | PRODUCT_BUNDLE_IDENTIFIER = dzw.DeviceInfoUITests; 489 | PRODUCT_NAME = "$(TARGET_NAME)"; 490 | TEST_TARGET_NAME = DeviceInfo; 491 | }; 492 | name = Debug; 493 | }; 494 | 962510B41F286C9A0031FEE4 /* Release */ = { 495 | isa = XCBuildConfiguration; 496 | buildSettings = { 497 | DEVELOPMENT_TEAM = 97KXK82D47; 498 | INFOPLIST_FILE = DeviceInfoUITests/Info.plist; 499 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 500 | PRODUCT_BUNDLE_IDENTIFIER = dzw.DeviceInfoUITests; 501 | PRODUCT_NAME = "$(TARGET_NAME)"; 502 | TEST_TARGET_NAME = DeviceInfo; 503 | }; 504 | name = Release; 505 | }; 506 | /* End XCBuildConfiguration section */ 507 | 508 | /* Begin XCConfigurationList section */ 509 | 9625107A1F286C9A0031FEE4 /* Build configuration list for PBXProject "DeviceInfo" */ = { 510 | isa = XCConfigurationList; 511 | buildConfigurations = ( 512 | 962510AA1F286C9A0031FEE4 /* Debug */, 513 | 962510AB1F286C9A0031FEE4 /* Release */, 514 | ); 515 | defaultConfigurationIsVisible = 0; 516 | defaultConfigurationName = Release; 517 | }; 518 | 962510AC1F286C9A0031FEE4 /* Build configuration list for PBXNativeTarget "DeviceInfo" */ = { 519 | isa = XCConfigurationList; 520 | buildConfigurations = ( 521 | 962510AD1F286C9A0031FEE4 /* Debug */, 522 | 962510AE1F286C9A0031FEE4 /* Release */, 523 | ); 524 | defaultConfigurationIsVisible = 0; 525 | defaultConfigurationName = Release; 526 | }; 527 | 962510AF1F286C9A0031FEE4 /* Build configuration list for PBXNativeTarget "DeviceInfoTests" */ = { 528 | isa = XCConfigurationList; 529 | buildConfigurations = ( 530 | 962510B01F286C9A0031FEE4 /* Debug */, 531 | 962510B11F286C9A0031FEE4 /* Release */, 532 | ); 533 | defaultConfigurationIsVisible = 0; 534 | defaultConfigurationName = Release; 535 | }; 536 | 962510B21F286C9A0031FEE4 /* Build configuration list for PBXNativeTarget "DeviceInfoUITests" */ = { 537 | isa = XCConfigurationList; 538 | buildConfigurations = ( 539 | 962510B31F286C9A0031FEE4 /* Debug */, 540 | 962510B41F286C9A0031FEE4 /* Release */, 541 | ); 542 | defaultConfigurationIsVisible = 0; 543 | defaultConfigurationName = Release; 544 | }; 545 | /* End XCConfigurationList section */ 546 | }; 547 | rootObject = 962510771F286C9A0031FEE4 /* Project object */; 548 | } 549 | -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/project.xcworkspace/xcuserdata/Jason.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dtheme/DeviceInfo/62cbc71e3418b30b0b6685d83554c734773ec357/DeviceInfo.xcodeproj/project.xcworkspace/xcuserdata/Jason.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/project.xcworkspace/xcuserdata/zego.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dtheme/DeviceInfo/62cbc71e3418b30b0b6685d83554c734773ec357/DeviceInfo.xcodeproj/project.xcworkspace/xcuserdata/zego.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/xcuserdata/Jason.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/xcuserdata/Jason.xcuserdatad/xcschemes/DeviceInfo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/xcuserdata/Jason.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DeviceInfo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9625107E1F286C9A0031FEE4 16 | 17 | primary 18 | 19 | 20 | 962510971F286C9A0031FEE4 21 | 22 | primary 23 | 24 | 25 | 962510A21F286C9A0031FEE4 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /DeviceInfo.xcodeproj/xcuserdata/zego.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DeviceInfo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DeviceInfo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DeviceInfo 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /DeviceInfo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DeviceInfo 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | _window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds]; 20 | _window.backgroundColor =[UIColor whiteColor]; 21 | _window.rootViewController = [ViewController new]; 22 | [_window makeKeyAndVisible]; 23 | return YES; 24 | } 25 | 26 | 27 | - (void)applicationWillResignActive:(UIApplication *)application { 28 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 29 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 30 | } 31 | 32 | 33 | - (void)applicationDidEnterBackground:(UIApplication *)application { 34 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 36 | } 37 | 38 | 39 | - (void)applicationWillEnterForeground:(UIApplication *)application { 40 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 41 | } 42 | 43 | 44 | - (void)applicationDidBecomeActive:(UIApplication *)application { 45 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 46 | } 47 | 48 | 49 | - (void)applicationWillTerminate:(UIApplication *)application { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /DeviceInfo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /DeviceInfo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DeviceInfo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /DeviceInfo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DeviceInfo 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /DeviceInfo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DeviceInfo 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "DeviceInfo.h" 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | NSLog(@"deviceInfo-->%@",[DeviceInfo deviceInfo]); 20 | NSLog(@"executablePathMD5-->%@",[DeviceInfo executablePathAndMD5Value]); 21 | NSLog(@"isJailBrojen-->%d",[DeviceInfo isJailBroken]); 22 | NSLog(@"MacAddress-->%@",[DeviceInfo getMacAddress]); 23 | 24 | } 25 | 26 | 27 | - (void)didReceiveMemoryWarning { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /DeviceInfo/class/DeviceInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // DeviceInfo.h 3 | // DeviceInfo 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface DeviceInfo : NSObject 12 | 13 | 14 | 15 | // 返回本类提供的所有设备信息 16 | + (NSDictionary *)deviceInfo; 17 | 18 | /** 19 | executablePath 和 其进行MD5加密后的值 20 | 21 | executablePath = array[0]; 22 | MD5Value = array[1]; 23 | 24 | @return executablePath和其MD5值加密值 25 | */ 26 | + (NSArray *)executablePathAndMD5Value; 27 | 28 | /** 29 | 是否越狱 30 | 31 | @return 是否越狱 32 | */ 33 | + (BOOL)isJailBroken; 34 | 35 | /** 36 | 获取设备Mac地址 37 | 38 | @return Mac地址 39 | */ 40 | + (NSString *)getMacAddress; 41 | 42 | 43 | /** 44 | 获取App名称 45 | 46 | @return app名称 47 | */ 48 | + (NSString *)getApplicationName; 49 | 50 | /** 51 | 获取app版本号 52 | 53 | @return app版本号 54 | */ 55 | + (NSString*) getLocalAppVersion; 56 | 57 | /** 58 | 获取BundleID 59 | 60 | @return bundle ID 61 | */ 62 | + (NSString*)getBundleID; 63 | 64 | 65 | /** 66 | 获取设备当前IP 67 | 68 | @return 获取设备当前IP 69 | */ 70 | + (NSString *)getDeviceIPAdress; 71 | 72 | /** 73 | 电池电量 74 | 75 | @return 电池电量 76 | */ 77 | + (CGFloat)getBatteryLevel; 78 | 79 | 80 | /** 81 | 电池状态 82 | 83 | @return 电池状态 84 | */ 85 | + (NSString *) getBatteryState; 86 | 87 | /** 88 | 当期设备语言 89 | 90 | @return 当前设备语言 91 | */ 92 | + (NSString *)getDeviceLanguage; 93 | 94 | 95 | /** 96 | * 获取UUID后存入的keychain 97 | * 使用keychain实现唯一UUID的一种方案 98 | * @return keychain中存储的UUID 99 | */ 100 | + (NSString *)keyChainUUID; 101 | 102 | /** 103 | * 删除keychain中的UUID 104 | * 如果删除后,重新获取用户的UUID会与之前的UUID不同 105 | */ 106 | + (void)removeKeyChainUUID; 107 | @end 108 | -------------------------------------------------------------------------------- /DeviceInfo/class/DeviceInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // DeviceInfo.m 3 | // DeviceInfo 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import "DeviceInfo.h" 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import 19 | #import 20 | 21 | @interface DeviceInfo () 22 | @property (nonatomic, strong) NSMutableArray *array; 23 | @end 24 | 25 | #define IPHONE5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO) 26 | 27 | 28 | @interface DeviceInfo() 29 | { 30 | } 31 | @property (retain, nonatomic)NSMutableArray *dirFileList; 32 | @end 33 | 34 | @implementation DeviceInfo 35 | 36 | 37 | // 38 | static const char* jailbreak_apps[] = 39 | { 40 | "/Applications/Cydia.app", 41 | "/Applications/limera1n.app", 42 | "/Applications/greenpois0n.app", 43 | "/Applications/blackra1n.app", 44 | "/Applications/blacksn0w.app", 45 | "/Applications/redsn0w.app", 46 | "/Applications/Absinthe.app", 47 | NULL, 48 | }; 49 | 50 | +(NSString *)dataMD5:(NSString *)dataString 51 | { 52 | if(dataString == nil){ 53 | return @""; 54 | } 55 | 56 | #if(0) 57 | CC_MD5_CTX md5; 58 | CC_MD5_Init(&md5); 59 | NSData *fileAllData=[dataString dataUsingEncoding:NSUTF8StringEncoding]; 60 | NSRange range; 61 | int i = 0; 62 | BOOL done=NO; 63 | while (!done) { 64 | range.location = i*1024; 65 | NSData *fileData; 66 | if(range.location+1024<=fileAllData.length){ 67 | range.length = 1024; 68 | fileData=[fileAllData subdataWithRange:range]; 69 | } 70 | else if(range.location+1<=fileAllData.length){ 71 | range.length = fileAllData.length-range.location; 72 | fileData=[fileAllData subdataWithRange:range]; 73 | } 74 | else{ 75 | break; 76 | } 77 | 78 | CC_MD5_Update(&md5, [fileData bytes], (CC_LONG)[fileData length]); 79 | if([fileData length]==0) 80 | done=YES; 81 | 82 | i++; 83 | } 84 | unsigned char digest[CC_MD5_DIGEST_LENGTH]; 85 | CC_MD5_Final(digest, &md5); 86 | NSString* s = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 87 | digest[0], digest[1], 88 | digest[2], digest[3], 89 | digest[4], digest[5], 90 | digest[6], digest[7], 91 | digest[8], digest[9], 92 | digest[10], digest[11], 93 | digest[12], digest[13], 94 | digest[14], digest[15]]; 95 | return s; 96 | #endif 97 | 98 | const char *cStr = [dataString UTF8String]; 99 | unsigned char result[16]; 100 | CC_MD5( cStr, (unsigned int) strlen(cStr), result); 101 | NSString* s = [NSString stringWithFormat: 102 | @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 103 | result[0], result[1], result[2], result[3], 104 | result[4], result[5], result[6], result[7], 105 | result[8], result[9], result[10], result[11], 106 | result[12], result[13], result[14], result[15] 107 | ]; 108 | 109 | return s; 110 | 111 | } 112 | 113 | //MD5 114 | +(NSString *)fileMD5:(NSString *)path 115 | { 116 | NSFileHandle *hanle=[NSFileHandle fileHandleForReadingAtPath:path]; 117 | if(hanle==nil) 118 | { 119 | // NSLog(@"Open file reading failed, path:%@", path); 120 | return @""; 121 | } 122 | CC_MD5_CTX md5; 123 | CC_MD5_Init(&md5); 124 | BOOL done=NO; 125 | while (!done) { 126 | NSData *fileData=[hanle readDataOfLength:1024]; 127 | CC_MD5_Update(&md5, [fileData bytes], (CC_LONG)[fileData length]); 128 | if([fileData length]==0) 129 | done=YES; 130 | } 131 | unsigned char digest[CC_MD5_DIGEST_LENGTH]; 132 | CC_MD5_Final(digest, &md5); 133 | 134 | [hanle closeFile]; 135 | 136 | NSString* s = [NSString stringWithFormat: @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 137 | digest[0], digest[1], 138 | digest[2], digest[3], 139 | digest[4], digest[5], 140 | digest[6], digest[7], 141 | digest[8], digest[9], 142 | digest[10], digest[11], 143 | digest[12], digest[13], 144 | digest[14], digest[15]]; 145 | return s; 146 | 147 | 148 | } 149 | 150 | +(NSArray *)executablePathAndMD5Value{ 151 | NSString * appPath = [[NSBundle mainBundle] executablePath]; 152 | NSString* md5 = [DeviceInfo fileMD5:appPath]; 153 | if(nil == md5) 154 | md5 = @""; 155 | NSMutableArray *arr = [[NSMutableArray alloc]initWithObjects:appPath, md5,nil]; 156 | return [NSArray arrayWithArray:arr]; 157 | } 158 | 159 | //越狱 160 | +(BOOL)isJailBroken 161 | { 162 | for(int i = 0; jailbreak_apps[i] != NULL; ++i) 163 | { 164 | if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithUTF8String:jailbreak_apps[i]]]) 165 | { 166 | return YES; 167 | } 168 | } 169 | 170 | 171 | BOOL jailbroken = NO; 172 | NSString *cydiaPath = @"/Applications/Cydia.app"; 173 | NSString *aptPath = @"/private/var/lib/apt/"; 174 | if ([[NSFileManager defaultManager] fileExistsAtPath:cydiaPath]) { 175 | jailbroken = YES; 176 | } 177 | if ([[NSFileManager defaultManager] fileExistsAtPath:aptPath]) { 178 | jailbroken = YES; 179 | } 180 | return jailbroken; 181 | 182 | return NO; 183 | 184 | } 185 | +(NSDictionary *)deviceInfo 186 | { 187 | NSMutableDictionary *deviceInfo=[[NSMutableDictionary alloc]init]; 188 | NSString *deviceType = [DeviceInfo deviceTypeDetail]; 189 | 190 | NSString *OSVersion = [NSString stringWithFormat:@"%@ %@",[[UIDevice currentDevice] systemName],[[UIDevice currentDevice] systemVersion]]; 191 | [deviceInfo setObject:deviceType forKey:@"DeviceType"]; 192 | [deviceInfo setObject:OSVersion forKey:@"DeviceOsType"]; 193 | [deviceInfo setObject:[self getMacAddress] forKey:@"DeviceMac"]; 194 | [deviceInfo setObject:[UIDevice currentDevice].model forKey:@"DeviceModel"]; 195 | [deviceInfo setObject:[self getDeviceDisplayMetrics] forKey:@"DeviceMetrics"]; 196 | [deviceInfo setObject:[DeviceInfo cpuArchitectures] forKey:@"CPUArchitecture"]; 197 | [deviceInfo setObject:[DeviceInfo getBundleID] forKey:@"BundleID"]; 198 | [deviceInfo setObject:[DeviceInfo getLocalAppVersion] forKey:@"AppVersion"]; 199 | [deviceInfo setObject:[DeviceInfo getApplicationName] forKey:@"AppName"]; 200 | [deviceInfo setObject:[DeviceInfo getDeviceIPAdress] forKey:@"IP"]; 201 | [deviceInfo setObject:@([DeviceInfo getBatteryLevel]) forKey:@"BatteryLevel"]; 202 | [deviceInfo setObject:[DeviceInfo getBatteryState] forKey:@"BatteryState"]; 203 | [deviceInfo setObject:[DeviceInfo keyChainUUID] forKey:@"UUID"]; 204 | return deviceInfo; 205 | } 206 | 207 | 208 | + (NSString *)getDeviceDisplayMetrics { 209 | NSString *DisplayMetrics; 210 | if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { 211 | if (IPHONE5) 212 | { 213 | DisplayMetrics=@"1136*640"; 214 | } 215 | if ([DeviceInfo iPhoneX]|| 216 | [[DeviceInfo deviceTypeDetail] isEqualToString:@"iPhone XS"]) 217 | { 218 | DisplayMetrics = @"2436*1125"; 219 | } 220 | if ([[DeviceInfo deviceTypeDetail] isEqualToString:@"iPhone XR"]) 221 | { 222 | DisplayMetrics = @"1792*828"; 223 | } 224 | if ([[DeviceInfo deviceTypeDetail]isEqualToString:@"iPhone XS Max"]) { 225 | DisplayMetrics = @"1242*2688"; 226 | } 227 | if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && 228 | ([UIScreen mainScreen].scale == 2.0)) { 229 | DisplayMetrics=@"960*640"; 230 | } 231 | else { 232 | DisplayMetrics=@"480*320"; 233 | } 234 | }else { 235 | if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && 236 | ([UIScreen mainScreen].scale == 2.0)) { 237 | DisplayMetrics=@"1024*768"; 238 | } 239 | else { 240 | DisplayMetrics=@"2048*1536"; 241 | } 242 | } 243 | return DisplayMetrics; 244 | } 245 | + (NSString *)getMacAddress 246 | { 247 | int mgmtInfoBase[6]; 248 | char *msgBuffer = NULL; 249 | size_t length; 250 | unsigned char macAddress[6]; 251 | struct if_msghdr *interfaceMsgStruct; 252 | struct sockaddr_dl *socketStruct; 253 | NSString *errorFlag = NULL; 254 | NSString *macAddressString = nil; 255 | 256 | mgmtInfoBase[0] = CTL_NET; // Request network subsystem 257 | mgmtInfoBase[1] = AF_ROUTE; // Routing table info 258 | mgmtInfoBase[2] = 0; 259 | mgmtInfoBase[3] = AF_LINK; // Request link layer information 260 | mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces 261 | 262 | if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0) 263 | errorFlag = @"if_nametoindex failure"; 264 | else 265 | { 266 | if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0) 267 | errorFlag = @"sysctl mgmtInfoBase failure"; 268 | else 269 | { 270 | if ((msgBuffer = malloc(length)) == NULL) 271 | errorFlag = @"buffer allocation failure"; 272 | else 273 | { 274 | if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0) 275 | errorFlag = @"sysctl msgBuffer failure"; 276 | } 277 | } 278 | } 279 | 280 | // Befor going any further... 281 | if (errorFlag != NULL) 282 | { 283 | macAddressString = nil; 284 | 285 | // Release the buffer memory 286 | free(msgBuffer); 287 | } 288 | else 289 | { 290 | interfaceMsgStruct = (struct if_msghdr *) msgBuffer; 291 | 292 | socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1); 293 | 294 | memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6); 295 | 296 | macAddressString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", 297 | macAddress[0], macAddress[1], macAddress[2], 298 | macAddress[3], macAddress[4], macAddress[5]]; 299 | 300 | free(msgBuffer); 301 | } 302 | 303 | 304 | if ([[[UIDevice currentDevice] systemVersion]intValue]<6) 305 | { 306 | if(macAddressString == nil || [macAddressString isEqualToString:@""]) 307 | return @"000000000000"; 308 | 309 | return macAddressString; 310 | } 311 | else if ([[[UIDevice currentDevice] systemVersion]intValue]==6) 312 | { 313 | if(macAddressString == nil || [macAddressString isEqualToString:@""]) 314 | { 315 | 316 | NSString *UUIDString = [[[UIDevice currentDevice]identifierForVendor]UUIDString]; 317 | if(UUIDString != nil && ![UUIDString isEqualToString:@""]) 318 | return [UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""]; 319 | else 320 | return @"000000000000"; 321 | 322 | } 323 | else 324 | { 325 | return macAddressString; 326 | } 327 | } 328 | else 329 | { 330 | //所有iOS7之后设备mac地址都返回020000000000,在此直接用UUIDString代替 331 | 332 | //96FEADAA-884B-405A-A382-9E275FC15580 333 | NSString *UUIDString = [[[UIDevice currentDevice]identifierForVendor]UUIDString]; 334 | if(UUIDString != nil && ![UUIDString isEqualToString:@""]) 335 | return [UUIDString stringByReplacingOccurrencesOfString:@"-" withString:@""]; 336 | else 337 | return @"000000000000"; 338 | } 339 | } 340 | 341 | + (NSString *)cpuArchitectures{ 342 | struct utsname systemInfo; 343 | uname(&systemInfo); 344 | return [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; 345 | } 346 | 347 | //获取设备型号 348 | //可根据https://www.theiphonewiki.com/wiki/Models#iPhone添加 349 | + (NSString*)deviceTypeDetail 350 | { 351 | // 需要#import "sys/utsname.h" 352 | struct utsname systemInfo; 353 | uname(&systemInfo); 354 | NSString *deviceString = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding]; 355 | //iPhone 356 | if ([deviceString isEqualToString:@"iPhone1,1"]) return @"iPhone 1G"; 357 | if ([deviceString isEqualToString:@"iPhone1,2"]) return @"iPhone 3G"; 358 | if ([deviceString isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS"; 359 | if ([deviceString isEqualToString:@"iPhone3,1"]) return @"iPhone 4"; 360 | if ([deviceString isEqualToString:@"iPhone3,2"]) return @"Verizon iPhone 4"; 361 | if ([deviceString isEqualToString:@"iPhone4,1"]) return @"iPhone 4S"; 362 | if ([deviceString isEqualToString:@"iPhone5,1"]) return @"iPhone 5"; 363 | if ([deviceString isEqualToString:@"iPhone5,2"]) return @"iPhone 5"; 364 | if ([deviceString isEqualToString:@"iPhone5,3"]) return @"iPhone 5C"; 365 | if ([deviceString isEqualToString:@"iPhone5,4"]) return @"iPhone 5C"; 366 | if ([deviceString isEqualToString:@"iPhone6,1"]) return @"iPhone 5S"; 367 | if ([deviceString isEqualToString:@"iPhone6,2"]) return @"iPhone 5S"; 368 | if ([deviceString isEqualToString:@"iPhone7,1"]) return @"iPhone 6 Plus"; 369 | if ([deviceString isEqualToString:@"iPhone7,2"]) return @"iPhone 6"; 370 | if ([deviceString isEqualToString:@"iPhone8,1"]) return @"iPhone 6s"; 371 | if ([deviceString isEqualToString:@"iPhone8,2"]) return @"iPhone 6s Plus"; 372 | if ([deviceString isEqualToString:@"iPhone8,4"]) return @"iPhone SE"; 373 | if ([deviceString isEqualToString:@"iPhone9,1"]) return @"iPhone 7"; 374 | if ([deviceString isEqualToString:@"iPhone9,2"]) return @"iPhone 7 Plus"; 375 | if ([deviceString isEqualToString:@"iPhone9,3"]) return @"iPhone 7"; 376 | if ([deviceString isEqualToString:@"iPhone9,4"]) return @"iPhone 7 Plus"; 377 | if ([deviceString isEqualToString:@"iPhone10,1"]) return @"iPhone 8"; 378 | if ([deviceString isEqualToString:@"iPhone10,2"]) return @"iPhone 8"; 379 | if ([deviceString isEqualToString:@"iPhone10,4"]) return @"iPhone 8"; 380 | if ([deviceString isEqualToString:@"iPhone10,5"]) return @"iPhone 8"; 381 | if ([deviceString isEqualToString:@"iPhone10,3"]) return @"iPhone X"; 382 | if ([deviceString isEqualToString:@"iPhone10,6"]) return @"iPhone X"; 383 | 384 | if ([deviceString isEqualToString:@"iPhone11,8"]) return @"iPhone XR"; 385 | if ([deviceString isEqualToString:@"iPhone11,2"]) return @"iPhone XS"; 386 | if ([deviceString isEqualToString:@"iPhone11,4"]) return @"iPhone XS Max"; 387 | if ([deviceString isEqualToString:@"iPhone11,6"]) return @"iPhone XS Max"; 388 | 389 | //iPad 390 | if ([deviceString isEqualToString:@"iPad1,1"]) return @"iPad"; 391 | if ([deviceString isEqualToString:@"iPad2,1"]) return @"iPad 2 (WiFi)"; 392 | if ([deviceString isEqualToString:@"iPad2,2"]) return @"iPad 2 (GSM)"; 393 | if ([deviceString isEqualToString:@"iPad2,3"]) return @"iPad 2 (CDMA)"; 394 | if ([deviceString isEqualToString:@"iPad2,4"]) return @"iPad 2 (32nm)"; 395 | if ([deviceString isEqualToString:@"iPad2,5"]) return @"iPad mini (WiFi)"; 396 | if ([deviceString isEqualToString:@"iPad2,6"]) return @"iPad mini (GSM)"; 397 | if ([deviceString isEqualToString:@"iPad2,7"]) return @"iPad mini (CDMA)"; 398 | if ([deviceString isEqualToString:@"iPad4,4"]) return @"iPad mini 2"; 399 | if ([deviceString isEqualToString:@"iPad4,5"]) return @"iPad mini 2"; 400 | if ([deviceString isEqualToString:@"iPad4,6"]) return @"iPad mini 2"; 401 | if ([deviceString isEqualToString:@"iPad4,7"]) return @"iPad mini 3"; 402 | if ([deviceString isEqualToString:@"iPad4,8"]) return @"iPad mini 3"; 403 | if ([deviceString isEqualToString:@"iPad5,1"]) return @"iPad mini 4"; 404 | if ([deviceString isEqualToString:@"iPad5,2"]) return @"iPad mini 4"; 405 | 406 | 407 | if ([deviceString isEqualToString:@"iPad3,1"]) return @"iPad 3(WiFi)"; 408 | if ([deviceString isEqualToString:@"iPad3,2"]) return @"iPad 3(CDMA)"; 409 | if ([deviceString isEqualToString:@"iPad3,3"]) return @"iPad 3(4G)"; 410 | if ([deviceString isEqualToString:@"iPad3,4"]) return @"iPad 4 (WiFi)"; 411 | if ([deviceString isEqualToString:@"iPad3,5"]) return @"iPad 4 (4G)"; 412 | if ([deviceString isEqualToString:@"iPad3,6"]) return @"iPad 4 (CDMA)"; 413 | 414 | if ([deviceString isEqualToString:@"iPad4,1"]) return @"iPad Air"; 415 | if ([deviceString isEqualToString:@"iPad4,2"]) return @"iPad Air"; 416 | if ([deviceString isEqualToString:@"iPad4,3"]) return @"iPad Air"; 417 | if ([deviceString isEqualToString:@"iPad5,3"]) return @"iPad Air 2"; 418 | if ([deviceString isEqualToString:@"iPad5,4"]) return @"iPad Air 2"; 419 | 420 | if ([deviceString isEqualToString:@"iPad6,3"]) return @"iPad Pro (9.7-inch)"; 421 | if ([deviceString isEqualToString:@"iPad6,4"]) return @"iPad Pro (9.7-inch)"; 422 | if ([deviceString isEqualToString:@"iPad6,7"]) return @"iPad Pro (12.9-inch)"; 423 | if ([deviceString isEqualToString:@"iPad6,8"]) return @"iPad Pro (12.9-inch)"; 424 | if ([deviceString isEqualToString:@"iPad6,11"]) return @"iPad (5th generation)"; 425 | if ([deviceString isEqualToString:@"iPad6,12"]) return @"iPad (5th generation)"; 426 | if ([deviceString isEqualToString:@"iPad7,1"]) return @"iPad Pro (12.9-inch, 2nd generation)"; 427 | if ([deviceString isEqualToString:@"iPad7,2"]) return @"iPad Pro (12.9-inch, 2nd generation)"; 428 | if ([deviceString isEqualToString:@"iPad7,3"]) return @"iPad Pro (10.5-inch)"; 429 | if ([deviceString isEqualToString:@"iPad7,4"]) return @"iPad Pro (10.5-inch)"; 430 | if ([deviceString isEqualToString:@"iPad7,5"]) return @"iPad (6th generation)"; 431 | if ([deviceString isEqualToString:@"iPad7,6"]) return @"iPad (6th generation)"; 432 | 433 | if ([deviceString isEqualToString:@"i386"]) return @"Simulator"; 434 | if ([deviceString isEqualToString:@"x86_64"]) return @"Simulator"; 435 | 436 | 437 | return deviceString; 438 | } 439 | 440 | 441 | //为了做iPhoneX 适配 无论是模拟器还是真机 都会判断出iPhone X 不影响上面方法 442 | + (BOOL)iPhoneX { 443 | struct utsname systemInfo; 444 | uname(&systemInfo); 445 | NSString *platform = [NSString stringWithCString:systemInfo.machine encoding:NSASCIIStringEncoding]; 446 | if ([platform isEqualToString:@"i386"] || [platform isEqualToString:@"x86_64"]) { 447 | return (CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(375, 812)) || 448 | CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(812, 375))); 449 | } 450 | BOOL isIPhoneX = [platform isEqualToString:@"iPhone10,3"] || [platform isEqualToString:@"iPhone10,6"]; 451 | return isIPhoneX; 452 | } 453 | +(NSDictionary *)appVersionInfo 454 | { 455 | 456 | NSDictionary *infoDic=[[NSBundle mainBundle] infoDictionary]; 457 | 458 | // CFShow((__bridge CFTypeRef)(infoDic)); 459 | //app名称 460 | NSString *app_Name=[infoDic objectForKey:@"CFBundleDisplayName"]; 461 | //app版本号 462 | NSString *app_Version=[infoDic objectForKey:@"CFBundleVersion"]; 463 | // 464 | 465 | NSDictionary *versionDic=[NSDictionary dictionaryWithObjectsAndKeys:app_Name,@"VersionName",app_Version,@"VersionCode",@"",@"VersionType",@"",@"VersionSource", nil]; 466 | 467 | return versionDic; 468 | 469 | } 470 | 471 | //getMainBundleMD5WithFlag方法为试验性的代码,上线时谨慎使用 472 | //flag 为1:每个文件的MD5追加存到同一个文件里,最后读取这个文件计算MD5. 473 | //flag 为2:每个文件的MD5追加存到同一个NSMutableString对象,再对这个对象内容计算MD5。如果文件很多,例如2000多个文件,NSMutableString对象会占用比较大的内存,再加上程序可用内存又不够多的话,虽然用我手头的iPhone 7测试没有问题,但是恐怕内存不够用产生问题。 474 | -(NSString*)getMainBundleMD5WithFlag:(NSInteger)flag 475 | { 476 | if(flag!=1 && flag!=2){ 477 | return @""; 478 | } 479 | 480 | NSString *appPath = [[NSBundle mainBundle] resourcePath]; 481 | 482 | //获取需要计算MD5的所有文件的路径 483 | self.dirFileList = [[NSMutableArray alloc] initWithCapacity:30]; 484 | [self allFilesAtPath:appPath]; 485 | 486 | NSMutableString *allFilesMD5string = [[NSMutableString alloc] init]; 487 | NSFileHandle *outFile; 488 | NSString *filePath; 489 | NSFileManager *defaultManager; 490 | 491 | if(flag == 1) 492 | { 493 | NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 494 | 495 | filePath = [documentsDirectory stringByAppendingPathComponent:@"md5.txt"]; 496 | // NSLog(@"md5filePath:%@",filePath); 497 | 498 | defaultManager = [NSFileManager defaultManager];//[[NSFileManager alloc]init];// 499 | if([defaultManager fileExistsAtPath:filePath]) { 500 | //以防万一,先删除已存在文件 501 | [defaultManager removeItemAtPath:filePath error:nil]; 502 | } 503 | 504 | //重新创建文件, NSFileHandle类没有提供创建文件的功能,所以必须使用NSFileManager来先创建文件 505 | [defaultManager createFileAtPath:filePath contents:nil attributes:nil]; 506 | 507 | //打开文件, 用于写操作 508 | outFile = [NSFileHandle fileHandleForWritingAtPath:filePath]; 509 | if(outFile == nil) 510 | { 511 | // NSLog(@"Open file writing failed, path:%@", filePath); 512 | return @""; 513 | } 514 | } 515 | 516 | 517 | while (self.dirFileList.count>0) { 518 | NSString *fileFullPathName = self.dirFileList[self.dirFileList.count-1]; 519 | 520 | //NSLog(@"%d, fileFullPathName>>>>: %@",self.dirFileList.count-1,fileFullPathName); 521 | NSString *fileMD5 = [DeviceInfo fileMD5:fileFullPathName]; 522 | if(fileMD5!=nil && ![fileMD5 isEqualToString:@""]) 523 | { 524 | 525 | if(flag == 1){ 526 | NSData *dataBuffer = [[fileMD5 stringByAppendingString:@"|"] dataUsingEncoding:NSUTF8StringEncoding]; 527 | //定位到文件的末尾位置(将在此追加文件内容) 528 | [outFile seekToEndOfFile]; 529 | //将数据写入文件 530 | [outFile writeData:dataBuffer]; 531 | 532 | } 533 | else 534 | { 535 | [allFilesMD5string appendString:fileMD5]; 536 | [allFilesMD5string appendString:@"|"]; 537 | } 538 | 539 | } 540 | 541 | [self.dirFileList removeObjectAtIndex:self.dirFileList.count-1]; 542 | } 543 | 544 | 545 | if(self.dirFileList.count>0){ 546 | [self.dirFileList removeAllObjects]; 547 | } 548 | self.dirFileList = nil;//及时释放资源 549 | 550 | NSString *MD5; 551 | if(flag == 1) 552 | { 553 | [outFile closeFile]; 554 | MD5 = [DeviceInfo fileMD5:filePath]; 555 | [defaultManager removeItemAtPath:filePath error:nil]; 556 | 557 | }else 558 | { 559 | MD5 = [DeviceInfo dataMD5:allFilesMD5string]; 560 | } 561 | 562 | // NSLog(@"MD5 = %@",MD5); 563 | if(MD5 == nil) 564 | MD5 = @""; 565 | 566 | return MD5; 567 | } 568 | 569 | //获取所有文件的全路径 570 | - (void)allFilesAtPath:(NSString*)dirString 571 | { 572 | NSError *error = nil; 573 | NSArray *contentOfFolder = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:dirString error:&error]; 574 | 575 | if(error) 576 | return; 577 | 578 | for (NSString *fileName in contentOfFolder) { 579 | NSString * fullPath = [dirString stringByAppendingPathComponent:fileName]; 580 | BOOL isDir; 581 | if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir){ 582 | // ignore .DS_Store,忽略隐藏文件 583 | //说明:计算太多文件的MD5,会影响程序启动速度,在此可以根据需要忽略掉一些文件,比如图片文件 584 | if (![[fileName substringToIndex:1] isEqualToString:@"."] 585 | && ![fileName isEqualToString:@"CodeResources"] 586 | && ![fileName isEqualToString:@"ResourceRules.plist"] 587 | && ![fileName isEqualToString:@"PkgInfo"] 588 | && ![fileName hasSuffix:@".mobileprovision"] 589 | && ![fileName hasSuffix:@".png"] && ![fileName hasSuffix:@".jpg"] && ![fileName hasSuffix:@".bmp"] && ![fileName hasSuffix:@".aiff"] && ![fileName hasSuffix:@".gif"] && ![fileName hasSuffix:@".mp4"] && ![fileName hasSuffix:@".wav"] ) { 590 | [self.dirFileList addObject:fullPath]; 591 | } 592 | }else{ 593 | 594 | //过滤掉某些文件夹,SC_Info里的文件包含每个用户自己的AppStore账号信息,不能参与计算MD5 595 | if(![fileName isEqualToString:@"_CodeSignature"] 596 | && ![fileName isEqualToString:@"SC_Info"] 597 | /*&& ![fileName isEqualToString:@"xface"]*/ 598 | && ![fileName hasSuffix:@".bundle"]) 599 | { 600 | [self allFilesAtPath:fullPath]; 601 | } 602 | } 603 | } 604 | } 605 | 606 | + (NSString *)getDeviceIPAdress { 607 | 608 | NSString *address = @"an error occurred when obtaining ip address"; 609 | 610 | struct ifaddrs *interfaces = NULL; 611 | 612 | struct ifaddrs *temp_addr = NULL; 613 | 614 | int success = 0; 615 | 616 | success = getifaddrs(&interfaces); 617 | 618 | if (success == 0) { // 0 表示获取成功 619 | 620 | temp_addr = interfaces; 621 | 622 | while (temp_addr != NULL) { 623 | 624 | if( temp_addr->ifa_addr->sa_family == AF_INET) { 625 | 626 | // Check if interface is en0 which is the wifi connection on the iPhone 627 | 628 | if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) { 629 | 630 | // Get NSString from C String 631 | 632 | address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; 633 | } 634 | } 635 | temp_addr = temp_addr->ifa_next; 636 | } 637 | } 638 | 639 | freeifaddrs(interfaces); 640 | 641 | return address; 642 | } 643 | 644 | +(NSString*)getLocalAppVersion{ 645 | 646 | return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; 647 | 648 | } 649 | 650 | +(NSString*)getApplicationName{ 651 | 652 | NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]; 653 | 654 | NSMutableString *mutableAppName = [NSMutableString stringWithString:appName]; 655 | return [mutableAppName copy]; 656 | } 657 | 658 | +(NSString*)getBundleID{ 659 | 660 | return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]; 661 | 662 | } 663 | 664 | 665 | + (CGFloat)getBatteryLevel { 666 | 667 | UIApplication *app = [UIApplication sharedApplication]; 668 | 669 | if (app.applicationState == UIApplicationStateActive||app.applicationState==UIApplicationStateInactive) { 670 | 671 | Ivar ivar= class_getInstanceVariable([app class],"_statusBar"); 672 | 673 | id status = object_getIvar(app, ivar); 674 | 675 | for (id aview in [status subviews]) { 676 | 677 | int batteryLevel = 0; 678 | 679 | for (id bview in [aview subviews]) { 680 | 681 | if ([NSStringFromClass([bview class]) caseInsensitiveCompare:@"UIStatusBarBatteryItemView"] == NSOrderedSame&&[[[UIDevice currentDevice] systemVersion] floatValue] >=6.0) { 682 | 683 | Ivar ivar= class_getInstanceVariable([bview class],"_capacity"); 684 | 685 | if(ivar) { 686 | 687 | batteryLevel = ((int (*)(id, Ivar))object_getIvar)(bview, ivar); 688 | 689 | if (batteryLevel > 0 && batteryLevel <= 100) { 690 | 691 | return batteryLevel; 692 | 693 | } else { 694 | return 0; 695 | } 696 | } 697 | } 698 | } 699 | } 700 | } 701 | return 0; 702 | 703 | } 704 | 705 | + (NSString *) getBatteryState { 706 | 707 | UIDevice *device = [UIDevice currentDevice]; 708 | 709 | if (device.batteryState == UIDeviceBatteryStateUnknown) { 710 | 711 | return @"UnKnow"; 712 | 713 | } else if (device.batteryState == UIDeviceBatteryStateUnplugged){ 714 | 715 | return @"Unplugged"; 716 | 717 | } else if (device.batteryState == UIDeviceBatteryStateCharging){ 718 | 719 | return @"Charging"; 720 | 721 | } else if (device.batteryState == UIDeviceBatteryStateFull){ 722 | 723 | return @"Full"; 724 | 725 | } 726 | 727 | return nil; 728 | 729 | } 730 | 731 | // 具体如何根据返回的字符串判断 可以参考这篇博客 http://www.cnblogs.com/bingxue314159/p/5381947.html 732 | + (NSString *)getDeviceLanguage { 733 | 734 | NSArray *languageArray = [NSLocale preferredLanguages]; 735 | return [languageArray objectAtIndex:0]; 736 | 737 | } 738 | 739 | + (NSString *)keychainUUID { 740 | 741 | NSString *getUDIDInKeychain = (NSString *)[DeviceInfo load:[[NSBundle mainBundle]bundleIdentifier]]; 742 | 743 | if (!getUDIDInKeychain || [getUDIDInKeychain isEqualToString:@""] || [getUDIDInKeychain isKindOfClass:[NSNull class]]) { 744 | 745 | CFUUIDRef puuid = CFUUIDCreate(nil); 746 | CFStringRef uuidString = CFUUIDCreateString(nil, puuid); 747 | NSString *result = (NSString *)CFBridgingRelease(CFStringCreateCopy(NULL, uuidString)); 748 | CFRelease(puuid); 749 | CFRelease(uuidString); 750 | 751 | [DeviceInfo save:[[NSBundle mainBundle]bundleIdentifier] data:result]; 752 | getUDIDInKeychain = (NSString *)[DeviceInfo load:[[NSBundle mainBundle]bundleIdentifier]]; 753 | } 754 | 755 | return getUDIDInKeychain; 756 | } 757 | 758 | + (void)removeKeyChainUUID { 759 | 760 | NSMutableDictionary *keychainQuery = [self getKeyChainQuery:[[NSBundle mainBundle]bundleIdentifier]]; 761 | SecItemDelete((CFDictionaryRef)keychainQuery); 762 | 763 | } 764 | 765 | + (NSMutableDictionary *)getKeyChainQuery:(NSString *)service { 766 | 767 | return [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword,(id)kSecClass,service,(id)kSecAttrService,service,(id)kSecAttrAccount,(id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible, nil]; 768 | } 769 | 770 | + (id)load:(NSString *)service { 771 | 772 | id ret = nil; 773 | 774 | NSMutableDictionary *keychainQuery = [self getKeyChainQuery:service]; 775 | [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData]; 776 | [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit]; 777 | CFDataRef keyData = NULL; 778 | 779 | if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { 780 | @try { 781 | ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData]; 782 | } 783 | @catch (NSException *exception) { 784 | NSLog(@"Unarchive of %@ failed: %@", service, exception); 785 | } 786 | @finally { 787 | } 788 | } 789 | 790 | if (keyData) { 791 | CFRelease(keyData); 792 | } 793 | 794 | return ret; 795 | } 796 | 797 | + (void)save:(NSString *)service data:(id)data { 798 | 799 | NSMutableDictionary *keychainQuery = [self getKeyChainQuery:service]; 800 | SecItemDelete((CFDictionaryRef)keychainQuery); 801 | [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData]; 802 | SecItemAdd((CFDictionaryRef)keychainQuery, NULL); 803 | 804 | } 805 | 806 | + (NSString *)originUUID { 807 | 808 | CFUUIDRef puuid = CFUUIDCreate( nil ); 809 | CFStringRef uuidString = CFUUIDCreateString(nil, puuid); 810 | NSString *result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString)); 811 | 812 | return result; 813 | } 814 | @end 815 | -------------------------------------------------------------------------------- /DeviceInfo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DeviceInfo 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DeviceInfoTests/DeviceInfoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DeviceInfoTests.m 3 | // DeviceInfoTests 4 | // 5 | // Created by dzw on 2017/7/26. 6 | // Copyright © 2017年 段志巍. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DeviceInfo.h" 11 | 12 | @interface DeviceInfoTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation DeviceInfoTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | #pragma mark - test case 29 | - (void)testExample { 30 | // This is an example of a functional test case. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | [self measureBlock:^{ 33 | NSDictionary *dict = [DeviceInfo deviceInfo]; 34 | NSLog(@"%@",dict); 35 | }]; 36 | } 37 | 38 | -(void)testExecutablePathAndMD5Value{ 39 | [self measureBlock:^{ 40 | NSArray *arr = [DeviceInfo executablePathAndMD5Value]; 41 | NSLog(@"%@",[arr copy]); 42 | }]; 43 | } 44 | 45 | 46 | 47 | 48 | #pragma mark - test case 49 | 50 | 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /DeviceInfoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 duanzhiwei 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DeviceInfo 2 | 3 | 4 | 获取iOS设备的设备信息 5 | 6 | Get iOS device Infomation,This utility class is used to obtain some common device information. 7 | 8 | 9 | 这个工具类是封装了一些常用方法,用于获取了一些常用的iOS设备信息。 10 | 11 | ### 包含的方法 12 | 13 | `+ (NSDictionary *)deviceInfo;` 14 | 15 | 返回一个字典,包含本类中提供的方法的所有值 16 | 17 | `+ (NSArray *)executablePathAndMD5Value;` 18 | 19 | 返回一个数组,index0是executablePath,index1是它的MD5加密值 20 | 21 | `+ (BOOL)isJailBrojen;` 22 | 23 | 判断是否为越狱设备 24 | 25 | `+ (NSString *)getMacAddress;` 26 | 27 | 获取设备当前IP 28 | 29 | `+ (NSString *)getDeviceLanguage;` 30 | 31 | 获取当前设备的语言环境 32 | 33 | `+ (NSString *) getBatteryState;` 34 | 35 | 获取当前的电池状态 36 | 37 | `+ (CGFloat)getBatteryLevel;` 38 | 39 | 获取当前的电池电量 40 | 41 | `+ (NSString *)getApplicationName;` 42 | 43 | app名称 44 | 45 | `+ (NSString*) getLocalAppVersion;` 46 | 47 | 获取app版本号 48 | 49 | 50 | ### 使用 51 | 52 | 所有方法都已经封装成类方法,引入`DeviceInfo.h`后就可以直接调。 53 | 54 | ```objc 55 | #import "DeviceInfo.h" 56 | ``` 57 | 58 | 59 | ```objc 60 | NSLog(@"deviceInfo-->%@",[DeviceInfo deviceInfo]); 61 | NSLog(@"executablePathMD5-->%@",[DeviceInfo executablePathAndMD5Value]); 62 | NSLog(@"isJailBrojen-->%d",[DeviceInfo isJailBrojen]); 63 | ``` 64 | 65 | 66 | --------------------------------------------------------------------------------