
轮播图
2017.11.12立项做混合app,2017.12.20交给测试,毕竟前端开发只有自己一个人,踩了很多坑,立贴记录一下。
第一次轮播图:使用swiper插件。
//其实最开始的时候,是打算自己手写轮播图的,但是发现自己写的bug太多,就使用插件了
<!--HTML部分-->
<div class="swiper-container">
<div class="swiper-wrapper">
<!--图片-->
<div class='swiper-slide'>
<a href='#'>
<img src=''/>
</a>
</div>
</div>
<div class="swiper-pagination"><!-- 分页器 --></div>
</div>
<!--JS部分-->
function slideshow (dom){
//12.27,ajax是自己封装的,后来放弃了,使用mui.get
ajax({
//type:"get",
url:"http://192.000.0.155:8080/getSlideShow",
dataType:"json",
suc:function(data){
var show =[];
var list = data.imglist;
for(var i =0; i < list.length; i++){
var j = "<div class='swiper-slide'><a href='"+list[i].url+"'><img src='"+ list[i].path +"'/></a></div>"
show.push(j);
}
dom.innerHTML = show.join("");
//开启轮播图
var mySwiper = new Swiper ('.swiper-container', {
loop: true, //循环播放
autoplay:true, //自动轮播
disableOnInteraction:false, //使用户点击后继续播放
pagination: {el:'.swiper-pagination'},
});
}
})
}
slideshow(document.querySelector(".swiper-wrapper"));
第二次轮播图:使用MUI
//不是因为swiper做的不好,而是项目中很多地方使用了mui,不想引入过多的插件
//说实话,mui的轮播图和swiper相比,很差,毕竟swiper是专业的
mui的轮播图就不上代码了,臃肿,简单,在HBuilder中,按下ms选择到轮播图就好
第三次轮播图:使用MUI
还是使用了MUI做轮播图,图片轮播代码部分没有改变
因为主页想换成网易云音乐那样左右滑动操作,但是在手指滑动轮播图时,不能阻止事件上传,窗口webview随手指滑动。至今没有找到合适解决办法。
重新更改webvive排布方式,把轮播图当作一个独立的html添加到主页main中,分解ontouchmove监听目标。解决主页滑动与轮播图滑动混淆问题。
/*main.html中js部分代码 */
self = plus.webview.currentWebview();
sliderW = plus.webview.create( "slider.html", "slider.html", {top: "0",height:"200px",hardwareAccelerated:true});
homeW = plus.webview.create( "home.html", "home.html",{bottom: "50px",top: "200px"});
newsW = plus.webview.create( "news.html", "news.html",{bottom: "50px",top:"0",hardwareAccelerated:true});
userW = plus.webview.create( "user.html", "user.html",{bottom: "50px",top:"0"});
self.append(sliderW)
self.append(homeW)
self.append(newsW)
self.append(userW)
sliderW.show();
homeW.show();
function move (webviewID,s,t){
/* s="rtl" = left // "ltr" =right
t = followFinger=跟随 || bounce=反弹
*
* */
function get (d){
return plus.webview.getWebviewById(d);
}
get(webviewID).drag(
{direction:s,moveMode:t},
{},
function(e){
if(e.result){
if(t == "followFinger"){
get(webviewID).back();
}
}
}
)
}
moves(homeW ,newsW,"rtl",function(){
news.classList.add("border");
home.classList.remove("border");
})
······//重复造轮子img。。。
//之所以没有使用mui的窗口滑动,是因为当初没有找到mui的插件,当后来知道mui的滑动插件的时候,又发现mui兼容Android4.0之下的问题,所以也就没有改
第四次轮播图:使用plus.nativeObj.ImageSlider
在2017.12.11,plus新增了原生图片轮播控件(plus.nativeObj.ImageSlider)支持自动播放属性(autoplay/interval),
2017.12.13,经过老板同意,舍弃主页滑动功能,为了性能,改mui轮播图为plus.nativeObj.ImageSlider
function slideshow (id,top) { //ajax获取网络图片
mui.getJSON(sg("host")+"app/getSlideShow",{userId:sg("userId")},function(data){
if(data.code ==0){
var li = data.imglist;
var imgs =[]; //图片
var imghref = []; //需要跳转的页面
for(var i=0; i<li.length;i++){
imghref.push(li[i].url);
var s = {src:sg("fileHost")+li[i].path,height:"100%",width:"100%"};
imgs.push(s);
}//声明轮播图
var slider = new plus.nativeObj.ImageSlider("slider", {
top:top||"0px",left:"0px",
height:"200px",width:"100%",position:"static",
autoplay:true,
fullscreen:false,
loop:true,
images:imgs,
});
plus.webview.getWebviewById(id).append(slider);
slider.show();
slider.addEventListener("click",function(e){
var index = e.currentImageIndex; //轮播图索引
get("main.html").evalJS("openAd('"+imghref[index]+"')")
})
}
})
}
第五次轮播图:使用MUI
三天后测试,发现plus.nativeObj.ImageSlider在自动轮播时候当滚动一定次数后,滚动会卡断,手动滑动也是失败,只能向反方向滑动。
无奈重新更换为mui的轮播图。
第六次轮播图:使用MUI
所谓的第六次更改,是想把轮播图的图片做缓存,在ajax发现图片没有更改的时候,使用缓存图片,减少http请求。
后来放弃了。因为发现手机会自动缓存,我要考虑的问题反而是怎么减少缓存。。。。。心好累。。。。
2017.11.12立项做混合app,2017.12.20交给测试,毕竟前端开发只有自己一个人,踩了很多坑,立贴记录一下。
第一次轮播图:使用swiper插件。
//其实最开始的时候,是打算自己手写轮播图的,但是发现自己写的bug太多,就使用插件了
<!--HTML部分-->
<div class="swiper-container">
<div class="swiper-wrapper">
<!--图片-->
<div class='swiper-slide'>
<a href='#'>
<img src=''/>
</a>
</div>
</div>
<div class="swiper-pagination"><!-- 分页器 --></div>
</div>
<!--JS部分-->
function slideshow (dom){
//12.27,ajax是自己封装的,后来放弃了,使用mui.get
ajax({
//type:"get",
url:"http://192.000.0.155:8080/getSlideShow",
dataType:"json",
suc:function(data){
var show =[];
var list = data.imglist;
for(var i =0; i < list.length; i++){
var j = "<div class='swiper-slide'><a href='"+list[i].url+"'><img src='"+ list[i].path +"'/></a></div>"
show.push(j);
}
dom.innerHTML = show.join("");
//开启轮播图
var mySwiper = new Swiper ('.swiper-container', {
loop: true, //循环播放
autoplay:true, //自动轮播
disableOnInteraction:false, //使用户点击后继续播放
pagination: {el:'.swiper-pagination'},
});
}
})
}
slideshow(document.querySelector(".swiper-wrapper"));
第二次轮播图:使用MUI
//不是因为swiper做的不好,而是项目中很多地方使用了mui,不想引入过多的插件
//说实话,mui的轮播图和swiper相比,很差,毕竟swiper是专业的
mui的轮播图就不上代码了,臃肿,简单,在HBuilder中,按下ms选择到轮播图就好
第三次轮播图:使用MUI
还是使用了MUI做轮播图,图片轮播代码部分没有改变
因为主页想换成网易云音乐那样左右滑动操作,但是在手指滑动轮播图时,不能阻止事件上传,窗口webview随手指滑动。至今没有找到合适解决办法。
重新更改webvive排布方式,把轮播图当作一个独立的html添加到主页main中,分解ontouchmove监听目标。解决主页滑动与轮播图滑动混淆问题。
/*main.html中js部分代码 */
self = plus.webview.currentWebview();
sliderW = plus.webview.create( "slider.html", "slider.html", {top: "0",height:"200px",hardwareAccelerated:true});
homeW = plus.webview.create( "home.html", "home.html",{bottom: "50px",top: "200px"});
newsW = plus.webview.create( "news.html", "news.html",{bottom: "50px",top:"0",hardwareAccelerated:true});
userW = plus.webview.create( "user.html", "user.html",{bottom: "50px",top:"0"});
self.append(sliderW)
self.append(homeW)
self.append(newsW)
self.append(userW)
sliderW.show();
homeW.show();
function move (webviewID,s,t){
/* s="rtl" = left // "ltr" =right
t = followFinger=跟随 || bounce=反弹
*
* */
function get (d){
return plus.webview.getWebviewById(d);
}
get(webviewID).drag(
{direction:s,moveMode:t},
{},
function(e){
if(e.result){
if(t == "followFinger"){
get(webviewID).back();
}
}
}
)
}
moves(homeW ,newsW,"rtl",function(){
news.classList.add("border");
home.classList.remove("border");
})
······//重复造轮子img。。。
//之所以没有使用mui的窗口滑动,是因为当初没有找到mui的插件,当后来知道mui的滑动插件的时候,又发现mui兼容Android4.0之下的问题,所以也就没有改
第四次轮播图:使用plus.nativeObj.ImageSlider
在2017.12.11,plus新增了原生图片轮播控件(plus.nativeObj.ImageSlider)支持自动播放属性(autoplay/interval),
2017.12.13,经过老板同意,舍弃主页滑动功能,为了性能,改mui轮播图为plus.nativeObj.ImageSlider
function slideshow (id,top) { //ajax获取网络图片
mui.getJSON(sg("host")+"app/getSlideShow",{userId:sg("userId")},function(data){
if(data.code ==0){
var li = data.imglist;
var imgs =[]; //图片
var imghref = []; //需要跳转的页面
for(var i=0; i<li.length;i++){
imghref.push(li[i].url);
var s = {src:sg("fileHost")+li[i].path,height:"100%",width:"100%"};
imgs.push(s);
}//声明轮播图
var slider = new plus.nativeObj.ImageSlider("slider", {
top:top||"0px",left:"0px",
height:"200px",width:"100%",position:"static",
autoplay:true,
fullscreen:false,
loop:true,
images:imgs,
});
plus.webview.getWebviewById(id).append(slider);
slider.show();
slider.addEventListener("click",function(e){
var index = e.currentImageIndex; //轮播图索引
get("main.html").evalJS("openAd('"+imghref[index]+"')")
})
}
})
}
第五次轮播图:使用MUI
三天后测试,发现plus.nativeObj.ImageSlider在自动轮播时候当滚动一定次数后,滚动会卡断,手动滑动也是失败,只能向反方向滑动。
无奈重新更换为mui的轮播图。
第六次轮播图:使用MUI
所谓的第六次更改,是想把轮播图的图片做缓存,在ajax发现图片没有更改的时候,使用缓存图片,减少http请求。
后来放弃了。因为发现手机会自动缓存,我要考虑的问题反而是怎么减少缓存。。。。。心好累。。。。

