Можно ли обнаружить, что приложение iOS работает на iPad mini во время выполнения?

Обнаружение различных аппаратных средств во время выполнения полезно для аналитики (среди прочего, еще более сомнительных целей).

Многим создателям приложений iOS может быть интересно узнать, сколько пользователей испытывает свое приложение на iPad mini (а не просто знать, сколько пользователей испытывает приложение на iPad с разрешением экрана 1024x768), что также было бы интересно).

Существует ли какой-либо публичный API в Cocoa touch/UIKit/ObjC/C, который может быть использован для обнаружения того, что ваше приложение iOS работает на iPad mini во время выполнения? В идеале, этот метод должен различать iPad 2 и iPad mini (которые имеют одинаковое количество пикселей, но различную плотность пикселей).


Сообщение Script: Я понимаю, что многие люди рассмотрят возможность обнаружения iPad mini во время работы плохую идею. Однако, я думаю, что это правильный вопрос с определенным ответом Да или Нет. Ответ, который, по моему мнению, полезен сообществу для ознакомления.

Ответ 1

Ответ в боксе был бы хорош, если бы он не вызывал поведение undefined, и если бы у него не было лишних частей. Один, + [NSString stringWithCString:encoding:] требует строку C, то есть указатель char с нулевым завершением (иначе он, скорее всего, сбрасывает ядро). Кроме того, вам не нужно преобразовать в NSString - так как sysctlbyname() предоставляет вам простую старую строку C (без терминатора NUL, конечно), вы можете напрямую использовать strcmp() для сохранения нескольких десятков циклов процессора

#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);

Изменить: теперь этот ответ также исправлен.

Ответ 2

Используйте sysctlbyname для получения строки платформы, а затем сравните ее с префиксными строками IPSW, указанными здесь. Похоже, что единственный известный в настоящее время iPad Mini - iPad2,5.

Пример:

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);

Ответ 3

Нет надежного и надежного способа определения плотности пикселов iPad. Другие ответы предлагают посмотреть строку hw.machine. Но мы не знаем (с того момента, как я пишу это), какие строки будут для мини-сотовых моделей iPad (хотя мы можем сделать обоснованное предположение: iPad2,6, вероятно, будет иметь GSM и iPad2,7, вероятно, будет иметь CDMA).

Хорошо проверить строку hw.machine для аналитики. Но это опасно, если это повлияет на пользовательский интерфейс приложения, потому что даже строка iPad2,5 для текущего iPad mini может быть изменена.

Когда вышел iPad 2, строка модели wifi была iPad2,1. Позже (когда они выпустили iPad 3), они изменили аппаратное обеспечение iPad 2 и изменили строку hw.machine на iPad2,4, но они все еще назвал его iPad 2. То же самое может произойти с iPad mini - или даже с iPad 2 снова! Например, Apple может выпускать еще одну версию аппаратного обеспечения iPad 2 и дать ей машинную строку iPad2,8.

Ответ 4

импортировать CoreTelephony.framework. Попробуйте это на устройстве

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

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

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

Это решает мою цель до сих пор. Но поскольку у меня нет iPad mini, я не знаю, что он собирается напечатать для iPad mini. Не могли бы вы сообщить мне?