Creating XPC Services

XPC Services API, часть libSystem, обеспечивает легкий механизм для основного межпроцессного взаимодействия, интегрированного с Grand Central Dispatch (GCD) и launchd. API XPC Services позволяет Вам создавать легкие инструменты помощника, названные службами XPC, выполняющими работу от имени Вашего приложения.

Существует две главных причины использовать службы XPC: разделение полномочия и устойчивость.

Устойчивость:

Давайте быть обращенным к нему; приложения иногда отказывают. Мы не хотим, чтобы он произошел, но это делает так или иначе. Часто, определенные части приложения более подвержены катастрофическим отказам, чем другие. Например, устойчивость любого приложения со сменным API по сути во власти авторов плагинов.

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

Разделение полномочия:

Современные приложения все более и более полагаются на недоверяемые данные, такие как веб-страницы, файлы, отправленные по электронной почте, и т.д. Это представляет растущий вектор атаки для вирусов и другого вредоносного программного обеспечения.

С традиционными приложениями, если приложение становится поставившим под угрозу посредством переполнения буфера или другой уязвимости системы обеспечения безопасности, атакующий получает возможность сделать что-либо, что может сделать пользователь. Для смягчения этого риска Mac OS X обеспечивает игру в песочнице — ограничение, какие типы операций процесс может выполнить.

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

Другие механизмы для деления приложения в меньшие части, такой как NSTask и posix_spawn, не позволяйте Вам поместить каждую часть приложения в его собственной песочнице, таким образом, не возможно использовать их для реализации разделения полномочия. Каждая служба XPC имеет свою собственную песочницу, таким образом, службы XPC могут упростить реализовывать надлежащее разделение полномочия.

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

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

Службами XPC управляют launchd, то, которое запускает их по требованию, перезапускает их, если они отказывают, и завершает их (путем отправки SIGKILL) когда они неактивны. Это очевидно для приложения с помощью службы, за исключением случая службы, отказывающей при обработке сообщения, требующего ответа. В этом случае приложение видит, что его соединение XPC стало недопустимым, пока служба не перезапущена launchd. Поскольку служба XPC может быть завершена внезапно в любое время, она должна быть разработана для держаний за минимальное состояние — идеально, служба должна быть абсолютно не сохраняющей состояние, несмотря на то, что это не всегда возможно.

По умолчанию службы XPC выполняются в наиболее ограниченной возможной среде — поигравший в песочнице с минимальным доступом к файловой системе, доступом к сети, и т.д. Подъем полномочий службы базироваться не поддерживается. Далее, служба XPC является частной, и является доступной только главному приложению, содержащему ее.

Выбор API XPC

При начале в Mac OS X v10.8, существует два различных APIs для работы со службами XPC: XPC Services API и NSXPCConnection API.

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

API XPC Services является API на базе С, обеспечивающий основные службы обмена сообщениями между клиентским приложением и помощником службы.

Если приложение и его служба не на основе платформы Основы, API XPC Services рекомендуется при необходимости в совместимости с Mac OS X v10.7, или. NSXPCConnection API рекомендуется для приложений на основе платформы Основы в Mac OS X v10.8 и позже.

API NSXPCConnection

NSXPCConnection API является частью платформы Основы и описан в NSXPCConnection.h заголовочный файл. Это состоит из следующих частей:

  • NSXPCConnection— класс, представляющий канал двунаправленной связи между двумя процессами. У и приложения и помощника службы есть по крайней мере один объект соединения.

  • NSXPCInterface— класс, описывающий ожидаемое программируемое поведение соединения (какие классы могут быть переданы через соединение, какие объекты представлены, и т.д.).

  • NSXPCListener— класс, прислушивающийся к поступлению соединений XPC. Ваш помощник службы должен создать один из них и присвоить его объект делегата, соответствующий NSXPCListenerDelegate протокол.

  • NSXPCListenerEndpoint— класс, однозначно определяющий NSXPCListener экземпляр и может быть отправлен в удаленное использование процесса NSXPCConnection. Это позволяет процессу создавать канал прямой связи между двумя другими процессами, иначе не видевшими друг друга.