Native.js 安卓连接蓝牙打印机【可连续打印】
自己摸索了一下,并参考其他人的代码,并修复了原来代码存在的问题,
问题1:字符串的getBytes函数,返回null【需要通过new的方式创建字符串】
问题2:初始化打印一次,之后无法使用【不要重复调用device.createInsecureRfcommSocketToServiceRecord(uuid)或重复引入CLASS】
代码如下,可正常运行【注意,蓝牙打印机必须先匹配,保证手机蓝牙打开】
mui.plusReady(function() {
main = plus.android.runtimeMainActivity();
BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
UUID = plus.android.importClass("java.util.UUID");
uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//不需要更改
BAdapter = BluetoothAdapter.getDefaultAdapter();
BAdapter.cancelDiscovery(); //停止扫描
device = BAdapter.getRemoteDevice("DC:1D:30:25:19:23");//这里是蓝牙打印机的蓝牙地址
plus.android.importClass(device);
bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
plus.android.importClass(bluetoothSocket);
});
function print() {
if(!bluetoothSocket.isConnected()) {
console.log('断开了,需要重新连接,连接中');
bluetoothSocket.connect();
}
if(bluetoothSocket.isConnected()) {
console.log('连接成功');
var outputStream = bluetoothSocket.getOutputStream();
plus.android.importClass(outputStream);
var s = plus.android.importClass('java.lang.String');
var string = new s("测试数据"+new Date().getMilliseconds()+'\n\n\n\n');//必须以创建字符串对象的形式创建对象,否则返回NULL
var bytes = string.getBytes('gbk');
console.log(bytes);
outputStream.write(bytes);
outputStream.flush();
} else {
console.log('fail');
}
}
至于打印的内容和格式,请参考各自打印机提供的打印指令集,把它拼成字符串调用getBytes函数即可打印。
自己摸索了一下,并参考其他人的代码,并修复了原来代码存在的问题,
问题1:字符串的getBytes函数,返回null【需要通过new的方式创建字符串】
问题2:初始化打印一次,之后无法使用【不要重复调用device.createInsecureRfcommSocketToServiceRecord(uuid)或重复引入CLASS】
代码如下,可正常运行【注意,蓝牙打印机必须先匹配,保证手机蓝牙打开】
mui.plusReady(function() {
main = plus.android.runtimeMainActivity();
BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
UUID = plus.android.importClass("java.util.UUID");
uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//不需要更改
BAdapter = BluetoothAdapter.getDefaultAdapter();
BAdapter.cancelDiscovery(); //停止扫描
device = BAdapter.getRemoteDevice("DC:1D:30:25:19:23");//这里是蓝牙打印机的蓝牙地址
plus.android.importClass(device);
bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
plus.android.importClass(bluetoothSocket);
});
function print() {
if(!bluetoothSocket.isConnected()) {
console.log('断开了,需要重新连接,连接中');
bluetoothSocket.connect();
}
if(bluetoothSocket.isConnected()) {
console.log('连接成功');
var outputStream = bluetoothSocket.getOutputStream();
plus.android.importClass(outputStream);
var s = plus.android.importClass('java.lang.String');
var string = new s("测试数据"+new Date().getMilliseconds()+'\n\n\n\n');//必须以创建字符串对象的形式创建对象,否则返回NULL
var bytes = string.getBytes('gbk');
console.log(bytes);
outputStream.write(bytes);
outputStream.flush();
} else {
console.log('fail');
}
}
至于打印的内容和格式,请参考各自打印机提供的打印指令集,把它拼成字符串调用getBytes函数即可打印。
收起阅读 »
native.js唤起微信扫一扫
没有废话直接上代码
var Intent = plus.android.importClass("android.content.Intent");
var intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
var ComponentName = plus.android.importClass("android.content.ComponentName");
var comp = new ComponentName("com.tencent.mm","com.tencent.mm.ui.LauncherUI");
intent.setComponent(comp);
//只想唤起微信就不要下面这句传参代码
intent.putExtra("LauncherUI.From.Scaner.Shortcut", true);
intent.setAction("android.intent.action.VIEW");
var main = plus.android.runtimeMainActivity();
main.startActivity(intent);
用得上就点个赞,仅此而已
没有废话直接上代码
var Intent = plus.android.importClass("android.content.Intent");
var intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
var ComponentName = plus.android.importClass("android.content.ComponentName");
var comp = new ComponentName("com.tencent.mm","com.tencent.mm.ui.LauncherUI");
intent.setComponent(comp);
//只想唤起微信就不要下面这句传参代码
intent.putExtra("LauncherUI.From.Scaner.Shortcut", true);
intent.setAction("android.intent.action.VIEW");
var main = plus.android.runtimeMainActivity();
main.startActivity(intent);
用得上就点个赞,仅此而已
收起阅读 »
ios调试基座打包方法
可下载附件中工程进行打包测试,工程下载后解压到SDK的根目录下(与SDK里其他两个示例工程同级目录)
1 下载最新SDK http://ask.dcloud.net.cn/article/103
2 调试基座的工程名称和target名称应当为DCloud_Pandora
(也可以将编译生成的app的名称,修改为DCloud_Pandora.app, 修改后重新压缩成IPA文件,放到HBuilder指定目录下即可)
3 在Xcode工程的Info.plist文件中添加UIFileSharingEnabled键,并将键值设置为YES
4 修改control.xml文件
在control.xml文件的hbuilder节点下添加属性debug='true' 和syncDebug="false"
<?xml version="1.0"?>
<hbuilder version="1.9.3.40219" debug="true" syncDebug="false">
<apps>
<app appid="HBuilder" appver="8.9.0"/>
</apps>
</hbuilder>
5 配置第三方插件
第三方插件配置方法请参考文档
消息推送(Push)插件配置
分享(Share)插件配置
地图(Maps)插件配置
统计(Statistic)插件配置
支付(Payment)插件配置
登录鉴权(Oauth)插件配置
6 引入扩展插件
扩展插件编写和引入方法请参考文档iOS平台5+插件开发
7 自定义基座包使用方法请参考文档真机运行自定义基座包使用说明
8 用户自己创建工程时请参考文档iOS创建最精简离线打包工程,创建基础工程后在工程里添加libliblog.a
可下载附件中工程进行打包测试,工程下载后解压到SDK的根目录下(与SDK里其他两个示例工程同级目录)
1 下载最新SDK http://ask.dcloud.net.cn/article/103
2 调试基座的工程名称和target名称应当为DCloud_Pandora
(也可以将编译生成的app的名称,修改为DCloud_Pandora.app, 修改后重新压缩成IPA文件,放到HBuilder指定目录下即可)
3 在Xcode工程的Info.plist文件中添加UIFileSharingEnabled键,并将键值设置为YES
4 修改control.xml文件
在control.xml文件的hbuilder节点下添加属性debug='true' 和syncDebug="false"
<?xml version="1.0"?>
<hbuilder version="1.9.3.40219" debug="true" syncDebug="false">
<apps>
<app appid="HBuilder" appver="8.9.0"/>
</apps>
</hbuilder>
5 配置第三方插件
第三方插件配置方法请参考文档
消息推送(Push)插件配置
分享(Share)插件配置
地图(Maps)插件配置
统计(Statistic)插件配置
支付(Payment)插件配置
登录鉴权(Oauth)插件配置
6 引入扩展插件
扩展插件编写和引入方法请参考文档iOS平台5+插件开发
7 自定义基座包使用方法请参考文档真机运行自定义基座包使用说明
8 用户自己创建工程时请参考文档iOS创建最精简离线打包工程,创建基础工程后在工程里添加libliblog.a
收起阅读 »
开启扫一扫 示例教程
需求明确
开启常见的条码(二维码及一维码)的扫描识别功能,可调用设备的摄像头对条码图片扫描进行数据输入。通过plus.barcode可获取条码码管理对象。
知识点明确
Barcode模块:plus.barcode,提供开启摄像头扫描功能。
Gallery模块:plus.gallery,提供读取相册二维码图片功能。
效果展示

