Во время создания проекта (FileONewO Project), после выбора шаблона проекта, на экране, в котором вводится имя проекта, появляется раскрывающийся список Devices, содержащий пункты iPad, iPhone или Universal.

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

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

Выбор пункта в раскрывающемся списке Devices также влияет на настройку сборки Targeted Device Family.

iPad

Приложение будет выполняться только на iPad.

iPhone

Приложение будет работать на iPhone или iPod touch; оно также может работать на iPad, но не как естественное приложение для iPad (оно выполняется в уменьшенном масштабируемом окне, которое я называю iPhone Emulator, компания Apple иногда называет это “режимом совместимости”).

IPhone/IPad

Приложение будет естественным образом выполняться на обоих типах устройств и должно быть структурировано как универсальное.

 

Если вы обновляете приложение для системы iOS 7 и хотите, чтобы оно естественным образом выполнялось на 64-битовом устройстве, измените настройку сборки Architectures для целевого приложения на “Standard architectures (including 64-bit)”. Две дополнительные настройки уровня проекта определяют, какая система установлена на вашем устройстве.

 

Base SDK

Новейшая система, в которой может работать ваше приложение. Когда я писал книгу, в среде Xcode 5.0 существовало только две возможности: IOS 7.0 и Latest iOS (IOS 7.0). Они выглядят одинахово, но второй выбор лучше (и он предлагается по умолчанию для нового проекта). Если вы обновите среду Xcode для разработки приложения, которое будет работать в последующих версиях операционной системы, любые существующие проекты, которые уже настроены на Latest IOS, будут использовать этот новейший комплект SDK в качестве своего комплекта Base SDK автоматически, без изменения настройки Base SDK.

 

IOS Deployment Target

Самой ранней операционной системой, на которой может работать ваше приложение в среде Xcode 5.0, может быть любая система iOS, вплоть до версии 4.3. Для того чтобы легко изменить настройку проекта IOS Deployment Target, откройте проект и перейдите на вкладку Info, а затем выберите пункт в раскрывающемся списке IOS Deployment Target. (Для того чтобы легко изменить настройку цели IOS Deployment Target, откройте цель, перейдите на вкладку General и выберите пункт в раскрывающемся списке Deployment Target. Однако, как правило, эту настройку изменяют на уровне проекта и предоставляют цели автоматически адаптировать настройки проекта.)

Написать приложение, в котором настройка Deployment Target отличалась бы от Base SDK, довольно сложно. С этим связаны две основные проблемы.

 

Не поддерживаемые функциональные возможности

В каждой новой системе компания Apple добавляет новые функциональные возможности. Среда Xcode охотно позволяет вам компилировать любые функции из комплекта Base SDK, даже если их нет в системе, заданной настройкой Deployment Target. Но ваше приложение даст сбой, если система выполнения приложений обнаружит функцию, не поддерживаемую системой, в которой приложение в действительности выполняется. Таким образом, если вы установили настройку проекта Deployment Target равной iOS 6, ваш проект будет скомпилирован и приложение будет работать в системе iOS 6, даже если она содержит функциональные свойства, доступные только в системе iOS 7, но ваше приложение даст сбой в системе iOS 6, если одна из таких функций будет действительно обнаружена.

 

Модифицированное поведение

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

Таким образом, обратная совместимость может потребовать написать дополнительный код — иначе говоря, такой код, в котором в разных системах выполняются разные наборы инструкций. Но дело не только в коде. Проект может содержать другие источники, например nib-файл, не совместимые с более ранними системами. (Например, nib-файл, использующий автоматическую разметку, вызовет сбой при загрузке в системе 10S 5.1 или более ранней, потому что автоматическая разметка использует класс NSLayoutConstraint, которого раньше не было.)

Даже если вы не стремитесь к обратной совместимости, вам все равно, возможно, придется решать проблемы, связанные с условным кодом, если вы хотите написать универсальное приложение. Несмотря на то что вы, возможно, стремитесь сократить дублирование общего кода для версий приложения, предназначенных для устройств iPhone и iPad, какой-то код придется написать отдельно, потому что ваше приложение должно работать иначе на разных устройствах. Как я уже говорил, вы не можете открыть всплывающее окно на iPhone; сложности могут значительно возрасти, потому что интерфейсы могут сильно отличаться и работать совершенно по-разному — нажатие на ячейке таблицы на устройстве IPhone может активизировать новый экран, а на более крупном устройстве iPad это может просто изменить часть экрана.

Разные программируемые устройства могут по-разному интерпретировать код в зависимости от системы или типа устройства, на котором выполняется приложение; таким образом, существует возможность предотвратить сбой или неправильную работу кода, используя настройки среды выполнения приложений.

 

