11、iOS开发详解(基础知识)

翻译自cordova官方文档(如果需要链接,请自行对照原文链接进行查看):
https://cordova.apache.org/docs/en/latest/guide/platforms/ios/plugin.html

iOS开发详解

本章节针对如何开发基于iOS系统的插件进行介绍,在此之前,请阅读Plugin Development Guide(插件开发指南)对插件的结构和JavaScript接口有一个大概的了解。
iOS插件是以继承至CDVPlugin类Objective-C的子类来实现的,通过JavaScript的exec函数来将service/parameter映射到Objective-C类,每一个插件在工程根目录下的config.xml文件中通过标签进行注册。

插件类的映射

我们通过如下的Cordova API来实现JavaScript到Objective-C的映射过程:

   exec(<successFunction>, <failFunction>, <service>, <action>, [<args>]);

通过这个JavaScript函数我们就可以使用JavaScript代码来执行Objective-C类的指定函数,并且通过args来传递参数。
通过config.xml中iOS平台的标签来指定需要的插件,通过plugin.xml文件来自动注入插件到iOS平台代码中去。

<featurename="LocalStorage"><paramname="ios-package"value="CDVLocalStorage" /></feature>

标签的name属性用于指定plugin在JavaScript执行exec方法时service参数的值,为标签内标签内value对应的Objective-C类的具体函数名,args以数组的形式传入到Objective-C函数内。的name字段永远为’ios-package’。

插件的实例化和生命周期

plugin对象的生命周期和UIWebView是一致的,Plugin是不需要实例化的,在他们第一次被调用的时候会自动实例化。也可以通过指定的方式来手动实例化一个plugin比如:

<featurename="Echo"><paramname="ios-package"value="Echo" /><paramname="onload"value="true" /></feature>

当使用的时候,在程序启动的时候会执行插件的pluginInitialize方法来实例化一个插件类对象。你可以通过覆盖pluginInitialize方法的方式在程序启动的时候为你的插件做点什么。
Plugin进行耗时操作的时候,比如媒体操作,监听,或者网络状态相关的事情,应该提供重置和取消操作来终止之前的操作或者请求。当需要转入新的页面或者刷新页面这种需要重新加载JavaScript的时候被使用。

创建一个iOS plugin

JavaScript通过config.xml配置的映射来发起一个plugin请求来执行Objective-C代码,但是最终的Objective-C插件类什么样呢?下面就是plugin的一个方法定义:

   - (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这三个Cordova源代码文件。

iOS CDVPluginResult类

你可以使用CDVPluginResult类来返回各种类型的结果信息给JavaScript的回调函数,通过以下的方式来创建一个CDVPluginResult对象:

  + (CDVPluginResult*)resultWithStatus:(CDVCommandStatus)statusOrdinal messageAs...

你可以返回字符串,整数,布尔,数组以及复合数据类型等,你也可以仅仅返回一个状态信息或者错误信息,当然你也可以不返回任何信息仅仅调用JavaScript端的回调函数。
下面复杂类型的返回值的使用方法:
messageAsArrayBuffer以NSData的形式被传送到JavaScript回调函数,并且被转换为ArrayBuffer类型,而ArrayBuffer在传入到Objective-C端的时候会被转换成NSData。
messageAsMultipart以NSArray的形式被传入到JavaScript回调函数,里面包含各种类型的数据对象。通过这种方式传送数据,里面的数据会被序列化和反序列化,所以他可以安全的返回NSData,而不是Array/Dictionary。
Echo iOS Plugin(这篇文章对于plugin的配置在使用cordova build命令以后会被覆盖,不建议在iOS工程直接加入文件修改配置文件信息的方式添加插件。使用独立插件通过plugin add的方式添加插件比较容易维护和使用)

这个例子通过plugin.xml来向指定的iOS平台注入信息。

<platformname="ios"><config-filetarget="config.xml"parent="/*"><featurename="Echo"><paramname="ios-package"value="Echo" /></feature></config-file></platform>

添加Echo.h文件和Echo.m文件到iOS镜像的文件夹的Plugins文件夹:

/********* 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插件只有一个功能。就是返回JavaScript传入的第一个参数内容。如果没有传入参数则返回错误,如果传入参数,则将该参数返回。

CDVPlugin简介

CDVPlugin类包含其他的一些方法,你可以通过重写的方式来实现自己的行为,比如捕获pause,resume等等。具体可以去读CDVPlugin.h/CDVPlugin.m源文件

Threading

我们在plugin里面经常需要做一些耗时的操作,但是在主线程耗时过长,App就会被系统kill。所以通过runInBackground来进行耗时操作:

  - (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];
        }];
    }

调试plugin

使用Xcode来调试plugin,如果调试JavaScript代码,需要使用Safari在虚拟机或者设备上调试。

易犯错误

不要忘记在config.xml添加映射信息。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值