实现步骤
- 创建条码扫描识别控件实例对象,涉及到Barcode模块,具体参数设置可参考5+ API Barcode
在plusReady事件触发之后创建一个Barcode实例对象,此对象提供四个方法:
start: 开始条码识别
cancel: 结束条码识别
close: 关闭条码识别控件
setFlash: 是否开启闪光灯
和两个事件:
onmarked: 条码识别成功事件
onerror: 条码识别错误事件
function plusReady() {
if(ws || !window.plus || !domready) {
return;
}
// 获取窗口对象
ws = plus.webview.currentWebview();
// 开始扫描
ws.addEventListener('show', function() {
scan = new plus.barcode.Barcode('bcid');
// 定义识别成功事件
scan.onmarked = onmarked;
// 定义开始条码识别
scan.start({
conserve: true, // 是否保存成功扫描到的条码数据时的截图
filename: '_doc/barcode/' // 保存成功扫描到的条码数据时的图片路径
});
}, false);
// 显示页面并关闭等待框
ws.show('pop-in');
}
// 二维码扫描成功
function onmarked(type, result, file) {
switch(type) {
case plus.barcode.QR:
type = 'QR';
break;
case plus.barcode.EAN13:
type = 'EAN13';
break;
case plus.barcode.EAN8:
type = 'EAN8';
break;
default:
type = '其它' + type;
break;
}
result = result.replace(/\n/g, '');
plus.nativeUI.alert('扫描结果:' + JSON.stringify(result), function() {
console.log('扫描成功')
}, "helloW2A", "OK");
back();
}
2.从相册中选择图片识别,涉及到Gallery模块,具体参数设置可参考5+ API:Gallery
// 从相册中选择二维码图片
function scanPicture() {
plus.gallery.pick(function(path) {
plus.barcode.scan(path, onmarked, function(error) {
plus.nativeUI.alert('无法识别此图片');
});
}, function(err) {
console.log('Failed: ' + err.message);
});
}
3.DOM结构参考
<body style="background-color: #000000;">
<!--指定Barcode对象的在界面中关联div标签的id号。-->
<div id="bcid">
<div style="height:40%"></div>
<p class="tip">...载入中...</p>
</div>
<footer>
<div class="fbt" onclick="back()">取 消</div> <!--退出页面-->
<div class="fbt" onclick="scanPicture()">从相册选择二维码</div>
</footer>
</body>
示例工程已上传,供开发者参考
需求明确
开启常见的条码(二维码及一维码)的扫描识别功能,可调用设备的摄像头对条码图片扫描进行数据输入。通过plus.barcode可获取条码码管理对象。
知识点明确
Barcode模块:plus.barcode,提供开启摄像头扫描功能。
Gallery模块:plus.gallery,提供读取相册二维码图片功能。
效果展示
实现步骤
- 创建条码扫描识别控件实例对象,涉及到Barcode模块,具体参数设置可参考5+ API Barcode
在plusReady事件触发之后创建一个Barcode实例对象,此对象提供四个方法:
start: 开始条码识别
cancel: 结束条码识别
close: 关闭条码识别控件
setFlash: 是否开启闪光灯
和两个事件:
onmarked: 条码识别成功事件
onerror: 条码识别错误事件
function plusReady() {
if(ws || !window.plus || !domready) {
return;
}
// 获取窗口对象
ws = plus.webview.currentWebview();
// 开始扫描
ws.addEventListener('show', function() {
scan = new plus.barcode.Barcode('bcid');
// 定义识别成功事件
scan.onmarked = onmarked;
// 定义开始条码识别
scan.start({
conserve: true, // 是否保存成功扫描到的条码数据时的截图
filename: '_doc/barcode/' // 保存成功扫描到的条码数据时的图片路径
});
}, false);
// 显示页面并关闭等待框
ws.show('pop-in');
}
// 二维码扫描成功
function onmarked(type, result, file) {
switch(type) {
case plus.barcode.QR:
type = 'QR';
break;
case plus.barcode.EAN13:
type = 'EAN13';
break;
case plus.barcode.EAN8:
type = 'EAN8';
break;
default:
type = '其它' + type;
break;
}
result = result.replace(/\n/g, '');
plus.nativeUI.alert('扫描结果:' + JSON.stringify(result), function() {
console.log('扫描成功')
}, "helloW2A", "OK");
back();
}
2.从相册中选择图片识别,涉及到Gallery模块,具体参数设置可参考5+ API:Gallery
// 从相册中选择二维码图片
function scanPicture() {
plus.gallery.pick(function(path) {
plus.barcode.scan(path, onmarked, function(error) {
plus.nativeUI.alert('无法识别此图片');
});
}, function(err) {
console.log('Failed: ' + err.message);
});
}
3.DOM结构参考
<body style="background-color: #000000;">
<!--指定Barcode对象的在界面中关联div标签的id号。-->
<div id="bcid">
<div style="height:40%"></div>
<p class="tip">...载入中...</p>
</div>
<footer>
<div class="fbt" onclick="back()">取 消</div> <!--退出页面-->
<div class="fbt" onclick="scanPicture()">从相册选择二维码</div>
</footer>
</body>
示例工程已上传,供开发者参考
收起阅读 »
iOS中个推SDK升级
原文链接:
iOS中5+SDK项目升级个推静态库.a为.framework
说明
上篇写了升级5+SDK的文章:
iOS离线打包项目升级5+SDK
本文属于上文补充,因为要适配iPhone X,原谅我穷买不起真机,只能用模拟机调试,在调试过程中发现一个个推致命的bug:
malloc: error for object 0x170242490: Invalid pointer dequeued from free list set a breakpoint in malloc_error_break to debug
1
查资料后发现,是个推在模拟器上运行的产生的错误,我使用的是1.6.3-SDK。他们已经在最新SDK中修改了这个错误。
问题:个推静态库文件导致模拟机崩溃
解决办法:升级个推静态库文件为最新
新问题:
个推老版本使用的都是.a格式的静态库文件,而从官网下载下来的最新SDK使用的是.framework格式。如何平滑替换?
开工
(1)备份项目(这是我开始大改动必须的工作)
(2)删除5+SDK中Feature-iOS中指定的静态库文件
liblibPush.a
libGeTuiPush.a
libGeTuiSdk.a
libGtExtensionSdk
(3)将最新SDK中相应库文件复制到.a文件相应的位置,方便管理。我使用的文件如下图:
选择noidfa文件
引入后在项目中Build Phase -> Link Binary With Libraries引入framework库到项目中
(4)添加系统依赖库
根据个推官网添加系统依赖库,如图所示:
添加系统依赖库
(5)5+SDK中LinkerFlags不变
(6)删除原项目中GeTuiSdk.h文件,导入头文件:
import <GTSDK/GeTuiSdk.h>
1
(7)将插件部分用到的方法名更换为最新即可
-
(void) bindAlias:(PGMethod )cmds {
NSString alias = [cmds.arguments objectAtIndex:1];
[GeTuiSdk bindAlias:alias andSequenceNum:@"seq-1"];
} -
(void) unbindAlias:(PGMethod )cmds {
NSString alias = [cmds.arguments objectAtIndex:1];
[GeTuiSdk clearAllNotificationForNotificationBar];
[GeTuiSdk unbindAlias:alias andSequenceNum:@"seq-1" andIsSelf:YES];
}
原文链接:
iOS中5+SDK项目升级个推静态库.a为.framework
说明
上篇写了升级5+SDK的文章:
iOS离线打包项目升级5+SDK
本文属于上文补充,因为要适配iPhone X,原谅我穷买不起真机,只能用模拟机调试,在调试过程中发现一个个推致命的bug:
malloc: error for object 0x170242490: Invalid pointer dequeued from free list set a breakpoint in malloc_error_break to debug
1
查资料后发现,是个推在模拟器上运行的产生的错误,我使用的是1.6.3-SDK。他们已经在最新SDK中修改了这个错误。
问题:个推静态库文件导致模拟机崩溃
解决办法:升级个推静态库文件为最新
新问题:
个推老版本使用的都是.a格式的静态库文件,而从官网下载下来的最新SDK使用的是.framework格式。如何平滑替换?
开工
(1)备份项目(这是我开始大改动必须的工作)
(2)删除5+SDK中Feature-iOS中指定的静态库文件
liblibPush.a
libGeTuiPush.a
libGeTuiSdk.a
libGtExtensionSdk
(3)将最新SDK中相应库文件复制到.a文件相应的位置,方便管理。我使用的文件如下图:
选择noidfa文件
引入后在项目中Build Phase -> Link Binary With Libraries引入framework库到项目中
(4)添加系统依赖库
根据个推官网添加系统依赖库,如图所示:
添加系统依赖库
(5)5+SDK中LinkerFlags不变
(6)删除原项目中GeTuiSdk.h文件,导入头文件:
import <GTSDK/GeTuiSdk.h>
1
(7)将插件部分用到的方法名更换为最新即可
-
(void) bindAlias:(PGMethod )cmds {
NSString alias = [cmds.arguments objectAtIndex:1];
[GeTuiSdk bindAlias:alias andSequenceNum:@"seq-1"];
} -
(void) unbindAlias:(PGMethod )cmds {
NSString alias = [cmds.arguments objectAtIndex:1];
[GeTuiSdk clearAllNotificationForNotificationBar];
[GeTuiSdk unbindAlias:alias andSequenceNum:@"seq-1" andIsSelf:YES];
}

