Using Services
Файл пера по умолчанию, создаваемый для новых приложений Какао, содержит меню Services в меню приложения, таким образом, нет ничего иного, что необходимо сделать для рвения со средством Служб; Ваше приложение автоматически имеет доступ ко всем надлежащим услугам, предоставленным другими приложениями. Если необходимо создать меню программно, Вы просто определяете NSMenu
возразите, что Вы хотите как свое меню Services с setServicesMenu:
метод NSApplication
.
Процесс
Если Вы разделяете на подклассы NSView
или NSWindow
(или любой другой подкласс NSResponder
), необходимо реализовать его таким образом, что это взаимодействует должным образом со средством Служб. Связь пользовательских представлений или окон в средство Служб влечет за собой следующие шаги:
Регистрация объектов пользовательского интерфейса для служб
Проверка пунктов меню Services для текущего выбора
Отправка текущего выбора к службе
Получение данных от службы для замены текущего выбора
Шаги для использования служб проиллюстрированы на рисунке 1.
Когда чистая служба провайдера вызывается (другими словами, служба без отправляют типы), шаг 3 пропускается. Когда чистая служба процессора вызывается (другими словами, служба без типов возврата), шаг 4 пропускается.
Следующие разделы покрывают каждый из этих шагов. Заключительный раздел, Вызов Service Programmatically, показывает, как вызвать службу в Вашем коде.
Регистрация объектов для служб
Меню Services не содержит каждую услугу, предложенную другими приложениями. Например, в текстовом редакторе услуга для инвертирования растрового изображения бесполезна и не должна быть предложена. То, какие службы появляются в меню Services, определяется по условию типы что объекты в приложении — в частности, NSResponder
объекты — могут отправить и получить через область монтажа.
NSResponder
возразите регистрирует эти типы данных с помощью NSApplication
Метод Objective C registerServicesMenuSendTypes:returnTypes:
. Объекты в платформе AppKit уже делают это для основных текстовых служб, но Вашего пользовательского NSResponder
подкласс должен сделать это для расширения списка. Удобное расположение находится в Вашем подклассе initialize
метод класса, который, как гарантируют, будет вызван ко времени выполнения перед любым другим методом класса. Все типы, используемые экземплярами класса, должны быть зарегистрированы, даже если они не всегда доступны; пункты меню Служб являются или настоящим или не существующие на основе того, что доступно в данный момент, как описано в Пунктах меню Validating Services.
Объект не должен регистрировать те же типы и для отправки и для получения. Например, предположите запись визуального редактора, который может отправить неформатированный и обогащенный текст, но может получить только неформатированный текст. Вот часть метода инициализации для текстового редактора NSView
подкласс:
+ (void)initialize |
{ |
static BOOL initialized = NO; |
/* Make sure code only gets executed once. */ |
if (initialized == YES) return; |
initialized = YES; |
sendTypes = [NSArray arrayWithObjects:NSStringPboardType, |
NSRTFPboardType, nil]; |
returnTypes = [NSArray arrayWithObjects:NSStringPboardType, |
nil]; |
[NSApp registerServicesMenuSendTypes:sendTypes |
returnTypes:returnTypes]; |
} |
Ваш NSResponder
объект может зарегистрировать любой тип данных области монтажа, общедоступный или собственный, распространенный или редкий. Если это обрабатывает открытые и общие типы, конечно, это имеет доступ к большему количеству служб. Для списка стандартных типов данных области монтажа см. Ссылку класса NSPasteboard.
Проверка пунктов меню служб
В то время как Ваше приложение работает, различные типы данных могут быть выбраны и доступны для передачи на области монтажа. Если служба не применяется к типу выбранных данных, его пункт меню должен быть отключен. Чтобы проверить, применяется ли служба, объект приложения отправляет validRequestorForSendType:returnType:
сообщения к Objective C возражают в цепочке респондента, чтобы видеть, есть ли у них данные типа, используемого той службой. В то время как меню Services видимо, этот метод вызывают часто — обычно много раз на событие — чтобы гарантировать, что должным образом включены пункты меню для всех поставщиков услуг: это отправляется за каждой комбинацией, отправляют и возвращают типы, поддерживаемые каждой службой и возможно для многих объектов в цепочке респондента. Поскольку этот метод часто вызывают, это должно быть быстро так, чтобы обработка событий не отставала от действий пользователя.
Следующий пример показывает, как этот метод может быть реализован для объекта, обрабатывающего неформатированный текст:
- (id)validRequestorForSendType:(NSString *)sendType |
returnType:(NSString *)returnType |
{ |
if ([sendType isEqual:NSStringPboardType] && |
[returnType isEqual:NSStringPboardType]) { |
if ([self selection] && [self isEditable]) { |
return self; |
} |
} |
return [super validRequestorForSendType:sendType returnType:returnType]; |
} |
Эта реализация проверяет и обозначенные типы и состояние объекта. Объект является допустимой запрашивающей стороной, если типы отправления и возврата являются неформатированным текстом или просто не указаны, и если объект имеет выбор и доступен для редактирования (когда отправляют и возвращаются, типы даны). Если этот объект не может обработать запрос на обслуживание в своем текущем состоянии, это вызывает реализацию своего суперкласса.
validRequestorForSendType:returnType:
сообщение отправляется вдоль сокращенной цепочки респондента, включая только цепочку респондента для ключевого окна и объекта приложения. Главное окно исключено.
Отправка данных к службе
Когда пользователь выбирает команду меню Services, с цепочкой респондента сверяются validRequestorForSendType:returnType:
. Первый объект, возвращающий значение кроме nil
призван для обработки запроса на обслуживание путем предоставления данных (если кто-либо требуется) с a writeSelectionToPasteboard:types:
сообщение. Можно реализовать этот метод, чтобы предоставить данные сразу или предоставить данные только, когда это фактически требуют. Вот реализация для объекта, сразу пишущего неформатированный текст:
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard |
types:(NSArray *)types |
{ |
NSArray *typesDeclared; |
if ([types containsObject:NSStringPboardType] == NO) { |
return NO; |
} |
typesDeclared = [NSArray arrayWithObject:NSStringPboardType]; |
[pboard declareTypes:typesDeclared owner:nil]; |
return [pboard setString:[self selection] |
forType:NSStringPboardType]; |
} |
Этот метод возвраты YES
если это успешно пишет или объявляет какие-либо данные и NO
если это перестало работать. Если у Вас есть большие объемы данных, или можно предоставить данные во многих форматах, необходимо предоставить данные только по требованию. Вы объявляете доступные типы как выше, но с объектом владельца, реагирующим на сообщение pasteboard:provideDataForType:
. Для получения дополнительной информации см. Ссылку класса NSPasteboard.
Получение данных от службы
После того, как запрашивающая сторона службы пишет данные в область монтажа, это ожидает ответа, поскольку поставщик услуг вызывается для выполнения работы; если служба не возвращает данные, конечно, запрашивающее приложение продолжает работать, и ни одно из следующего не применяется. Поставщик услуг считывает данные из области монтажа, работ над нею, и затем возвращает результат. В этой точке запрашивающая сторона службы отправляется a readSelectionFromPasteboard:
сообщение говоря ему заменить выбор любыми данными возвратилось. Простой текстовый объект может реализовать этот метод следующим образом:
- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard |
{ |
NSArray *types; |
NSString *theText; |
types = [pboard types]; |
if ( [types containsObject:NSStringPboardType] == NO ) { |
return NO; |
} |
theText = [pboard stringForType:NSStringPboardType]; |
[self replaceSelectionWithString:theText]; |
return YES; |
} |
Этот метод возвраты YES
если это успешно считывает данные из области монтажа; иначе, это возвращается NO
.
Вызов службы программно
Хотя пользователь обычно вызывает стандартную службу путем выбора элемента в меню Services, можно вызвать его в коде с помощью этой функции:
BOOL NSPerformService(NSString *serviceItem, NSPasteboard *pboard) |
Эта функция возвраты YES
если успешно выполняется служба; иначе, это возвращается NO
. Имя пункта меню Services (на любом языке) содержится в serviceItem. Это должно быть полное имя службы; например, “Search in Google
.” Параметр pboard содержит данные, которые будут использоваться для службы, и, когда функция возвращается, это содержит данные, возвращенные из службы. Можно тогда сделать с данными, чего Вы желаете.