Кроме того, заголовок содержит несколько констант, описанных в Ссылке Констант NSXPCConnection.

Службы XPC API

XPC Services (на базе С) API состоит из двух основных частей:

  • xpc.h— APIs для создания и управления объектами списка свойств и APIs, который демоны используют для ответа на сообщения.

    Поскольку этот API на libSystem уровне, он не может зависеть от Базовой Основы. Кроме того, не все типы CF могут быть с готовностью совместно использованы через границы процесса. XPC поддерживает типы соединения, такие как дескрипторы файлов в его графах объектов, не поддерживающихся CFPropertyList, потому что это было разработано как персистентный формат хранения, тогда как XPC был разработан как формат IPC. По этим причинам API XPC использует его собственный контейнер, поддерживающий только примитивы, которые практичны для переноса через границы процесса.

    Некоторые высокоуровневые типы могут быть переданы через соединение XPC, несмотря на то, что они не появляются в xpc.h заголовочный файл (потому что ссылка на высокоуровневые платформы от libSystem была бы нарушением разделения на уровни). Например, IOSurfaceCreateXPCObject и IOSurfaceLookupFromXPCObject функции позволяют Вам передавать объект IOSurface между службой XPC, делающей получение и главное приложение.

  • connection.h— APIs для соединения со службой XPC. Эта служба является специальным пакетом помощника, встроенным в Ваш комплект приложений.

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

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

Создание службы

Служба XPC является пакетом в Contents/XPCServices каталог пакета главного приложения; пакет службы XPC содержит Info.plist файл, исполнимая программа и любые ресурсы необходимы службе. Служба XPC указывает, какую функцию вызвать, когда служба получает сообщения путем вызова xpc_main(3) Mac OS X Developer Tools Manual Page от main функция.

Для создания службы XPC в XCode сделайте следующее:

  1. Добавьте новую цель к своему проекту, с помощью шаблона XPC Service.

  2. Добавьте фазу Файлов Копии к настройкам сборки своего приложения, копирующую службу XPC в Contents/XPCServices каталог пакета главного приложения.

  3. Добавьте зависимость к настройкам сборки своего приложения, чтобы указать, что она зависит от пакета службы XPC.

  4. Если Вы пишете низкоуровневую службу XPC (на базе С), реализуете минимальное main функционируйте для регистрации обработчика событий, как показано в следующем листинге кода. Замена my_event_handler с именем Вашей функции обработчика событий.

    int main(int argc, const char *argv[]) {
        xpc_main(my_event_handler);
     
        // The xpc_main() function never returns.
        exit(EXIT_FAILURE);
    }

    Если Вы пишете высокоуровневое использование службы (Objective-C-based) NSXPCConnection, сначала создайте делегата соединения класс, соответствующий NSXPCListenerDelegate протокол. Затем реализуйте минимальное main функция, создающая и конфигурирующая объект прослушивателя, как показано в следующем листинге кода.

    int main(int argc, const char *argv[]) {
        MyDelegateClass *myDelegate = ...
        NSXPCListener *listener =
            [NSXPCListener serviceListener];
     
        listener.delegate = myDelegate;
        [listener resume];
     
        // The resume method never returns.
        exit(EXIT_FAILURE);
    }

    Подробные данные этого класса описаны далее в Использовании Службы.

  5. Добавьте надлежащие пары ключ/значение к помощнику Info.plist сказать launchd имя службы. Они описаны в Ключах Списка свойств Службы XPC.

Используя службу

Путем Вы используете службу XPC, зависит от того, работаете ли Вы с API C (XPC Services) или Objective C API (NSXPCConnection).

Используя Objective C NSXPCConnection API

Objective C NSXPCConnection API обеспечивает высокоуровневый интерфейс вызова удаленной процедуры, позволяющий Вам вызывать методы на объектах в одном процессе от другого процесса (обычно приложение, вызывая метод в службе XPC). NSXPCConnection API автоматически сериализирует структуры данных и объекты для передачи и десериализовывает их на другом конце. В результате вызов метода на удаленном объекте ведет себя во многом как вызов метода на локальном объекте.

Использовать NSXPCConnection API, необходимо создать следующее:

Рисунок 4-1 показывает, как совмещаются эти части.

Рисунок 4-1  архитектура NSXPC

В некоторых случаях Вы, возможно, должны далее настроить протокол к whitelist дополнительным классам для использования в параметрах набора или проксировать определенные объекты вместо того, чтобы копировать их. Это описано далее в Работе с Пользовательскими Классами.

Полная архитектура

При работе с NSXPCConnection- основанные вспомогательные приложения, и главное приложение и помощник имеют экземпляр NSXPCConnection. Главное приложение создает свой объект соединения сам, заставляющий помощника запускаться. Когда соединение установлено, метод делегата в помощнике передается его объект соединения. Это проиллюстрировано на рисунке 4-1.

Каждый NSXPCConnection объект обеспечивает три главных особенности:

  • exportedInterface свойство, описывающее методы, которые должны быть сделаны доступными для противоположной стороны соединения.

  • exportedObject свойство, содержащее локальный объект для обработки вызовов метода, входящих с другой стороны соединения.

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

Когда главное приложение вызывает метод на объекте прокси, служба XPC NSXPCConnection вызовы объектов, которые метод на объекте сохранил в exportedObject свойство.

Точно так же, если служба XPC получает объект прокси и вызывает метод на том объекте, главное приложение NSXPCConnection вызовы объектов, которые метод на объекте сохранил в exportedObject свойство.

Разработка интерфейса

NSXPCConnection API использует в своих интересах протоколы Objective C для определения программируемого интерфейса между вызывающим приложением и службой. Любой метод экземпляра, который Вы хотите вызвать от противоположной стороны соединения, должен быть явно определен в формальном протоколе. Например:

@protocol FeedMeACookie
    - (void)feedMeACookie: (Cookie *)cookie;
@end

Поскольку коммуникация по XPC является асинхронной, все методы в протоколе должны иметь тип возврата void. Если необходимо возвратить данные, можно определить блок ответа как это:

@protocol FeedMeAWatermelon
    - (void)feedMeAWatermelon: (Watermelon *)watermelon
        reply:(void (^)(Rind *))reply;
@end

Метод может иметь только один блок ответа. Однако, потому что соединения двунаправлены, помощник службы XPC может также ответить вызывающими методами в интерфейсе, предоставленном главным приложением при желании.

Каждый метод должен иметь тип возврата void, и все параметры к методам или блокам ответа должны быть также:

  • Арифметические типы (int, char, float, double, uint64_t, NSUInteger, и т.д.)

  • BOOL

  • Струны до

  • C структуры и массивы, содержащие только типы, упоминается выше

  • Objective C возражает что реализация NSSecureCoding протокол.

Соединение с и Используя интерфейс

Как только Вы определили протокол, необходимо создать интерфейсный объект, описывающий его. Чтобы сделать это, вызовите interfaceWithProtocol: метод на NSXPCInterface класс. Например:

NSXPCInterface *myCookieInterface =
    [NSXPCInterface interfaceWithProtocol:
        @protocol(FeedMeACookie)];

Как только Вы создали интерфейсный объект в главном приложении, необходимо сконфигурировать соединение с ним путем вызова initWithServiceName: метод. Например:

NSXPCConnection *myConnection =    [[NSXPCConnection alloc]
     initWithServiceName:@"com.example.monster"];
myConnection.remoteObjectInterface = myCookieInterface;
[myConnection resume];