使用 uploader 进行七牛图片上传
.
说明
我是七牛的忠实拥趸。
个人网站、公司项目,文件和图片的存储方案使用的都是七牛。
这两天在封装 DC 的七牛图片上传,遇到了点问题,不过最后还是解决了。
这里只分享下简单的思路和代码。
.
开发思路
- 生成七牛上传令牌
因为有安全隐患,七牛官方推荐开发者向自己的业务服务器发送 ajax 进行获取。
我在贴出的代码中略过了这一步,你们自己处理。
. - 选取图片
使用摄像头(plus.camera)或者相册(plus.gallery)都可以。
. - 上传图片
最主要就是设置 “令牌”、“图片名称” 等参数。
不过需要的注意就是添加文件(addFile)后面一定要加 {"key":"file"},这是固定值,不要改,别问我为什么。
.
// 从相册获取图片
plus.gallery.pick(function(ret){
// 获取图片名称
var path = ret;
var file = ret.substr(ret.lastIndexOf("/")+1);
var token = "xxxxxxx"; // 填写你的七牛上传令牌
// 上传图片
var url = "http://upload.qiniu.com/";
var uploader = plus.uploader.createUpload(url,{},function(up,state){
if( state==200 )
Console("上传成功");
else
Console("上传失败 - ",state);
});
uploader.addData("key",file);
uploader.addData("token",token);
uploader.addFile(path,{"key":"file"}); // 固定值,千万不要改!!!!!!
uploader.start();
});
.
说明
我是七牛的忠实拥趸。
个人网站、公司项目,文件和图片的存储方案使用的都是七牛。
这两天在封装 DC 的七牛图片上传,遇到了点问题,不过最后还是解决了。
这里只分享下简单的思路和代码。
.
开发思路
- 生成七牛上传令牌
因为有安全隐患,七牛官方推荐开发者向自己的业务服务器发送 ajax 进行获取。
我在贴出的代码中略过了这一步,你们自己处理。
. - 选取图片
使用摄像头(plus.camera)或者相册(plus.gallery)都可以。
. - 上传图片
最主要就是设置 “令牌”、“图片名称” 等参数。
不过需要的注意就是添加文件(addFile)后面一定要加 {"key":"file"},这是固定值,不要改,别问我为什么。
.
// 从相册获取图片
plus.gallery.pick(function(ret){
// 获取图片名称
var path = ret;
var file = ret.substr(ret.lastIndexOf("/")+1);
var token = "xxxxxxx"; // 填写你的七牛上传令牌
// 上传图片
var url = "http://upload.qiniu.com/";
var uploader = plus.uploader.createUpload(url,{},function(up,state){
if( state==200 )
Console("上传成功");
else
Console("上传失败 - ",state);
});
uploader.addData("key",file);
uploader.addData("token",token);
uploader.addFile(path,{"key":"file"}); // 固定值,千万不要改!!!!!!
uploader.start();
});
收起阅读 »

