简体   繁体   English

是否有可能在运行时检测到您的iOS应用程序在iPad mini上运行?

[英]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). 许多iOS应用程序创建者可能有兴趣知道有多少用户在iPad mini上体验他们的应用程序(而不仅仅知道有多少用户在iPad上以1024x768的屏幕分辨率体验他们的应用程序 - 这也很有趣)。

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? Cocoa touch/UIKit/ObjC/C是否有任何公共API可用于检测您的iOS应用程序是否在运行时在iPad mini上运行? Ideally, this method should distinguish between iPad 2 & iPad mini (which have the same number of pixels, but a different pixel density). 理想情况下,此方法应区分iPad 2和iPad mini(具有相同像素数,但像素密度不同)。


Post Script: I realize many people will consider detecting iPad mini at runtime a bad idea. Post Script:我意识到很多人会考虑在运行时检测iPad mini是一个坏主意。 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. 如果没有调用未定义的行为并且它没有多余的部分,Boxel的答案会很好。 One, + [NSString stringWithCString:encoding:] requires a C string - that is, a NUL-terminated char pointer (else it will most likely dump core). 一, + [NSString stringWithCString:encoding:]需要一个C字符串 - 即一个NUL终止的char指针(否则它很可能会转储核心)。 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: 此外,您不需要转换为NSString - 因为sysctlbyname()为您提供了一个普通的旧C字符串(当然没有NUL终结符),您可以直接使用strcmp()来保存几十个CPU周期:

#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 . 使用sysctlbyname获取平台字符串,然后将其与此处列出的IPSW前缀字符串进行比较。 It looks like the only currently known iPad Mini is "iPad2,5" 看起来目前唯一知名的iPad Mini是“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. 没有可靠的,面向未来的方法来检测iPad mini的像素密度。 Other answers suggest looking at the hw.machine string. 其他答案建议查看hw.machine字符串。 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). 但是我们不知道(截至我写这篇文章的时候)iPad mini蜂窝模型的字符串是什么(虽然我们可以做出有根据的猜测: iPad2,6可能会有GSM和iPad2,7可能会有CDMA )。

It's fine to look at the hw.machine string for analytics. 可以查看hw.machine字符串进行分析。 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. 但让它影响你的应用程序的用户界面是危险的,因为即使是当前iPad mini的iPad2,5字符串也可能会发生变化。

When the iPad 2 came out, the wifi model's string was iPad2,1 . 当iPad 2问世时,wifi模型的字符串是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! 后来(当他们发布iPad 3时), 他们更换了iPad 2硬件并将hw.machine字符串更改为iPad2,4 ,但他们仍将其称为iPad 2.使用iPad mini也可能发生同样的事情 - 甚至是iPad 2又来了! For example, Apple could release yet another version of the iPad 2 hardware and give it the machine string iPad2,8 . 例如,Apple可以发布另一个版本的iPad 2硬件并给它机器字符串iPad2,8

import CoreTelephony.framework. 导入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. 但由于我没有任何iPad mini,我不知道iPad mini会打印什么。 Could you let me know? 你能让我知道吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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