Рисунок 4-2 показывает основные шаги в этом процессе. Обратите внимание на то, что только первые четыре шага описаны в этом разделе.

Рисунок 4-2  процесс соединения NSXPC

В этой точке главное приложение может вызвать remoteObjectProxy или remoteObjectProxyWithErrorHandler: методы на myConnection объект получить объект прокси. Этот объект действует как прокси для объекта, который служба XPC установила как ее экспортируемый объект (путем установки exportedObject свойство). Этот объект должен соответствовать протоколу, определенному remoteObjectInterface свойство.

Когда Ваше приложение вызывает метод на объекте прокси, соответствующий метод вызывают на экспортируемом объекте в службе XPC. Когда вызовы метода службы блок ответа, значения параметров сериализированы и переданы обратно приложению, где значения параметров десериализовываются и передаются блоку ответа. (Блок ответа выполняется в адресном пространстве приложения.)

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

Как показано на рисунке 4-2, когда NSXPCConnection- основанный помощник получает первое сообщение от соединения, делегат слушателя listener:shouldAcceptNewConnection: метод вызывают с объектом прослушивателя и объектом соединения. Этот метод позволяет Вам решить, принять ли соединение или нет; это должно возвратиться YES принять соединение или NO отказаться от соединения.

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

  • exportedInterface— интерфейсный объект, описывающий протокол для объекта, который Вы хотите экспортировать. (Создающий этот объект был описан ранее в Соединении с и Используя Интерфейс.)

  • exportedObject— локальный объект (обычно в помощнике), которому должны быть поставлены вызовы метода удаленного клиента. Каждый раз, когда противоположный конец соединения (обычно в приложении) вызывает метод на объекте соединения прокси, соответствующий метод вызывают на объекте, указанном exportedObject свойство.

После установки тех свойств это должно вызвать объект соединения resume метод перед возвратом YES. Несмотря на то, что делегат может задержать вызов resume, соединение не получит сообщений, пока оно не сделает так.

Отправка сообщений

Отправка сообщений с NSXPC так же проста как создание вызова метода. Например, учитывая интерфейс myCookieInterface (описанный в предыдущих разделах) на объекте соединения XPC myConnection, можно вызвать feedMeACookie метод как это:

Cookie *myCookie = ...
 
[[myConnection remoteObjectProxy] feedMeACookie: myCookie];

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

Ошибки из-за неправильного обращения

В дополнение к любым методам обработки ошибок, определенным для задачи данного помощника, и служба XPC и главное приложение должны также обеспечить следующие блоки обработчика ошибок XPC:

  • Когда процесс на другом конце соединения разрушил или иначе закрыл свое соединение, обработчик прерывания — вызвал.

    Объект локального соединения обычно все еще допустим — любой будущий вызов автоматически породит новый экземпляр помощника, если не будет невозможно сделать так — но Вы, возможно, должны сбросить любое состояние, которое иначе сохранил бы помощник.

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

  • Обработчик аннулирования — вызвал, когда лишить законной силы метод вызывают или когда не мог быть запущен помощник XPC. Когда этот обработчик вызывают, объект локального соединения больше не действителен и должен быть воссоздан.

    Это всегда - последний обработчик, обратился к объекту соединения. Когда этот блок вызывают, объект соединения был разъединен. Не возможно отправить дальнейшие сообщения на соединении в той точке, ли в обработчике или в другое место в Вашем коде.

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

Работа с пользовательскими классами

NSXPCConnection класс ограничивает, какие объекты могут быть переданы по соединению. По умолчанию это позволяет только известный - безопасные классы — классы набора Основы, NSString, и т.д. Можно идентифицировать эти классы тем, соответствуют ли они NSSecureCoding протокол.

Только классы, соответствующие этому протоколу, могут быть отправлены в NSXPCConnection- основанный помощник. Если необходимо передать собственные классы как параметры, необходимо гарантировать, чтобы они соответствовали NSSecureCoding протокол, как описано ниже.

Однако это не всегда достаточно. Необходимо выполнить дополнительную работу в двух ситуациях:

  • Если Вы передаете объект в наборе (словарь, массив, и т.д.).

  • Если необходимо передать объект по доверенности вместо того, чтобы копировать объект.

Все три случая описаны в следующих разделах.

Приспосабливание NSSecureCoding

Все объекты, переданные по соединению NSXPC, должны соответствовать NSSecureCoding. чтобы сделать это, Ваш класс должен сделать следующее:

  • Объявите поддержку безопасного кодирования. Переопределите supportsSecureCoding метод, и заставляет его возвратиться YES.

  • Декодируйте экземпляры singleton-класса безопасно. Если класс переопределяет initWithCoder: метод, при декодировании любой переменной экземпляра, свойства или другого значения, содержащего объект класса ненабора (включая пользовательские классы) всегда, использует decodeObjectOfClass:forKey: гарантировать, что данные имеют ожидаемый тип.

  • Декодируйте классы набора безопасно. Любой класс ненабора, содержащий экземпляры классов набора, должен переопределить initWithCoder: метод. В том методе, при декодировании объекта коллекции или объектов, всегда использование decodeObjectOfClasses:forKey: и обеспечьте список любых объектов, которые могут появиться в наборе.

При генерации списка классов для разрешения в декодируемом классе набора необходимо знать о двух вещах.

Во-первых, классы набора Apple не автоматически whitelisted decodeObjectOfClasses:forKey: метод, таким образом, необходимо включать их явно в массив типов классов.

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

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

Рисунок 4-3 показывает некоторые примеры того, когда белый список требуется и показывает, когда классы должны обеспечить переопределенный initWithCoder: методы.

  Белый список рисунка 4-3 и безопасные примеры кодирования
Белый список класс для использования в контейнерах

Большую часть времени пользовательские классы прошли через параметры метода, может быть автоматически whitelisted основан на подписи метода. Однако, когда метод указывает класс набора (NSArray, NSDictionary, и т.д.) как тип параметра, компилятор не имеет никакого способа определить, каким классам нужно позволить появиться в том контейнере. Поэтому, если Ваши методы берут экземпляры класса набора в качестве параметров, Вы должны явно whitelist любые классы, которые могут появиться в тех контейнерах.

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

Вы должны whitelist только классы, которые могут быть элементами любых объектов коллекции верхнего уровня. Если Вы, whitelist классы на верхнем уровне излишне, тем объектам позволяют появиться в объектах коллекции верхнего уровня, который не является тем, что Вы хотите. В частности:

  • Предоставленные Apple классы, поддерживающие сериализацию списка свойств (такую как другие классы набора) автоматически whitelisted для Вас. Это никогда не необходимо для whitelist эти классы на верхнем уровне.

    Для самого актуального списка классов, поддерживаемых сериализацией списка свойств, считайте Списки свойств Сериализации в Руководстве по программированию Архивов и Сериализации.

  • Не делайте whitelist пользовательских классов, если им позволяют только внутренние экземпляры других пользовательских классов. Если класс включения правильно соответствует NSSecureCoding, такой белый список не требуется. Для получения дополнительной информации считайте Приспосабливание NSSecureCoding.

Например, предположите, что у Вас есть следующий класс и протокол:

@interface FrenchFry
...
@end
 
@protocol FeedMeABurgerAndFries
    - (void)feedMeFries: (NSArray *)pommesFrites;
    - (void)feedMeABurger: (Burger *)aBurger;
@end

Принятие pommesFrites массив является массивом FrenchFry объекты (поскольку имя подразумевает), Вы были бы whitelist массив FrenchFry объекты следующим образом:

// Create the interface
NSXPCInterface *myBurgerInterface =
    [NSXPCInterface interfaceWithProtocol:
        @protocol(FeedMeABurgerAndFries)];
 
// Create a set containing the allowed
// classes.
NSSet *expectedClasses =
    [NSSet setWithObjects:[NSArray class], [FrenchFry class], nil];
 
[myBurgerInterface
      setClasses: expectedClasses
     forSelector: @selector(feedMeFries:)
   argumentIndex: 0  // the first parameter
         ofReply: NO // in the method itself.
];

Первый параметр к методу является параметром 0, сопровождаемый параметром 1, и т.д.

В этом случае, значение NO передается для ofReply параметр, потому что этот код изменяет whitelist для одного из параметров самого метода. Если Вы - белый список класс для параметра блока ответа метода, передачи YES вместо этого.

Передача объекта по доверенности

Большую часть времени это целесообразно копировать объекты и отправлять их другой стороне соединения. Передача объектов копированием является самым прямым способом использовать NSXPC и должна использоваться по мере возможности.

Однако копирование объектов не всегда желательно. В частности:

  • Если необходимо совместно использовать единственный экземпляр данных между клиентским приложением и помощником, необходимо передать объекты по доверенности.

  • Если объект должен вызвать методы на других объектах в Вашем приложении, которое Вы не можете или не хотеть передавать через соединение (такое как объекты пользовательского интерфейса), то необходимо передать объект по доверенности — любой вызывающая сторона, вызываемый (где возможный), или релейный объект, который Вы создаете в частности с этой целью.

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

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

Предположим, например, что у Вас есть класс, соответствующий следующему протоколу:

@protocol FeedSomeone
    - (void)feedSomeone:
        (id <FeedMeACookie>)someone;
@end
 
...
 
NSXPCInterface *myFeedingInterface =
    [NSXPCInterface interfaceWithProtocol:
        @protocol(FeedSomeone)];

Если бы Вы хотите передать первый параметр тому методу по доверенности, Вы сконфигурировали бы интерфейс как это:

// Create an interface object that describes
// the protocol for the object you want to
// pass by proxy.
NSXPCInterface *myCookieInterface =
    [NSXPCInterface interfaceWithProtocol:
        @protocol(FeedMeACookie)];
 
// Create an object of a class that
// conforms to the FeedMeACookie protocol
Monster *myMonster = ...
 
[myFeedingInterface
     setInterface: myCookieInterface
      forSelector: @selector(sendOtherProxy:)
    argumentIndex: 0  // the first parameter of
          ofReply: NO // the feedSomeone: method
];

Первый параметр к методу является параметром 0, сопровождаемый параметром 1, и т.д.

В этом случае, значение NO передается для ofReply параметр, потому что этот код изменяет whitelist для одного из параметров самого метода. Если Вы - белый список класс для параметра блока ответа метода, передачи YES вместо этого.

Используя C XPC службы API

