Вызов методов Objective C от JavaScript

Веб-возможности сценариев WebKit разрешают Вам получать доступ к свойствам Objective-C и методам Objective C вызова от среды сценариев JavaScript.

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

Как использовать Objective C в JavaScript

WebScripting неофициальный протокол, определенный в WebScriptObject.h, определяет методы, которые можно реализовать в классах Objective C для представления их интерфейсов среде сценариев, таких как JavaScript. Методы и свойства могут оба быть представлены. Для создания метода допустимым для экспорта необходимо гарантировать, что его тип возврата и все его параметры являются объектами Objective C или типами исходных данных как int и float. Структуры и не объектные указатели не будут переданы JavaScript.

Аргумент метода и типы возврата преобразовываются в надлежащие типы для среды сценариев. Например:

Экземпляры всех других классов обернуты прежде чем быть переданным сценарию и развернуты, когда они возвращаются к Objective C.

Как исключение, массивы JavaScript не могут быть чисто отображены на NSArray объекты, потому что они - гибрид между численно-индексным-массивом и ассоциативным массивом. Для предотвращения потери данных во время отображения необходимо вместо этого использовать webScriptValueAtIndex: и setWebScriptValueAtIndex:value: методы.

Демонстрационный класс Objective C

Давайте смотреть на демонстрационный класс. В этом случае мы создадим класс адресной книги Objective C и представим его JavaScript. Давайте запустимся с определения класса:

@interface BasicAddressBook: NSObject {
}
+ (BasicAddressBook *)addressBook;
- (NSString *)nameAtIndex:(int)index;
@end

Теперь мы запишем код для публикации a BasicAddressBook экземпляр к JavaScript:

BasicAddressBook *littleBlackBook = [BasicAddressBook addressBook];
 
id win = [webView windowScriptObject];
[win setValue:littleBlackBook forKey:@"AddressBook"];

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

Теперь, давайте приведем пример, показывающий, как можно использовать BasicAddressBook экземпляр класса в JavaScript. В этом случае мы распечатаем имя лица в определенном индексе в нашей адресной книге:

function printNameAtIndex(index) {
    var myaddressbook = window.AddressBook;
    var name = myaddressbook.nameAtIndex_(index);
    document.write(name);
}

Вы, возможно, заметили одну причуду в предыдущем примере кода. Существует подчеркивание после вызова JavaScript к Objective C nameAtIndex метод. В JavaScript это вызывают nameAtIndex_. Это - пример схемы переименования метода по умолчанию в действии.

Если Вы не реализуете webScriptNameForSelector для возврата пользовательского имени схема конструкции по умолчанию используется. Это - Ваша ответственность гарантировать, что возвращенное имя уникально для сценария, вызывающего этот метод. Если Ваша реализация webScriptNameForSelector возвраты nil или Вы не реализуете его, имя по умолчанию для селектора будет создано следующим образом:

Следующая таблица показывает результаты в качестве примера конструктора имени метода по умолчанию:

Селектор Objective C

Имя сценария по умолчанию для селектора

setFlag:

setFlag_

setFlag:forKey:withAttributes:

setFlag_forKey_withAttributes_

propertiesForExample_Object:

propertiesForExample$ _Object_

$ set_: forKey:withDictionary:

set$ _ $$ _forKey_withDictionary_

Так как конструкция по умолчанию для имени метода может сбить с толку в зависимости от его имени Objective C, Вы принесли бы преимущества себе и пользователям Вашего класса, если Вы реализуете webScriptNameForSelector и возвратите более человекочитаемые имена для своих методов.

При возвращении к BasicAddressBook теперь мы реализуем webScriptNameForSelector и isSelectorExcludedFromWebScript для нашего nameAtIndex метод. В нашей реализации класса BasicAddressBook мы добавим это:

+ (NSString *) webScriptNameForSelector:(SEL)sel
{
    ...
 
    if (sel == @selector(nameAtIndex:))
            name = @"nameAtIndex";
 
    return name;
}
 
+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
{
    if (sel == @selector(nameAtIndex:)) return NO;
    return YES;
}

Теперь мы можем изменить наш код JavaScript для отражения нашего более логического имени метода:

function printNameAtIndex(index) {
    var myaddressbook = window.AddressBook;
    var name = myaddressbook.nameAtIndex(index);
    document.write(name);
}

Для получения дополнительной информации

Для получения дополнительной информации об использовании Objective C от JavaScript и наоборот, см. следующие документы: