Руководство по разработке плагинов для iOS
Этот раздел предоставляет подробную информацию о том, как реализовать код нативного плагина на платформе iOS. Прежде чем читать это, ознакомьтесь с [Руководством по разработке плагинов][plugin-dev], чтобы получить общее представление о структуре плагина и его общем JavaScript-интерфейсе. В этом разделе мы продолжаем демонстрацию образца плагина echo, который взаимодействует между веб-вью Cordova и нативной платформой.
Плагин для iOS реализуется как класс Objective-C, который расширяет класс CDVPlugin. Для того, чтобы JavaScript-метод exec сопоставился с классом Objective-C, каждый класс плагина должен быть зарегистрирован как тег <feature> в файле config.xml в указанной директории приложения.
Сопоставление классов плагинов
JavaScript-часть плагина использует метод cordova.exec следующим образом:
exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);
Это обеспечивает передачу запроса от UIWebView к нативной стороне iOS, эффективно вызывая метод action в классе service, с аргументами, переданными в массиве args.
Укажите плагин как тег <feature> в файле config.xml проекта приложения Cordova-iOS, используя файл plugin.xml для автоматической инъекции этого разметки, как описано в [Руководстве по разработке плагинов][plugin-dev]:
<feature name="LocalStorage">
<param name="ios-package" value="CDVLocalStorage" />
</feature>
Атрибут name функции должен соответствовать тому, что вы указываете в качестве параметра service вызова JavaScript exec. Атрибут value должен соответствовать имени класса Objective-C плагина. Элемент <param> должен всегда содержать значение ios-package. Если вы не следуете этим рекомендациям, плагин может быть скомпилирован, но Cordova всё равно может не получить к нему доступ.
Инициализация и жизненный цикл плагина
Один экземпляр объекта плагина создается на весь период существования каждого UIWebView. Плагины не инициализируются до тех пор, пока они не будут впервые упомянуты в вызове JavaScript, если плагин не <param> с атрибутом onload name установленным в значение "true" в файле config.xml. Например,
<feature name="Echo">
<param name="ios-package" value="Echo" />
<param name="onload" value="true" />
</feature>
Плагины должны использовать метод pluginInitialize для своей логики запуска.
Плагины с длительными запросами или фоновыми операциями, такими как воспроизведение медиа, обработка событий или поддержание внутреннего состояния, должны реализовывать метод onReset, чтобы отменить эти длительные запросы или очистить ресурсы после этих операций. Метод выполняется при переходе UIWebView на новую страницу или при обновлении, что перезагружает JavaScript.
Написание плагина Cordova для iOS
JavaScript-вызов инициирует запрос плагина к нативной стороне, а соответствующий iOS Objective-C плагин должным образом сопоставляется в файле config.xml, но как выглядит конечный класс iOS Objective-C плагина? Все, что передается плагину с помощью JavaScript-функции exec, передаётся в метод action соответствующего класса плагина. Метод плагина имеет следующую сигнатуру:
- (void)myMethod:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* myarg = [command.arguments objectAtIndex:0];
if (myarg != nil) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Arg was null"];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
Для получения более подробной информации, см. CDVInvokedUrlCommand.h, CDVPluginResult.h и CDVCommandDelegate.h.
Типы сообщений iOS CDVPluginResult
Вы можете использовать CDVPluginResult для возврата различных типов результатов обратно в JavaScript-обработчики, используя методы класса, которые следуют этому шаблону:
+ (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAs...
Вы можете создавать типы String, Int, Double, Bool, Array, Dictionary, ArrayBuffer, и Multipart. Вы также можете опустить любые аргументы, чтобы отправить статус, вернуть ошибку или даже не отправлять никакого результата плагина, в этом случае ни один обратный вызов не срабатывает.
Обратите внимание на следующее для сложных значений возврата:
messageAsArrayBufferожидаетNSData*и преобразует его вArrayBufferв JavaScript-обработчике. Точно так же любыеArrayBufferзначения, которые JavaScript отправляет плагину, преобразуются вNSData*.messageAsMultipartожидает массивNSArray*, содержащий любые другие поддерживаемые типы, и отправляет весь массив в качествеargumentsв ваш JavaScript-обработчик. Таким образом, все аргументы сериализуются или десериализуются по мере необходимости, поэтому безопасно возвращатьNSData*как составное значение, но не какArray/Dictionary.
Пример плагина Echo для iOS
Для соответствия JavaScript-интерфейсу функции echo, описанной в разделе «Плагины приложений», используйте plugin.xml для инъекции спецификации feature в файл config.xml локальной платформы:
<platform name="ios">
<config-file target="config.xml" parent="/*">
<feature name="Echo">
<param name="ios-package" value="Echo" />
</feature>
</config-file>
</platform>
Затем мы добавим следующие файлы Echo.h и Echo.m в папку Plugins в каталоге приложения Cordova-iOS:
/********* Echo.h Cordova Plugin Header *******/
#import <Cordova/CDVPlugin.h>
@interface Echo : CDVPlugin
- (void)echo:(CDVInvokedUrlCommand*)command;
@end
/********* Echo.m Cordova Plugin Implementation *******/
#import "Echo.h"
#import <Cordova/CDVPlugin.h>
@implementation Echo
- (void)echo:(CDVInvokedUrlCommand*)command
{
CDVPluginResult* pluginResult = nil;
NSString* echo = [command.arguments objectAtIndex:0];
if (echo != nil && [echo length] > 0) {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
} else {
pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
}
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
@end
Необходимые импорты в начале файла наследуют класс от CDVPlugin. В данном случае, плагин поддерживает только один тип действия echo. Он получает строку эха, вызывая метод objectAtIndex, чтобы получить первый параметр массива arguments, который соответствует аргументам, переданным JavaScript-функцией exec().
Он проверяет параметр, чтобы убедиться, что он не является nil, или пустой строкой, возвращая PluginResult со статусом ERROR, если это так. Если параметр проходит проверку, он возвращает PluginResult со статусом OK, передавая исходную строку echo. Наконец, он отправляет результат в self.commandDelegate, который выполняет обратные вызовы метода exec для успеха или ошибки на стороне JavaScript. Если вызывается обратный вызов успеха, он передаёт параметр echo.
Интеграция с iOS
Класс CDVPlugin содержит другие методы, которые ваш плагин может переопределять. Например, вы можете захватывать события паузы, возобновления, завершения работы приложения и handleOpenURL событий. Обратитесь к классам CDVPlugin.h и CDVPlugin.m для получения дополнительных сведений.
Потоки
Методы плагинов обычно выполняются в том же потоке, что и основной интерфейс. Если ваш плагин требует значительной обработки или блокирующего вызова, вам следует использовать фоновый поток. Например:
- (void)myPluginMethod:(CDVInvokedUrlCommand*)command
{
// Check command.arguments here.
[self.commandDelegate runInBackground:^{
NSString* payload = nil;
// Some blocking logic...
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
// The sendPluginResult method is thread-safe.
[self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}];
}
Отладка плагинов iOS
Для отладки на стороне Objective-C вам потребуется встроенный отладчик Xcode. Для JavaScript вы можете подключить Safari к приложению, запущенному в iOS-симуляторе/устройстве.
Распространённые ошибки
Не забудьте добавить сопоставление вашего плагина в
config.xml. Если вы это забудете, в консоли Xcode будет выведено сообщение об ошибке.Не забудьте добавить все хосты, с которыми вы подключаетесь, в белый список, как описано в руководстве по белому списку доменов Whitelist Guide. Если вы это забудете, в консоли Xcode будет выведено сообщение об ошибке.
© 2012, 2013, 2015 The Apache Software Foundation
Licensed under the Apache License 2.0.
https://cordova.apache.org/docs/en/6.x/guide/platforms/ios/plugin.html