Явное тестирование среды

Класс UIDevice позволяет запрашивать текущее устройство (currentDevice), чтобы выяснить версию (systemVersion) и тип (userlnterfaceldiom) его системы.

Для примера создайте проект Universal на основе шаблона Master-Detall Application и загляните в файл AppDelegate.т. Вы увидите код в методе application:didFinish LaunchingWithOptions:, который конфигурирует начальный интерфейс по-разному в зависимости от типа устройства, на котором выполняется приложение.

 

Суффикс имени ключа Info.plist

Настройки Info.plist можно конфигурировать только на один тип устройства, добавляя суффикс ~ iphone или ~ipad к имени ключа. Если суффикс уже есть, эта настройка заменяет общую настройку (без суффикса) на подходящее устройство.

 

Откройте проект Universal, основанный на шаблоне Master-Detall Application. Вы увидите, что файл Inf о.plist содержит два набора настроек “Supported Interface orientations”: общий набор (UlSupportedlnterfaceOrientations) и набор настроек только для устройства iPad, который заменяет общий набор, когда приложение выполняется на iPad (UISup portedlnterfaceOrientations-ipad).

Аналогично проект Universal, основанный на шаблоне Master-Detail Application, содержит две раскадровки: одну, обеспечивающую интерфейс для iPhone, и другую для iPad. Выбор между ними осуществляет настройка Info.plist “Main storyboard file base name”, которая появляется дважды: в общем случае (UIMainStoryboardFile) и только для iPad (UIMainStoryboardFile-ipad), которая заменяет общую, когда приложение выполняется на устройстве iPad.

 

Суффикс имени ресурса

Многие вызовы функций, загружающих ресурсы по имени из комплекта приложения, подчиняются тем же правилам использования суффиксов в именах, что и ключи в файле Info .plist, автоматически выбирая альтернативные ресурсы, имена которых до расширения заканчиваются суффиксом ~ iphone или ~ipad , соответствующим типу устройства. Например, если задать имя изображения 0"linen.png", то метод imageNamed: в классе Ullmage загрузит изображение linen-ipad.png, если он найдет его и приложение работает на устройстве iPad.

(Однако в среде Xcode 5 есть новшество: если изображение находится в каталоге ресурсов, соглашение об именах можно не выполнять. Так как используемое изображение определяется его местом в этом каталоге. Выберите множество изображений в этом каталоге и пункт Device Specific в раскрывающемся списке Devices в окне инспектора атрибутов для создания разных версий изображения для устройств iPhone и iPad. Это одна из многих причин использования каталогов ресурсов!)

 

Слабо связанные каркасы

Если ваше приложение связано с каркасом и пытается работать в системе, в которой этого каркаса нет, то во время его выполнения произойдет сбой. Для решения этой проблемы можно установить необязательную связь с каркасом, изменив пункт Required в листинге на фазе сборки Linked Frameworks and Libraries на Optional. С технической точки зрения это называется слабой связью с каркасом (weak-linking the framework).

(Этот метод работает, даже если вы используете новые модули в среде Xcode 5 (см. главу 6), — но в этом случае вы должны ясно установить слабую связь с требуемым каркасом, сделав так, чтобы его имя появилось в списке Linked Frameworks and Libraries; автоматического способа задать слабую связь не существует.)

 

Проверка существования метода

Существует возможность проверить, существует ли требуемый метод, используя метод respondsToSelector: и вызовы объекта класса

NSObject

if ([UIButton respondsToSelector: Sselector(appearance)]) {

//ok - вызываем метод класса appearance) else (

//не вызываем метод класса appearance

}

Проверка существования класса

Существует возможность проверить, существует ли класс, используя функцию NSClassFromString, которая возвращает nil, если класс не существует. Кроме того, если используется версия Base SDK 5.0 или более поздняя и каркас, которому принадлежит класс, существует или имеет слабую связь с приложением, можно послать этому классу любое сообщение (как классу) и проверить, равен ли результат nil; этот механизм работает, потому что классы, начиная с системы iOS 5, являются слабо связанными.

// считаем, что каркас Core Image является слабо связанным

if ([CIFilter class]) { //ok - можно работать с классом CIFilter

Проверка существования констант и функций

Существует возможность проверить, существует ли имя константы, включая имя функции в языке С, взяв адрес имени и сравнив его с нулем. Например:

if (&UIApplicationWillEnterForegroundNotification) {

// OK - можно ссылаться на UIApplicationWillEnterForegroundNotification


 

 

 

Добавить комментарий