Руководство по разработке плагинов для iOS
В этом разделе приводятся подробные сведения о том, как реализовать код нативного плагина на платформе iOS. Прежде чем приступать к чтению, ознакомьтесь с Руководством по разработке плагинов для общего обзора структуры плагина и его общего JavaScript-интерфейса. В этом разделе продолжается демонстрация образца плагина echo, который взаимодействует от Cordova webview с нативной платформой и обратно.
Плагин iOS реализуется как класс Objective-C, расширяющий класс CDVPlugin. Для того, чтобы JavaScript-метод exec сопоставил параметр service с классом 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 для автоматической инъекции этого разметки, как описано в Руководстве по разработке плагинов:
<feature name="LocalStorage">
<param name="ios-package" value="CDVLocalStorage" />
</feature>
Атрибут name функции должен совпадать с тем, что вы указали как параметр exec вызова JavaScript service. Атрибут 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.
Создание плагина iOS для Cordova
Вызов 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-обработчике. Аналогично, любыеArrayBufferJavaScript-отправленные в плагин преобразуются в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 Simulator/Device.
Распространённые ошибки
Не забудьте добавить сопоставление вашего плагина в
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/8.x/guide/platforms/ios/plugin.html