简体   繁体   中英

Is it possible to detect that your iOS app is running on an iPad mini at runtime?

Detecting different hardware at runtime is useful for analytics (among other, even more questionable purposes).

Many iOS app creators may be interested to know how many users are experiencing their app on an iPad mini (rather than just knowing how many users are experiencing their app on an iPad with 1024x768 screen resolution - which would also be interesting).

Is there any public API in Cocoa touch/UIKit/ObjC/C which could be used to detect that your iOS app is running on an iPad mini at runtime? Ideally, this method should distinguish between iPad 2 & iPad mini (which have the same number of pixels, but a different pixel density).


Post Script: I realize many people will consider detecting iPad mini at runtime a bad idea. However, I think this is a valid question with a definite Yes or No answer. An answer which I think it is useful for the community to know.

Boxel's answer would be good if it didn't invoke undefined behavior and if it didn't have superfluous parts. One, + [NSString stringWithCString:encoding:] requires a C string - that is, a NUL-terminated char pointer (else it will most likely dump core). Also, you don't need the conversion to NSString - since sysctlbyname() provides you with a plain old C string (without the NUL terminator, of course), you can directly use strcmp() to save a few dozen CPU cycles:

#include <sys/sysctl.h>

size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = malloc(size + 1);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
machine[size] = 0;

if (strcmp(machine, "iPad2,5") == 0) {
    /* iPad mini */
}

free(machine);

Edit: now that answer is fixed as well.

Use sysctlbyname to get the platform string, then compare it with the IPSW prefix strings listed here . It looks like the only currently known iPad Mini is "iPad2,5"

Example:

size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = malloc(size + 1);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
machine[size] = 0;

if(strcmp(machine, "iPad2,5") == 0) {
    // do something special on the iPad Mini    
}

free(machine);

There is no reliable, future-proof way to detect the iPad mini's pixel density. Other answers suggest looking at the hw.machine string. But we don't know (as of the time I write this) what the strings will be for the iPad mini cellular models (though we can make an educated guess: iPad2,6 will probably have GSM and iPad2,7 will probably have CDMA).

It's fine to look at the hw.machine string for analytics. But it's dangerous to let it affect your app's user interface, because even the iPad2,5 string for the current iPad mini is subject to change.

When the iPad 2 came out, the wifi model's string was iPad2,1 . Later (when they released the iPad 3), they changed the iPad 2 hardware and changed the hw.machine string to iPad2,4 , but they still called it the iPad 2. The same thing could happen with the iPad mini - or even with the iPad 2 again! For example, Apple could release yet another version of the iPad 2 hardware and give it the machine string iPad2,8 .

import CoreTelephony.framework. Try this on device

#import <sys/utsname.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

NSString*
machineName()
{
    struct utsname systemInfo;
    uname(&systemInfo);

    return [NSString stringWithCString:systemInfo.machine
                          encoding:NSUTF8StringEncoding];
}

This solves my purpose up to now. But as I don't have any iPad mini I don't know what it gonna print for iPad mini. Could you let me know?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM