C程序设计语言读书笔记:导言
C语言作为大学软件工程专业入门的第一门编程语言,我其实早就还给老师。从今天开始,重新温习一下,并记下一些非常基础的读书笔记,勉励自己。
iOS程序设计(原书第2版) 这书不错。
1.输出格式问题
printf(“ %3d %6d”,fahr, celsius);
打印fahr与celsius的值,fahr的值占3个数字宽,celsius的值占6个数字宽。
%d 按照十进制整型数打印
%6d 按照十进制整型数打印,至少6个字符宽
%f 按照浮点数打印
%6f 按照浮点数打印,至少6个字符宽
%.2f 按照浮点数打印,小数点后有两位小数
%6.2f 按照浮点数打印,至少6个字符宽,小数点后有两位小数
printf函数还支持下列格式说明:
%o表示八进制数
%x表示十六进制数
%c表示字符
%s表示字符串
%%表示百分号(%)本身
%u表示无符号字符类型
%lu表示无符号长整形类型
2.符号常量
#define指令行的末尾没有分号。
让Octopress博客在多台Mac上同时使用
JSDoc安装问题
JSDoc安装后出现-bash: sudu: command not found
1.根据JSDoc的github安装教程 Github安装文档
使用CLI指令npm install jsdoc
来安装JSDoc后,在命令行输入指令jsdoc -help
,CLI提示-bash: sudu: command not found
。
百度谷歌后,发现是安装的指令的问题,使用指令npm install -g jsdoc@"<=3.3.0""
,安装后,在CLI输入jsdoc -help
能显示jsdoc的帮组信息。
留一下任务给自己,为什么使用指令npm install -g jsdoc@"<=3.3.0""
能够成功使用jsdoc指令?
iOS平台编写Cordova插件
由于文章篇幅有点长,所以建议大家可以参考插件的文件目录结构以及各文件内容,边看边拷贝文件内容,快速编写一个插件demo出来,首先有个大概的了解。毕竟纸上得来终觉浅,看完了不写,相当于没看。在2.各文件内容以及作用里面,会详细介绍配置文件以及各元素的作用。(文章末尾有提供安卓平台下编写Cordova插件连接)
1.插件的文件目录结
在桌面或者你认为适合放插件的文件夹下,新建文件夹。新建的文件夹的名称是该插件的id,格式为:com.xxxxxxxx.xxx。
比如,我在桌面新建文件夹,命名为:com.technologystudios.logout
在新建名称为com.technologystudios.logout的文件夹后,依次新建以下的文件(com.technologystudios.logout不必再新建,只需新建README.md,plugin.xml,src和www文件夹以及下级的文件,其中plugin.xml,src,www为必须的文件)
新建后的文件目录结构(这只是个人新建插件文件目录结构的习惯,并非标准。)
com.technologystudios.logout
├── README.md
├── plugin.xml
├── src
│ └── ios
│ ├── CDVLogoutPlugin.h
│ └── CDVLogoutPlugin.m
└── www
└── logoutplugin.js
2.各文件内容以及作用
README.md文件
作为帮助文件的存在,内容描述的是插件如何使用以及定义返回的参数格式等。
Logout Plugin
==============
Non-Cross-platform LogoutPlugin
Note:Just for LogoutPlugin
## Using the plugin ##
LogoutPlugin
使用方法:
var logoutPlugin = cordova.require("com.technologystudios.logout.logoutplugin")
logoutPlugin.executeLogout
{
"type":"Logout"
}
返回的参数格式:
{
"code":0,
"data":{},
"message":"登出成功!",
"success":"1"
}
## Licence ##
The PHOENIX License
Copyright (c) 2015 PHOENIX Tony Mo
plugin.xml文件
plugin.xml 是插件的配置文件。 还是先给出例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
- plugin:依次为命名空间、ID、版本,值得我们注意的是属性id。id的值为插件的id值:“com.technologystudios.logout"。
- name:插件的名称
- description:描述信息
- engines:Cordova版本
- license:授权
- platform:支持的平台,iOS平台的话,属性name的值为iOS。
- config-file:封装feature元素注入特定平台(在这里平台为iOS)的config.xml文件
- feature:属性name为插件的名字
param:iOS平台,name的值就是"ios-package";安卓平台,name的值就是"android-package" 使用CLI添加插件后(后面会介绍CLI添加插件的方法),在项目名称/platforms/ios/项目名称/config.xml文件,会注入
而又值得我们注意的是,feature元素的属性name的值"LogoutPlugin",是插件的服务名称,需要与logoutplugin.js文件的1 2 3
<feature name="LogoutPlugin"> <param name="ios-package" value="CDVLogoutPlugin" /> </feature>
1
cordova.exec(successCallback, errorCallback, 'LogoutPlugin','executeLogout', [options]);
这个方法的第三个参数的值一致,(在logoutplugin.js文件会详细说明)。 而param元素属性value=“CDVLogoutPlugin”,“CDVLogoutPlugin"是native代码的类名,需要作为与src/ios目录下的文件名和类名一致(在CDVLogoutPlugin会详细说明)。
- header-file,source-file:在iOS平台下,指向iOS原生代码的头文件和实现文件的位置
- js-module:src指向插件的js文件地址www/logoutplugin.js,属性name的值"logoutplugin",作为插件id的最后一部分。JS使用
cordova.require
加载logoutPlugin对象的时候,使用到的是插件id + “logoutplugin” ,cordova.require("com.technologystudios.logout.logoutplugin")
,为什么通过这个指令就能够得到logoutPlugin对象?
当通过CLI安装插件后,logoutplugin.js被拷贝到:项目名称/platforms/ios/www/plugins/my.plugin.id/www/logoutplugin.js这个目录,同时,插件的id,js文件被拷贝到的目标目录,以及clobbers元素信息,会作为新增的条目被增加到:项目名称/platforms/ios/cordova_plugins.js文件。 cordova_plugins.js文件,我对它的理解,是封装插件的信息,通过插件id加载对应的插件js文件,获得插件对象,而不需要调用端关心需要加载哪一个js文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
cordova.define定义名字为'cordova/plugin_list'
的模块,改模块向外声明返回的对象类型为数组,该数组对象封装了项目的插件列表。cordova.require("com.technologystudios.logout.logoutplugin")
,通过获得'cordova/plugin_list'
模块返回的数组对象,并根据id加载对应的js文件logoutplugin.js。而logoutplugin.js文件定义了module.exports = logoutplugin;
模块并对外部声明模块返回logoutplugin对象(具体代码内容见logoutplugin.js文件)。所以通过cordova.require(id)
能获取插件的对象。
涉及到的mudule.exports以及cordova.define,cordova.require资料
nodejs中exports与module.exports的区别详细介绍
Cordova 3.x 源码分析(3) – cordova.js模块系统require/define
clobbers:官网API给出的解释是"指示
module.exports
作为window.some.value
被插入到window对象"。目前对该元素没有很深的理解,target的值我一般赋值"plugins.xxx",xxx的值就是与js-module属性name的值一致。有对这个元素理解深刻的同学麻烦指教一下。framework:插件依赖的framework。例子:
<framework src="libz.dylib" />
官网plugin.xml文档plugin.xml字段的详细解释。
src/ios/CDVLogoutPlugin文件
该目录下的文件名以及类名需要与plugin.xml文件里面的
1 2 3 4 5 |
|
param的value属性值一致。"CDVLogoutPlugin"表示插件名字为"LogoutPlugin"的feature,映射到名为"CDVLogoutPlugin"的服务,插件服务的类名称为"CDVLogoutPlugin",在logoutplugin.js文件中,会使用到这个映射的关系。
CDVLogoutPlugin.h文件的代码例子:
1 2 3 4 5 |
|
CDVLogoutPlugin.m文件的代码例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|
CDVLogoutPlugin类需要继承CDVPlugin类,CDVLogoutPlugin的方法executeLogout:名称,需要与logoutplugin.js的cordova.exec方法第四个参数一致。executeLogout:方法默认的参数类型是CDVInvokedUrlCommand。
1
|
|
在CDVLogoutPlugin.m文件中,executeLogout:方法,command.arguments[0]表示的是cordova.exe函数中的最后一个参数[options],参数的格式可以定义在README.md文件中。该例子的参数格式为{“type”:“Logout”},在javascript传递一个对象到native的插件。
1
|
|
这行代码是返回调用插件的结果给javascript回调函数。Status为CDVCommandStatus_OK的,回调successCallback函数,Status为CDVCommandStatus_ERROR回调errorCallback函数。
www/logoutplugin.js文件
还是直接上例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
代码第2,3行,是加载cordova,exec对象;
1 2 |
|
第4行,new一个LogoutPlugin对象。
第7行是定义LogoutPlugin对象的executeLogout方法。
1
|
|
executeLogout方法接收三个参数,第一第二个参数,函数类型。successCallback函数,调用本地插件成功时回调的函数;errorCallback函数,调用本地插件失败时回调的函数。这是javascript与native对接的回调函数,通过native的
1 2 |
|
CDVPluginResult对象的属性status(CDVCommandStatus_OK/CDVCommandStatus_ERROR)来返回调用对应的成功(successCallback)/失败函数(errorCallback)。
第三个参数,数组类型,为javascript到native的参数。通过
1
|
|
获得,其中command
为CDVInvokedUrlCommand*
类型。
第23行
1
|
|
执行cordova.exec方法,调用'LogoutPlugin'服务的'executeLogout'方法。本地Objective-C代码会执行CDVLogoutPlugin类的executeLogout:方法。
第一第二个参数(successCallback/errorCallback)为外部传递进来的成功/失败回调函数。
第三个参数("LogoutPlugin"),为插件的服务名称,需要与plugin.xml文件的
1 2 3 |
|
feature元素name属性值"LogoutPlugin"保持一致,"LogoutPlugin" 通过元素param设置其映射的Objective-C的类的名字为"CDVLogoutPlugin"。
- 第四个参数('executeLogout'),为"LogoutPlugin" 映射到Objective-C的"CDVLogoutPlugin"类的方法名字
- 第五个参数(options),是javascript调用native的插件传递的参数,参数格式为数组,通过被调用的本地方法executeLogout:传入的对象(CDVInvokedUrlCommand*)command, command.arguments[0]来获取。
第27行
1
|
|
创建模块logoutplugin,通过加载logoutplugin.js文件能获取logoutplugin对象。在plugin.xml文件中会详细说明。
大家可以尝试快速新建插件,目录结构以及各文件内容可以直接拷贝粘贴,先写一个雏形插件。假设大家都写好了这个登出的插件。
3.Cordova CLI安装插件
这里没有使用pluginman来对Cordova插件的管理。若需要使用pluginman来管理插件的话,请点击这里这里
假设大家已经搭建好Ionic环境,以及已经新建好Ionic的项目,如果没有,请点击这里来进行环境的搭建以及新建项目,这里不再赘言。
- 打开CLI,进入项目的目录
输入指令
cordova plugin -h
会出现帮助信息,其中我们关注的是add <pluginid>|<directory>|<giturl> [...] ..... add specified plugins pluginid will be matched in --searchpath / registry directory is a directory containing a plugin giturl is a git repo containing a plugin
- pluginid:根据插件的id来搜索插件并安装,该插件需要在Cordova插件库注册成功的。
- directory:通过插件所在的本地路径来安装(LogoutPlugin就是通过这种方式来安装)
giturl:通过url进行插件的安装
这是使用CLI安装插件前的最外层的plugins目录结构(并非/platforms/ios/www/plugins)
这是/platforms/ios/www/plugins
在CLI输入指令
cordova plugin add /Users/Tony/Desktop/plugin/com.technologystudios.logout
“/Users/Tony/Desktop/plugin/com.technologystudios.logout"是插件的路径, 敲下回车键之后,出现Installing "com.technologystudios.logout" for ios
信息表示成功安装插件安装成功后,最外层的plugins目录和/platforms/ios/www/plugins都会多一个刚才add的插件,其中平台里面的plugins是copy最外层的plugins的内容
4.HTML调用本地插件
1.html代码
1 2 3 4 5 6 7 8 9 10 |
|
第3-8行代码,描述的是名字为"登出"的按钮,ng-click事件为"logout()“。很容易理解。
2.javascript代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
|
第3行代码,是登出按钮的logout()事件的定义。
第8-13行代码,简单地输入控制台调用本地插件的情况,以及输入返回的参数。
第5-13行代码,是options参数格式,以及成功回调函数和失败回调函数的定义。
第18行代码,cordova.require("com.technologystudios.logout.logoutplugin")
加载logoutPlugin对象。
Javascript端调用native端的插件,首先需要通过cordova.require("插件id.xxx")
来获取得插件对象,其中"xxx"为plugin.xml的元素js-module属性name的值"logoutplugin"。
1 2 3 |
|
第33行代码,获取logoutPlugin对象后,通过调用executeLogout(successCallback, errorCallback, newOptions)方法(方法的定义,在logoutplugin.js文件),来调用映射到objective-c的CDVLogoutPlugin类的方法executeLogout:。
3.Objective-C 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
第12行代码,简单地在控制台输出native的插件被调用的信息。
第18行代码,组装CDVPluginResult类型的result对象,初始化status为CDVCommandStatus_OK,以及返回的参数:@{@"code":@(0),@"data":@{},@"message":@"登出成功!",@"success":@"1"}
5.例子
点击HTML5页面的"登出"按钮,在xcode控制台会输出信息
CDVLogoutPlugin's function:executeLogout is called
表示消息成功地传递到native的插件。
然后顺序执行
1 2 |
|
返回调用成功会HTML,在前端的控制台会输入下面的信息:
返回的Object就是在native的插件组装的对象@{@"code":@(0),@"data":@{},@"message":@"登出成功!",@"success":@"1"}
。
6.Cordova更新插件
一般情况下,被添加的插件会被修改,而且被修改的文件位置在:项目名/platforms/ios/www/plugins/pluginid/src/ios/xxxx,或者是项目名/platforms/ios/www/plugins/pluginid/www/xxx.js,被修改的文件是不会自动更新到:项目名/plugins/pluginid的文件。
那么,被添加的插件如何更新?
很遗憾,目前Cordova的CLI没有提供Cordova plugin update
指令来直接更新插件。
笔者解决方案 这里分两种情况:
1.没有在ng-cordova注册的插件
笔者采用一个曲线救国的方法来更新插件,当需要修改:项目名/platforms/ios/www/plugins/pluginid下的文件,我会拷贝修改的文件内容到:项目名称/plugins/对应需要被覆盖的文件。
当插件的修改内容达到需要更新版本号的时候,保存更新的插件文件,更新:项目名称/plugins/pluginid/plugin.xml文件的version="x.x.x"
,拷贝:项目名称/plugins/pluginid文件夹到桌面或者你认为合适的地方。
进入到项目的路径下,输入指令(使用logout插件id作为例子)
`cordova plugin remove com.technologystudios.logout`
CLI会输出这些信息
`Uninstalling com.technologystudios.logout from ios Removing "com.technologystudios.logout`
指令的意思是移除plugin id为com.technologystudios.logout的插件。
成功执行remove puglin之后,项目名称/plugins/以及项目名称/platforms/ios/www/plugins/下的com.technologystudios.logout文件件会被自动删除。
在CLI输入指令
ionic build ios
cordova plugin add /Users/Tony/Desktop/com.technologystudios.logout
重新安装最新的插件到项目,完成一次插件的更新。
注意 若重新安装后,调用插件,xcode的控制台出现
2015-06-18 18:57:28.677 PluginDemoTabs[18677:645115] ERROR: Plugin 'LogoutPlugin' not found, or is not a CDVPlugin. Check your plugin mapping in config.xml.
2015-06-18 18:57:28.677 PluginDemoTabs[18677:645115] -[CDVCommandQueue executePending] [Line 159] FAILED pluginJSON = ["LogoutPlugin1500224491","LogoutPlugin","executeLogout",[{"type":"Logout"}]]
- 选中使用xcode打开项目,找到CDVLogoutPlugin.m文件,选中,然后在Target Membership,选中项目的target,打钩,然后使用CLI输入指令
ionic build ios
重新编译项目,问题解决。
2.在ng-cordova注册的插件 目前还没有在ng-cordova上传并成功注册过插件,在这里先挖个坑,往后的日子再填。
安卓平台下编写cordova插件 Cordova 开发属于自己的插件(plugin)
(完)