Как мне подойти к созданию универсального приложения iOS, которое будет включать функции iOS 4, хотя iPad еще не запускает iOS 4?

Я бы хотел создать игру для iPhone и iPad. Таким образом, было бы целесообразно начать этот проект с нуля как универсальное приложение. Тем не менее, iPhone и iPad в настоящее время работают с двумя разными версиями iOS, поскольку iOS 4 пока недоступен для iPad. Есть две функции iOS 4 (GameCenter и iAd), которые я хотел бы поддержать в своей игре.

  • В этом случае, это плохая идея создать этот проект как универсальное приложение?
  • Если нет, каковы некоторые мысли, которые я должен принять во внимание, когда я создаю универсальное приложение, поддерживающее две разные версии iOS?
  • Можно ли сделать ставку на то, что Apple выпустит iOS 4 для iPad осенью, как предполагают?
  • Если да, то в любом случае я могу приступить к созданию этих функций iOS 4 (GameCenter и iAd) в моей версии iPad моей игры?

Большое спасибо за всю вашу мудрость!

EDIT: Я понимаю, что эта проблема связана с управлением рисками. Я знаю о рисках, но меня больше интересуют любые технические соображения, связанные с созданием универсального приложения, когда iOS фрагментируется среди различных устройств iOS.

Ответ 1

Если вы собираетесь создать универсальное приложение, просто запомните следующие два фрагмента кода:

  • Использование классов, только если они доступны на текущем устройстве

    Рассмотрим этот фрагмент кода:

    UILocalNotification* n = [[UILocalNotification alloc] init];
    

    При создании универсального приложения этот код приведет к ошибке выполнения на любом устройстве, на котором установлена ​​версия iOS, которая не знает о классе UILocalNotification.

    Вы по-прежнему можете поддерживать UILocalNotification в своем коде, сохраняя обратную совместимость, используя следующий фрагмент кода:

    Class notificationClass = NSClassFromString(@"UILocalNotification");
    if (notificationClass) {
      UILocalNotification* n = [[notificationClass alloc] init];
    }
    

    Этот метод позволяет использовать классы, которые недоступны в некоторых версиях ОС на устройствах, поддерживающих классы.

  • Использование методов только в том случае, если они доступны на текущем устройстве

    Предположим, вы хотели бы сделать следующее:

    [[UIApplication sharedApplication] scheduleLocalNotification:n];
    

    Используйте следующий фрагмент кода для условного вызова метода в случае, если он доступен на текущем устройстве:

    if ([UIApplication instancesRespondToSelector:@selector(scheduleLocalNotification:)]) {
      [[UIApplication sharedApplication] scheduleLocalNotification:n];
    }
    

Эти два метода - это, вероятно, единственное, что вам нужно знать, чтобы создать универсальное приложение. Условно выполняйте свой код в зависимости от возможностей устройства, и вы должны быть в порядке.

Сказав это, вам все равно нужно учитывать, что iPad, вероятно, будет использовать другой интерфейс, чем ваш iPhone. И, к сожалению, вы не сможете протестировать свой iPad-интерфейс с функциями iOS 4, пока они не станут доступны на iPad. Но это не должно быть слишком большой проблемой: если вы используете [[UIDevice currentDevice] userInterfaceIdiom], чтобы проверить, работает ли вы на iPad, вы можете запретить вашему универсальному приложению выполнять код, который еще не имеет интерфейса для iPad. Когда Apple выпустит iOS 4 для iPads, вы можете реализовать пользовательский интерфейс, удалить эту проверку и выпустить обновление в хранилище.

Ответ 2

Вам нужно сделать две вещи:

  • Слабая связь любых фреймворков, которые присутствуют в 3.2 SDK.
  • Записывать тесты времени выполнения для любых API, которые являются новыми для iOS 4.

Чтобы сделать первый, щелкните правой кнопкой мыши по вашей цели и выберите "Получить информацию". Фреймворки перечислены в инспекторе (на вкладке "Общие" ) с раскрывающимся списком рядом с ними, который позволит вам выбрать ссылку "Слабый". Это гарантирует, что приложение все равно будет работать, если рамки нет.

Чтобы сделать второе, вы можете сделать что-то вроде следующего, чтобы протестировать новую анимацию на основе блоков в iOS 4:

if ([UIView respondsToSelector:@selector(animateWithDuration:animations:)]) {
    // Your awesome animation code here
} else {
    // Your almost-as-awesome, non-block-based animation code here.
}

Используя интроспективные методы, такие как -respondsToSelector:, вы можете избежать вызова того, что поддерживает текущая ОС.

Обратите внимание, что если вы хотите поддерживать iPhone OS 3.0, эти же правила будут применяться.

Наконец, также возможно, хотя и не рекомендуется, сделать это так:

#ifdef __IPHONE_4_0
    // Your iOS 4.0-compatible code here
#elif defined(__IPHONE_3_2)
    // Your iPhone OS 3.2-compatible code here
#elif defined(__IPHONE_3_0)
    // Your iPhone OS 3.0-compatible code here
#endif

Почему это не рекомендуется? Простой: будет скомпилирован только код для версии iOS с наивысшим номером. iPhone app arent скомпилирован отдельно для отдельных версий iOS, поэтому чтобы это действительно работало, вам пришлось бы выпускать несколько версий приложения.

Ответ 4

Это вопрос, который связан с управлением риском. Риски включают:

  • Apple не выпускает ожидаемые "Унифицированная 4.1" ОС в пределах требуемый таймфрейм
  • ОС выпущена вовремя для вашего потребностей, но один или оба GameCenter или iAds не включены.
  • GameCenter и/или iAds включены, но они не соответствуют точному API вы ожидали
  • API-интерфейсы - это то, что вы ожидали, но они багги, поскольку это первый версия на iPad
  • и т.д...

Только вы можете определить, на каком уровне каждого риска вам будет комфортно, насколько вероятен ваш риск, если вы можете смягчить каждый риск, и каковы будут затраты на любую из этих проблем на этом пути.