分享MUI搜索框动态赋值样式问题
项目中用到了MUI input search框
在动态赋值的时候没有获取焦点,所以搜素框里面的图标和placeholder文字都没有变,会重叠覆盖。
经过火狐调试官方input.html,查看在获取焦点的时候添加了mui-active 这个class
代码:<div class="mui-input-row mui-search mui-active>
<input class="mui-input-clear" placeholder="" data-input-clear="1" data-input-search="1" type="search"><span class="mui-icon mui-icon-clear mui-hidden"></span><span class="mui-placeholder"><span class="mui-icon mui-icon-search"></span><span></span></span>
</div>
所以大家以后在用到动态赋值的时候把值更新后,再控制下mui-active这个class是否添加就好了
大家以后遇到问题也不要过度依赖论坛,先自己试试看能否解决,实在没有办法再搜索
项目中用到了MUI input search框
在动态赋值的时候没有获取焦点,所以搜素框里面的图标和placeholder文字都没有变,会重叠覆盖。
经过火狐调试官方input.html,查看在获取焦点的时候添加了mui-active 这个class
代码:<div class="mui-input-row mui-search mui-active>
<input class="mui-input-clear" placeholder="" data-input-clear="1" data-input-search="1" type="search"><span class="mui-icon mui-icon-clear mui-hidden"></span><span class="mui-placeholder"><span class="mui-icon mui-icon-search"></span><span></span></span>
</div>
所以大家以后在用到动态赋值的时候把值更新后,再控制下mui-active这个class是否添加就好了
大家以后遇到问题也不要过度依赖论坛,先自己试试看能否解决,实在没有办法再搜索
收起阅读 »
【分享】快速获取matchUrls可用的匹配依据的值
需求简述
在 wap2app 开发中,matchUrls 可以使用多种匹配依据来匹配目标 page。
部分开发者对Location对象不够熟悉,不知道应该去匹配哪个部分,才能正确匹配到目标 page。
解决方案
准备工作
- 在电脑上打开浏览器,最好是chrome
- 访问要适配的 wap 站,F12打开控制台,并且切换到手机模式
- 跳转到目标地址,也就是要匹配的地址
方案一
在控制台执行下面的代码,会将所有可用的匹配依据的值,都 log 出来。
(function() {
var _location = window.location;
var props = ['hash', 'host', 'hostname', 'href', 'pathname', 'port', 'protocol', 'search'];
for(var i = 0, len = props.length; i < len; i++) {
console.log(props[i] + ':' + _location[props[i]]);
}
}());
方案二
也可以直接使用 console 本身的方法,以表格的形式将 window.location 的值展示出来。
console.table(window.location);
这个方法,会把所有的属性都列出来,找到可用的匹配依据的值就行了。
需求简述
在 wap2app 开发中,matchUrls 可以使用多种匹配依据来匹配目标 page。
部分开发者对Location对象不够熟悉,不知道应该去匹配哪个部分,才能正确匹配到目标 page。
解决方案
准备工作
- 在电脑上打开浏览器,最好是chrome
- 访问要适配的 wap 站,F12打开控制台,并且切换到手机模式
- 跳转到目标地址,也就是要匹配的地址
方案一
在控制台执行下面的代码,会将所有可用的匹配依据的值,都 log 出来。
(function() {
var _location = window.location;
var props = ['hash', 'host', 'hostname', 'href', 'pathname', 'port', 'protocol', 'search'];
for(var i = 0, len = props.length; i < len; i++) {
console.log(props[i] + ':' + _location[props[i]]);
}
}());
方案二
也可以直接使用 console 本身的方法,以表格的形式将 window.location 的值展示出来。
console.table(window.location);
这个方法,会把所有的属性都列出来,找到可用的匹配依据的值就行了。
收起阅读 »
iOS离线打包项目升级5+SDK
原文链接:iOS离线打包项目升级5+SDK
(1)替换SDK
用最新SDK文件替换项目中SDK
(2) 将PandoraApi.bundle引入项目,引入时候勾选项如下图:
引入PandoraApi.bundle
(3) 将PandoraApi.bundle中feature.plist文件用原来项目中替换,当然如果没有写过插件,应该不需要。
(4)导入inc文件到项目中,打开SDK所在目录,拖动到项目中相应位置,此处,因我原生不会改动,所以设置如下:
导入inc文件
(5)修改control.xml中对应的appid等,修改时要注意和www文件中manifest.json文件中对应字段要完全一致,如下图:
修改control.xml文件
(6)导入相应的依赖库,及项目中相关设置,此处注意,下图中红框标注libcoreSupport.a文件一定要导入,否则会报错,当然还有其他库依赖的问题,可以根据提示解决。
项目中相关设置
(7)根据SDK最新demo,修改本项目中的主控制器中启动5+SDK的相关代码,我的启动位置在ViewController.m中,故更新为最新即可,由于适配了iPhone X有改动,需留意!
(8)到此处,文件配置基本没问题了,现在是不是可以启动应用了呢?哈哈哈,启动下试试吧,beng~,呃呃呃,程序是可以启动了,但是卡顿在index页面了,www文件我没有更改,不可能出错啊。用Safari调试后发现,是调用插件地方报错,怎么会这样?升级前是好好的,郁闷中~~
(9)最新SDK中注册插件有变动
最新SDK中注册插件不在document.addEventListener(‘plusready’)方法中了,直接注册即可。好程序可以启动了,恭喜��
(10)等等等,啊啊啊啊,报错,搜索了下,个推静态库在模拟机上报错,这个,这个,我只有模拟机,穷的买不起真机测试啊,啊啊啊啊,老板,我要真机,我要iPhone X。。。还是算了,升级个推SDK吧。升级这块在本文中不赘述,后期补充一篇文章,因为需要将本项目中.a静态库替换成个推最新的.frameworks框架了。
(11)血的教训!!!
最新的SDK注册插件不需要document.addEventListener(“plusready”, function(){},true);中注册插件,直接放外面注册就可以了
方法调用最好还是放在plusready事件之后, 是document.addEventListener(‘plusready’) ,不要用mui.plusready,或者直接加一个timeout也可以
(12)原生调用webview方式有变动
原来原生调用webview中需要根据id遍历查找,如下代码:
NSArray frames = [[[[PDRCore Instance] appManager] activeApp] appWindow].allFrames;
for (PDRCoreAppFrame frame in frames)
if ([frame.frameName isEqualToString:@"rmsNews"]){
[frame stringByEvaluatingJavaScriptFromString:@"initChat()"];
}
改成如下方式即可:
PDRCoreAppWindow appWindow = [[[[PDRCore Instance] appManager] activeApp] appWindow];
PDRCoreAppFrame frame = [appWindow getFrameByName:@"rmsNews"];
//同步
[frame stringByEvaluatingJavaScriptFromString:@"initChat()"];
//或者可以用异步
[frame evaluateJavaScript:@"initChat()" completionHandler:^(id result, NSError *error) {
}];
总结
升级之后,页面自动适配了iPhone X,同时运行流畅度和页面反应速度都有很大提升,感觉5+做的越来越好,虽然苹果在封杀类似这种混合式开发,但是不可否认,存在即合理,希望5+做的越来越好。
原文链接:iOS离线打包项目升级5+SDK
(1)替换SDK
用最新SDK文件替换项目中SDK
(2) 将PandoraApi.bundle引入项目,引入时候勾选项如下图:
引入PandoraApi.bundle
(3) 将PandoraApi.bundle中feature.plist文件用原来项目中替换,当然如果没有写过插件,应该不需要。
(4)导入inc文件到项目中,打开SDK所在目录,拖动到项目中相应位置,此处,因我原生不会改动,所以设置如下:
导入inc文件
(5)修改control.xml中对应的appid等,修改时要注意和www文件中manifest.json文件中对应字段要完全一致,如下图:
修改control.xml文件
(6)导入相应的依赖库,及项目中相关设置,此处注意,下图中红框标注libcoreSupport.a文件一定要导入,否则会报错,当然还有其他库依赖的问题,可以根据提示解决。
项目中相关设置
(7)根据SDK最新demo,修改本项目中的主控制器中启动5+SDK的相关代码,我的启动位置在ViewController.m中,故更新为最新即可,由于适配了iPhone X有改动,需留意!
(8)到此处,文件配置基本没问题了,现在是不是可以启动应用了呢?哈哈哈,启动下试试吧,beng~,呃呃呃,程序是可以启动了,但是卡顿在index页面了,www文件我没有更改,不可能出错啊。用Safari调试后发现,是调用插件地方报错,怎么会这样?升级前是好好的,郁闷中~~
(9)最新SDK中注册插件有变动
最新SDK中注册插件不在document.addEventListener(‘plusready’)方法中了,直接注册即可。好程序可以启动了,恭喜��
(10)等等等,啊啊啊啊,报错,搜索了下,个推静态库在模拟机上报错,这个,这个,我只有模拟机,穷的买不起真机测试啊,啊啊啊啊,老板,我要真机,我要iPhone X。。。还是算了,升级个推SDK吧。升级这块在本文中不赘述,后期补充一篇文章,因为需要将本项目中.a静态库替换成个推最新的.frameworks框架了。
(11)血的教训!!!
最新的SDK注册插件不需要document.addEventListener(“plusready”, function(){},true);中注册插件,直接放外面注册就可以了
方法调用最好还是放在plusready事件之后, 是document.addEventListener(‘plusready’) ,不要用mui.plusready,或者直接加一个timeout也可以
(12)原生调用webview方式有变动
原来原生调用webview中需要根据id遍历查找,如下代码:
NSArray frames = [[[[PDRCore Instance] appManager] activeApp] appWindow].allFrames;
for (PDRCoreAppFrame frame in frames)
if ([frame.frameName isEqualToString:@"rmsNews"]){
[frame stringByEvaluatingJavaScriptFromString:@"initChat()"];
}
改成如下方式即可:
PDRCoreAppWindow appWindow = [[[[PDRCore Instance] appManager] activeApp] appWindow];
PDRCoreAppFrame frame = [appWindow getFrameByName:@"rmsNews"];
//同步
[frame stringByEvaluatingJavaScriptFromString:@"initChat()"];
//或者可以用异步
[frame evaluateJavaScript:@"initChat()" completionHandler:^(id result, NSError *error) {
}];
总结
升级之后,页面自动适配了iPhone X,同时运行流畅度和页面反应速度都有很大提升,感觉5+做的越来越好,虽然苹果在封杀类似这种混合式开发,但是不可否认,存在即合理,希望5+做的越来越好。