Типичный процесс выполнения программы следующие:

  1. Приложение вызывает xpc_connection_create(3) Mac OS X Developer Tools Manual Page создать объект соединения XPC.

  2. Приложение вызывает некоторую комбинацию xpc_connection_set_event_handler(3) Mac OS X Developer Tools Manual Page или xpc_connection_set_target_queue(3) Mac OS X Developer Tools Manual Page по мере необходимости сконфигурировать параметры соединения до фактического соединения со службой.

  3. Вызовы приложения xpc_connection_resume(3) Mac OS X Developer Tools Manual Page начать коммуникацию.

  4. Приложение отправляет сообщения в использование службы xpc_connection_send_message(3) Mac OS X Developer Tools Manual Page, xpc_connection_send_message_with_reply(3) Mac OS X Developer Tools Manual Page, или xpc_connection_send_message_with_reply_sync(3) Mac OS X Developer Tools Manual Page.

  5. Когда Вы отправляете первое сообщение, launchd демон ищет Ваш комплект приложений пакет службы чей CFBundleIdentifier оцените соответствует указанное имя, затем запускает того демона службы XPC по требованию.

  6. Функция обработчика событий (указанный в службе Info.plist файл), вызывается с сообщением. Функция обработчика событий работает на очереди, имя которой является именем службы XPC.

  7. Если исходное сообщение было отправлено с помощью xpc_connection_send_message_with_reply(3) Mac OS X Developer Tools Manual Page или xpc_connection_send_message_with_reply_sync(3) Mac OS X Developer Tools Manual Page, служба должна ответить использованию xpc_dictionary_create_reply(3) Mac OS X Developer Tools Manual Page, тогда использование xpc_dictionary_get_remote_connection(3) Mac OS X Developer Tools Manual Page получить соединение клиента и xpc_connection_send_message(3) Mac OS X Developer Tools Manual Page, xpc_connection_send_message_with_reply(3) Mac OS X Developer Tools Manual Page, или xpc_connection_send_message_with_reply_sync(3) Mac OS X Developer Tools Manual Page передавать словарь ответа обратно приложению.

    Служба может также отправить сообщение непосредственно в приложение с xpc_connection_send_message(3) Mac OS X Developer Tools Manual Page.

  8. Если ответ был отправлен службой, обработчик, связанный с предыдущим сообщением, вызывают после получения ответа. Ответ может быть помещен на различную очередь, чем та, используемая для входящих сообщений. Никакое последовательное отношение не гарантируется между ответными сообщениями и неответными сообщениями.

  9. Если ошибка происходит (такие как закрытие соединения), обработчик событий соединения (установленный предыдущим вызовом в xpc_connection_set_event_handler(3) Mac OS X Developer Tools Manual Page) вызывается с надлежащей ошибкой, как (без определенного порядка) обработчики для любых выдающихся сообщений, все еще ждущих ответов.

  10. В любое время приложение может вызвать xpc_connection_suspend(3) Mac OS X Developer Tools Manual Page когда это должно приостановить обратные вызовы от службы. Все приостанавливают вызовы, должен быть сбалансирован с вызовов резюме. Не безопасно выпустить последнюю ссылку на приостановленное соединение.

  11. В конечном счете, вызовы приложения xpc_connection_cancel(3) Mac OS X Developer Tools Manual Page завершать соединение.

    Примечание: Любая сторона соединения может вызвать xpc_connection_cancel(3) Mac OS X Developer Tools Manual Page. Нет никакого функционального различия между приложением, отменяющим соединение и службой, отменяющей соединение.

Ключи списка свойств службы XPC

XPC требует, чтобы Вы указали много специальных пар ключ/значение в Info.plist файл в пакете помощника службы. Эти ключи упоминаются ниже.

CFBundleIdentifier

Строка. Имя службы в стиле обратного DNS (например, com.example.myapp.myservice). (Это значение заполнено в шаблоном XPC Service.)

CFBundlePackageType

Строка. Значение должно быть XPC! идентифицировать пакет как службу XPC. (Это значение заполнено в шаблоном XPC Service.)

XPCService

Словарь. Содержит следующие ключи:

Ключ

Значение

EnvironmentVariables

Словарь. Переменные, установленные в среде службы.

JoinExistingSession

Булевская переменная. Указывает, что Ваша служба работает в том же сеансе безопасности как вызывающая сторона.

Значение по умолчанию False, который указывает, что служба выполняется в новом сеансе безопасности.

Установите значение в True если служба должна получить доступ к цепочке для ключей пользователя, области монтажа, или другим ресурсам на сеанс и службам.

RunLoopType

Строка. Указывает тип выполненного цикла, используемого для службы. Значение по умолчанию dispatch_main, который использует dispatch_main(3) Mac OS X Developer Tools Manual Page функционируйте для установки стиля GCD выполненный цикл. Другое поддерживаемое значение NSRunLoop, который использует NSRunLoop класс для установки цикла выполнения.