HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

个推与华为深度合作,成为首批支持兼容HarmonyOS NEXT的服务商

个推SDK 消息推送 鸿蒙next 华为


自华为官方宣布HarmonyOS NEXT鸿蒙星河版开放申请以来,越来越多的头部APP宣布启动鸿蒙原生开发,鸿蒙生态也随之进入全新发展的第二阶段。

作为华为鸿蒙生态的重要合作伙伴,个推一直积极参与鸿蒙生态建设。为帮助用户在HarmonyOS NEXT上持续享有智能互联的丰富体验,个推消息推送服务完成了对HarmonyOS NEXT的兼容适配,以支持开发者更加高效地进行鸿蒙原生应用开发。

个推消息推送SDK鸿蒙版本不仅具有高并发、高速度、高可靠等性能优势,能够有效满足APP开发者的大规模用户实时触达需求,还将面向开发者继续提供大数据标签推送、文案圈人模型等数智能力,助力开发者打造智能、友好、人性化的鸿蒙应用体验。

此外,个推也正在加快推进整体开发者服务和数智运营解决方案在鸿蒙生态中的全面落地,以更好地帮助开发者实现针对全域用户的精细化运营管理,助力APP客户的商业价值增长。

继续阅读 »


自华为官方宣布HarmonyOS NEXT鸿蒙星河版开放申请以来,越来越多的头部APP宣布启动鸿蒙原生开发,鸿蒙生态也随之进入全新发展的第二阶段。

作为华为鸿蒙生态的重要合作伙伴,个推一直积极参与鸿蒙生态建设。为帮助用户在HarmonyOS NEXT上持续享有智能互联的丰富体验,个推消息推送服务完成了对HarmonyOS NEXT的兼容适配,以支持开发者更加高效地进行鸿蒙原生应用开发。

个推消息推送SDK鸿蒙版本不仅具有高并发、高速度、高可靠等性能优势,能够有效满足APP开发者的大规模用户实时触达需求,还将面向开发者继续提供大数据标签推送、文案圈人模型等数智能力,助力开发者打造智能、友好、人性化的鸿蒙应用体验。

此外,个推也正在加快推进整体开发者服务和数智运营解决方案在鸿蒙生态中的全面落地,以更好地帮助开发者实现针对全域用户的精细化运营管理,助力APP客户的商业价值增长。

收起阅读 »

NXCLOUD牛信云——国际短信验证码服务商,专享通道,即时送达

即时通信

一、什么是国际短信验证码?

国际短信验证码很好理解,就是用户在进行注册、登录或修改密码等操作的时候,都需要验证码确认操作是否属于本人的一个安全验证方式。这种验证方式目前广泛运用于众多APP中,不仅是出海企业,更是众多海外用户所信赖的验证方式。

二、牛信云出海国际短信验证码的功能有哪些?

①助力海外用户快速登录账号:在出海国际短信验证码还未使用到账号登录中时,人们都是进行账号和密码登录,同时通过图形或字母等验证方式进行辅助保障,过程十分繁琐,海外用户很难做到在短时间内实现账号登录。出海国际短信验证码的诞生帮助人们解决了一部分登录难题,海外用户现在登录APP账号,只需要输入手机号码,然后获取验证码,将正确的验证码填入,即可成功登录。这种登录方式不仅方便且十分快捷,深受众多海外用户喜爱。

②保障海外用户的账号安全:在人们心中,出海国际短信验证码较大的作用便是其可以很好地保障海外用户的账号安全。海外用户不管是在登录账号、密码修改,或是在操作账号变更等情况,只要海外用户的验证码不泄露,账号的安全性能还是很高的。这都是得益于手机号码实行一机一码制,海外用户无论是在操作哪些机密设置时,都是需要依靠出海国际短信验证码验证,其安全性还是很强的。

③防止海外用户恶意注册:以往出海企业在推出新APP的时候,总有针对新用户发送一些福利,而这个时候总有些非法分子想要薅取出海企业羊毛,不断申请注册新账号领取福利,出海企业发现这个漏洞却无法弥补,出海国际短信验证码的诞生,则很好地帮助了出海企业有效制止此类事件。现在企业发放对新用户的福利,一个手机号码只能领取一次,无法再实现重复领取。不仅有效防止了用户恶意注册,还保障了出海企业的利益。

牛信云以科技为基础,以产品为驱动,通过开放API接口,将底层通信能力SDK化,向开发者及企业级用户提供安全、稳定、可靠的一站式出海云通信服务。为了方便开发者调用,牛信云还为跨境电商、出海游戏、在线会议、在线社交、视频直播、金融支付、本地生活等行业提供不同的场景化解决方案,将通信云技术普惠化和实用化,助力中国品牌迅速拓展和占领海外市场,实现高效出海。

面对充满竞争与瞬息万变的全球市场,牛信云积极拥抱变化,始终为进步和卓越而努力,以出海通信为基石,争分夺秒地沿着数字化服务生态前进,推动业务与世界不懈向前,为中国出海企业提供一站式的通信解决方案,与合作伙伴一道,共同前进。

继续阅读 »

一、什么是国际短信验证码?

国际短信验证码很好理解,就是用户在进行注册、登录或修改密码等操作的时候,都需要验证码确认操作是否属于本人的一个安全验证方式。这种验证方式目前广泛运用于众多APP中,不仅是出海企业,更是众多海外用户所信赖的验证方式。

二、牛信云出海国际短信验证码的功能有哪些?

①助力海外用户快速登录账号:在出海国际短信验证码还未使用到账号登录中时,人们都是进行账号和密码登录,同时通过图形或字母等验证方式进行辅助保障,过程十分繁琐,海外用户很难做到在短时间内实现账号登录。出海国际短信验证码的诞生帮助人们解决了一部分登录难题,海外用户现在登录APP账号,只需要输入手机号码,然后获取验证码,将正确的验证码填入,即可成功登录。这种登录方式不仅方便且十分快捷,深受众多海外用户喜爱。

②保障海外用户的账号安全:在人们心中,出海国际短信验证码较大的作用便是其可以很好地保障海外用户的账号安全。海外用户不管是在登录账号、密码修改,或是在操作账号变更等情况,只要海外用户的验证码不泄露,账号的安全性能还是很高的。这都是得益于手机号码实行一机一码制,海外用户无论是在操作哪些机密设置时,都是需要依靠出海国际短信验证码验证,其安全性还是很强的。

③防止海外用户恶意注册:以往出海企业在推出新APP的时候,总有针对新用户发送一些福利,而这个时候总有些非法分子想要薅取出海企业羊毛,不断申请注册新账号领取福利,出海企业发现这个漏洞却无法弥补,出海国际短信验证码的诞生,则很好地帮助了出海企业有效制止此类事件。现在企业发放对新用户的福利,一个手机号码只能领取一次,无法再实现重复领取。不仅有效防止了用户恶意注册,还保障了出海企业的利益。

牛信云以科技为基础,以产品为驱动,通过开放API接口,将底层通信能力SDK化,向开发者及企业级用户提供安全、稳定、可靠的一站式出海云通信服务。为了方便开发者调用,牛信云还为跨境电商、出海游戏、在线会议、在线社交、视频直播、金融支付、本地生活等行业提供不同的场景化解决方案,将通信云技术普惠化和实用化,助力中国品牌迅速拓展和占领海外市场,实现高效出海。

面对充满竞争与瞬息万变的全球市场,牛信云积极拥抱变化,始终为进步和卓越而努力,以出海通信为基石,争分夺秒地沿着数字化服务生态前进,推动业务与世界不懈向前,为中国出海企业提供一站式的通信解决方案,与合作伙伴一道,共同前进。

收起阅读 »

软件发布-Go To YouTube Website

Go To YouTube Website发布!

仅在DCloud,bilibili与oschina发布

支持Android平台

放出源码:

源码:

<!DOCTYPE html>  
<html>  
<body>  
<head>  
    <meta charset="utf-8">  
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
    <title>Go To YouTube Website</title>  
    <script type="text/javascript">  

        document.addEventListener('plusready', function(){  
            //console.log("所有plus api都应该在此事件发生后调用,否则会出现plus is undefined。")  

            <script language="javascript"> location.replace("http://www.youtube.com") </script>  
        });  

    </script>  
</head>   
</body>  
</html>

(要安装文件私信我)

继续阅读 »

Go To YouTube Website发布!

仅在DCloud,bilibili与oschina发布

支持Android平台

放出源码:

源码:

<!DOCTYPE html>  
<html>  
<body>  
<head>  
    <meta charset="utf-8">  
    <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
    <title>Go To YouTube Website</title>  
    <script type="text/javascript">  

        document.addEventListener('plusready', function(){  
            //console.log("所有plus api都应该在此事件发生后调用,否则会出现plus is undefined。")  

            <script language="javascript"> location.replace("http://www.youtube.com") </script>  
        });  

    </script>  
</head>   
</body>  
</html>

(要安装文件私信我)

收起阅读 »

网约车APP定制开发搭建

App

网约车APP制作核心功能:
1.多种出行方式:网约车APP的出行选择可以有专车出行、快车出行、拼车出行。
2.预估车费:选择出发地点和出发目的地,可以直接计算出行程、时间和车费。
3.预约用车:若用户在未来几个小时候有需要用车,可以提前预约时间段,可以让司机师傅去上车地点接人。
4.查看司机:打开APP即可查看用户自身离周边近有多少车辆。
5.账户充值:APP可以出一些优惠活动,引导用户充值,让用户更加省钱车行。
6.评估服务:可以根据用户提供的建议弥补平台的不足,从而更精进app服务。
7.线上支付:用户可以根据自己合适的支付方式,选择扣除车费。
8.地图导航:用可以通过APP定位知道自己当前的位置和要去的目的地,司机师傅可以根据用户定位上车地点前去接客户上车,两者都可以显示具体的距离和时间。

继续阅读 »

网约车APP制作核心功能:
1.多种出行方式:网约车APP的出行选择可以有专车出行、快车出行、拼车出行。
2.预估车费:选择出发地点和出发目的地,可以直接计算出行程、时间和车费。
3.预约用车:若用户在未来几个小时候有需要用车,可以提前预约时间段,可以让司机师傅去上车地点接人。
4.查看司机:打开APP即可查看用户自身离周边近有多少车辆。
5.账户充值:APP可以出一些优惠活动,引导用户充值,让用户更加省钱车行。
6.评估服务:可以根据用户提供的建议弥补平台的不足,从而更精进app服务。
7.线上支付:用户可以根据自己合适的支付方式,选择扣除车费。
8.地图导航:用可以通过APP定位知道自己当前的位置和要去的目的地,司机师傅可以根据用户定位上车地点前去接客户上车,两者都可以显示具体的距离和时间。

收起阅读 »

5+ api videoplayer objectFit:'cover' 属性不起作用,有黑边问题

VideoPlayer

将 objectFit:'cover' 改成 'object-fit':'cover'

将 objectFit:'cover' 改成 'object-fit':'cover'

【真BUG】官方文档小技巧

文档

今天开始学习插件开发,应该是官方怕我们学会,搞的莫名奇妙,这个官方的demo

! function(root, factory) {    
    if (typeof exports == 'object' && typeof module != 'undefined') {    
        module.exports = factory()    
    } else if (typeof define == 'function' && define.amd) {    
        define(factory)    
    } else {    
        /**    
         * 插件对象直接扩展到 window 对象上    
         * 这个对象的名字,需要自己填写一下。例如:plugintest    
         */    
        var moduleName = 'plugintest';    
        root[moduleName] = factory()    
    }    
}(this, function() {    
    var _BARCODE = 'plugintest';    
    var plugintest = {    
        PluginTestFunction: function(Argus1, Argus2, Argus3, Argus4, successCallback, errorCallback) {    
            var success = typeof successCallback !== 'function' ? null : function(args) {    
                    successCallback(args);    
                },    
                fail = typeof errorCallback !== 'function' ? null : function(code) {    
                    errorCallback(code);    
                };    
            callbackID = plus.bridge.callbackId(success, fail);    

            return plus.bridge.exec(_BARCODE, "PluginTestFunction", [callbackID, Argus1, Argus2, Argus3, Argus4]);    
        },    
        PluginTestFunctionArrayArgu: function(Argus, successCallback, errorCallback) {    
            var success = typeof successCallback !== 'function' ? null : function(args) {    
                    successCallback(args);    
                },    
                fail = typeof errorCallback !== 'function' ? null : function(code) {    
                    errorCallback(code);    
                };    
            callbackID = plus.bridge.callbackId(success, fail);    
            return plus.bridge.exec(_BARCODE, "PluginTestFunctionArrayArgu", [callbackID, Argus]);    
        },    
        PluginTestFunctionSync: function(Argus1, Argus2, Argus3, Argus4) {    
            return plus.bridge.execSync(_BARCODE, "PluginTestFunctionSync", [Argus1, Argus2, Argus3, Argus4]);    
        },    
        PluginTestFunctionSyncArrayArgu: function(Argus) {    
            return plus.bridge.execSync(_BARCODE, "PluginTestFunctionSyncArrayArgu", [Argus]);    
        }    
    };    
    return plugintest;    
});

我粘贴复制都跑不起来,研究半天,后面自己写,其实就用了plus.bridge.exec(_BARCODE, "PluginTestFunctionArrayArgu", [callbackID, Argus]); 这一句就可以了,简直扯淡!

继续阅读 »

今天开始学习插件开发,应该是官方怕我们学会,搞的莫名奇妙,这个官方的demo

! function(root, factory) {    
    if (typeof exports == 'object' && typeof module != 'undefined') {    
        module.exports = factory()    
    } else if (typeof define == 'function' && define.amd) {    
        define(factory)    
    } else {    
        /**    
         * 插件对象直接扩展到 window 对象上    
         * 这个对象的名字,需要自己填写一下。例如:plugintest    
         */    
        var moduleName = 'plugintest';    
        root[moduleName] = factory()    
    }    
}(this, function() {    
    var _BARCODE = 'plugintest';    
    var plugintest = {    
        PluginTestFunction: function(Argus1, Argus2, Argus3, Argus4, successCallback, errorCallback) {    
            var success = typeof successCallback !== 'function' ? null : function(args) {    
                    successCallback(args);    
                },    
                fail = typeof errorCallback !== 'function' ? null : function(code) {    
                    errorCallback(code);    
                };    
            callbackID = plus.bridge.callbackId(success, fail);    

            return plus.bridge.exec(_BARCODE, "PluginTestFunction", [callbackID, Argus1, Argus2, Argus3, Argus4]);    
        },    
        PluginTestFunctionArrayArgu: function(Argus, successCallback, errorCallback) {    
            var success = typeof successCallback !== 'function' ? null : function(args) {    
                    successCallback(args);    
                },    
                fail = typeof errorCallback !== 'function' ? null : function(code) {    
                    errorCallback(code);    
                };    
            callbackID = plus.bridge.callbackId(success, fail);    
            return plus.bridge.exec(_BARCODE, "PluginTestFunctionArrayArgu", [callbackID, Argus]);    
        },    
        PluginTestFunctionSync: function(Argus1, Argus2, Argus3, Argus4) {    
            return plus.bridge.execSync(_BARCODE, "PluginTestFunctionSync", [Argus1, Argus2, Argus3, Argus4]);    
        },    
        PluginTestFunctionSyncArrayArgu: function(Argus) {    
            return plus.bridge.execSync(_BARCODE, "PluginTestFunctionSyncArrayArgu", [Argus]);    
        }    
    };    
    return plugintest;    
});

我粘贴复制都跑不起来,研究半天,后面自己写,其实就用了plus.bridge.exec(_BARCODE, "PluginTestFunctionArrayArgu", [callbackID, Argus]); 这一句就可以了,简直扯淡!

收起阅读 »

html5 5+sdk启动白屏

WEBSOCKET

  目前两个项目是html加原生一起开发,主要是html,html运用的是hbulider,里面有一个套成型的mui,原生这边主要是做一些插件之类的,html不能满足的功能,不知道是这个sdk适配的不怎么完美还是什么原因,总有一些问题,下面是我遇到的问题:
  
  标题
  
  ==启动白屏
  
  这个应该是android原生的问题,原生好处理,加载html,利用这个5+sdk的框架,就会有一些问题,
  
  处理:添加一个启动界面,用原生,设置背景为透明,设置一个主题
  
  <style name="Login" parent="DCloudTheme" >
  
  <!--<item name="android:windowIsTranslucent">true</item>-->
  
  <item name="android:windowBackground">@drawable/splash</item>
  
  <item name="android:windowNoTitle">true</item>
  
  </style>
  
  进来不做任何处理,直接跳转sdkWebApp,我是用这个方式直接
  
  加载的项目。这个sdkwebapp的主题必须设置为dcloud,
  
  加载地图会出现黑屏
  
  这个项目里面有一个考勤界面,需要百度地图
  
  ,目前
  
  ios的不会出现跳转时黑屏的问题,android的不行,不知道后期更新会不会解决这个问题

继续阅读 »

  目前两个项目是html加原生一起开发,主要是html,html运用的是hbulider,里面有一个套成型的mui,原生这边主要是做一些插件之类的,html不能满足的功能,不知道是这个sdk适配的不怎么完美还是什么原因,总有一些问题,下面是我遇到的问题:
  
  标题
  
  ==启动白屏
  
  这个应该是android原生的问题,原生好处理,加载html,利用这个5+sdk的框架,就会有一些问题,
  
  处理:添加一个启动界面,用原生,设置背景为透明,设置一个主题
  
  <style name="Login" parent="DCloudTheme" >
  
  <!--<item name="android:windowIsTranslucent">true</item>-->
  
  <item name="android:windowBackground">@drawable/splash</item>
  
  <item name="android:windowNoTitle">true</item>
  
  </style>
  
  进来不做任何处理,直接跳转sdkWebApp,我是用这个方式直接
  
  加载的项目。这个sdkwebapp的主题必须设置为dcloud,
  
  加载地图会出现黑屏
  
  这个项目里面有一个考勤界面,需要百度地图
  
  ,目前
  
  ios的不会出现跳转时黑屏的问题,android的不行,不知道后期更新会不会解决这个问题

收起阅读 »

刚从apicloud转过来,分享一下看法吧

APICloud

非职业码农,算是爱好

apicloud有一个优点就是更简单,文档更易阅读。

过来这边因为我没有用小程序的需求,而且对自由性要求比较高,所以没用uni-app

目前看到的就是这边api更多,但是文档写得不好(一般吧)。
很多东西不需要重新打包。例如:改为沉浸式状态栏或非沉浸式。直接更新后重启一下就行了。apicloud那边app还得重新编译一下
APP启动速度超级快,我这边的程序0.6s就可以启动完毕,那边要3s

不过apicloud的扩展性也还行,绝大多数功能都有模块供你使用

转过来的原因是因为那边吃相太难看。APP安装量大于5w,月活大于1w就需要开通商业服务。5999元以上。以后人越多还越贵。最多是2w多(大概)
当然收费并非不行,主要是页面上根本没有告诉你后续需要开通商业服务。你得经常浏览他们的论坛才能知道。真恶心人

继续阅读 »

非职业码农,算是爱好

apicloud有一个优点就是更简单,文档更易阅读。

过来这边因为我没有用小程序的需求,而且对自由性要求比较高,所以没用uni-app

目前看到的就是这边api更多,但是文档写得不好(一般吧)。
很多东西不需要重新打包。例如:改为沉浸式状态栏或非沉浸式。直接更新后重启一下就行了。apicloud那边app还得重新编译一下
APP启动速度超级快,我这边的程序0.6s就可以启动完毕,那边要3s

不过apicloud的扩展性也还行,绝大多数功能都有模块供你使用

转过来的原因是因为那边吃相太难看。APP安装量大于5w,月活大于1w就需要开通商业服务。5999元以上。以后人越多还越贵。最多是2w多(大概)
当然收费并非不行,主要是页面上根本没有告诉你后续需要开通商业服务。你得经常浏览他们的论坛才能知道。真恶心人

收起阅读 »

笔记渲染x5杀掉进程,app退出不行要kill掉

Native.JS 5+sdk X5

小白的笔记
var Intent = plus.android.importClass("android.os.Process");
var pid = Intent.myPid()
console.log("进程id:"+pid)
Intent.killProcess(pid)

逻辑 提示杀掉,让用户重新打开
function 内核判断(){
if(寻找文本(plus.navigator.getUserAgent(),"MQQBrowser")!= -1 ){
console.log ("x5");
}else{
询问框_原生("需要重新打开app","内核加载(可能多次加载)","立即","稍后");
}
}
function 杀掉进程(){
var Intent = plus.android.importClass("android.os.Process");
var pid = Intent.myPid();
console.log("进程id:"+pid);
Intent.killProcess(pid);
}

继续阅读 »

小白的笔记
var Intent = plus.android.importClass("android.os.Process");
var pid = Intent.myPid()
console.log("进程id:"+pid)
Intent.killProcess(pid)

逻辑 提示杀掉,让用户重新打开
function 内核判断(){
if(寻找文本(plus.navigator.getUserAgent(),"MQQBrowser")!= -1 ){
console.log ("x5");
}else{
询问框_原生("需要重新打开app","内核加载(可能多次加载)","立即","稍后");
}
}
function 杀掉进程(){
var Intent = plus.android.importClass("android.os.Process");
var pid = Intent.myPid();
console.log("进程id:"+pid);
Intent.killProcess(pid);
}

收起阅读 »

5+ app 保存海报图片至手机相册

/**  
* this.posterUrl  海报 base64 图片  
*/  
let fileName = 'share'  
      var bitmap = new plus.nativeObj.Bitmap('share')  
      bitmap.loadBase64Data(this.posterUrl, function(e) {  
        console.log('加载Base64图片数据成功')  
        // 如果传入文件名称为空,则直接设置APP名称为文件名称  
        if (fileName === undefined) {  
          fileName = plus.runtime.name  
        }  

        fileName = fileName+ +(new Date) + '.png'  

        bitmap.save('_doc/' + fileName, {}, function(i) {  
          console.log('保存图片成功:' + JSON.stringify(i))  
          plus.gallery.save(i.target, function(e) {  
            console.log('保存图片成功:' + JSON.stringify(e))  
            Toast(`图片保存到:${e.file}`)  
          }, function() {  
            Toast(`图片保存失败`)  
          })  
        }, function(e) {  
          console.log('保存图片失败:' + JSON.stringify(e))  
          Toast(`图片保存失败`)  
        })  
      }, function(e) {  
        console.log('加载Base64图片数据失败:' + JSON.stringify(e))  
        Toast(`图片保存失败`)  
      })
继续阅读 »
/**  
* this.posterUrl  海报 base64 图片  
*/  
let fileName = 'share'  
      var bitmap = new plus.nativeObj.Bitmap('share')  
      bitmap.loadBase64Data(this.posterUrl, function(e) {  
        console.log('加载Base64图片数据成功')  
        // 如果传入文件名称为空,则直接设置APP名称为文件名称  
        if (fileName === undefined) {  
          fileName = plus.runtime.name  
        }  

        fileName = fileName+ +(new Date) + '.png'  

        bitmap.save('_doc/' + fileName, {}, function(i) {  
          console.log('保存图片成功:' + JSON.stringify(i))  
          plus.gallery.save(i.target, function(e) {  
            console.log('保存图片成功:' + JSON.stringify(e))  
            Toast(`图片保存到:${e.file}`)  
          }, function() {  
            Toast(`图片保存失败`)  
          })  
        }, function(e) {  
          console.log('保存图片失败:' + JSON.stringify(e))  
          Toast(`图片保存失败`)  
        })  
      }, function(e) {  
        console.log('加载Base64图片数据失败:' + JSON.stringify(e))  
        Toast(`图片保存失败`)  
      })
收起阅读 »

动态修改app应用图标

要求:5+SDK离线打包方式。 iOS 10.3及以上。
思路:在5+SDK离线工程中新增应用图标,在工程info.plist文件新增图标内容,新增一个原生页面(ViewControllers),在原生页面中写修改应用图标代码(步骤3),在js中通过跳转原生页面来修改应用图标,跳转原生页面代码(步骤4)。
安卓的思路也大致一样,通过跳转原生页面来操作应用图标修改。

  1. 配置icons,在工程中新增一个icons应用图标文件,并添加要更改的icon。(可添加多个尺寸和多种类型的icon)

  2. 配置info.plist

  1. 通过代码触发事件来修改应用图标。

    
    - (void)changeAppIconWithName:(NSString *)iconName {  
    if (![[UIApplication sharedApplication] supportsAlternateIcons]) {  
        return;  
    }  
    
    if ([iconName isEqualToString:@""]) {  
        iconName = nil;  
    }  
    [[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {  
        if (error) {  
            NSLog(@"更换app图标发生错误了 : %@",error);  
        }  
    }];  
    }  
    [self changeAppIconWithName:@"rain"];  


4.  js跳转原生页面  
/*  
  //ViewControllers为要跳转的原生页面  
            var newVCobj = plus.ios.newObject("ViewControllers");  
            var UIApplicationClass = plus.ios.importClass("UIApplication");  
            var UIAppObj = UIApplicationClass.sharedApplication();  
            var del = plus.ios.invoke(UIAppObj,"delegate");  
            var appWindowObj = plus.ios.invoke(del,"window");  
            var appRootController = plus.ios.invoke(appWindowObj,"rootViewController");  

            //从底部向上弹出方式跳转。  
            plus.ios.invoke(appRootController,"presentViewController:animated:completion:",newVCobj,"YES",null);  

            //带有原生导航的跳转方式,跳转动画为从右到左滑入。  
//          plus.ios.invoke(appRootController,"pushViewController:animated:",newVCobj,"YES");  

//如需传值  
//js注册通知进行js与oc传值  defaultsName为通知名, 1234为需要传的值,  原生实现通知方法进行值接收。  
            SetUserDefault("defaultsName", "1234");  

//注册通知进行js传值到oc界面  
        function SetUserDefault(key, value)    
        {    
            if (typeof value != 'undefined' && typeof key === "string")    
            {    
                var UserDefaultsClass = plus.ios.importClass("NSUserDefaults");    
                var standardUserDefaults = UserDefaultsClass.standardUserDefaults();    
                plus.ios.invoke(standardUserDefaults, "setObject:forKey:", value, key);    
                plus.ios.invoke(standardUserDefaults,"synchronize");    
            }    
        }   

//oc页面实现通知接收传值方法  
NSUserDefaults* pDefDefaults = [NSUserDefaults standardUserDefaults];  
    if (pDefDefaults) {  
        NSString* pString =  [pDefDefaults objectForKey:@"defaultsName"];  
        NSLog(@"这里是js通知所传的值:%@",pString);  
    }  

返过来,oc要给js传值也可以通过发送通知进行传值。  

*/  

demo:下方  
继续阅读 »

要求:5+SDK离线打包方式。 iOS 10.3及以上。
思路:在5+SDK离线工程中新增应用图标,在工程info.plist文件新增图标内容,新增一个原生页面(ViewControllers),在原生页面中写修改应用图标代码(步骤3),在js中通过跳转原生页面来修改应用图标,跳转原生页面代码(步骤4)。
安卓的思路也大致一样,通过跳转原生页面来操作应用图标修改。

  1. 配置icons,在工程中新增一个icons应用图标文件,并添加要更改的icon。(可添加多个尺寸和多种类型的icon)

  2. 配置info.plist

  1. 通过代码触发事件来修改应用图标。

    
    - (void)changeAppIconWithName:(NSString *)iconName {  
    if (![[UIApplication sharedApplication] supportsAlternateIcons]) {  
        return;  
    }  
    
    if ([iconName isEqualToString:@""]) {  
        iconName = nil;  
    }  
    [[UIApplication sharedApplication] setAlternateIconName:iconName completionHandler:^(NSError * _Nullable error) {  
        if (error) {  
            NSLog(@"更换app图标发生错误了 : %@",error);  
        }  
    }];  
    }  
    [self changeAppIconWithName:@"rain"];  


4.  js跳转原生页面  
/*  
  //ViewControllers为要跳转的原生页面  
            var newVCobj = plus.ios.newObject("ViewControllers");  
            var UIApplicationClass = plus.ios.importClass("UIApplication");  
            var UIAppObj = UIApplicationClass.sharedApplication();  
            var del = plus.ios.invoke(UIAppObj,"delegate");  
            var appWindowObj = plus.ios.invoke(del,"window");  
            var appRootController = plus.ios.invoke(appWindowObj,"rootViewController");  

            //从底部向上弹出方式跳转。  
            plus.ios.invoke(appRootController,"presentViewController:animated:completion:",newVCobj,"YES",null);  

            //带有原生导航的跳转方式,跳转动画为从右到左滑入。  
//          plus.ios.invoke(appRootController,"pushViewController:animated:",newVCobj,"YES");  

//如需传值  
//js注册通知进行js与oc传值  defaultsName为通知名, 1234为需要传的值,  原生实现通知方法进行值接收。  
            SetUserDefault("defaultsName", "1234");  

//注册通知进行js传值到oc界面  
        function SetUserDefault(key, value)    
        {    
            if (typeof value != 'undefined' && typeof key === "string")    
            {    
                var UserDefaultsClass = plus.ios.importClass("NSUserDefaults");    
                var standardUserDefaults = UserDefaultsClass.standardUserDefaults();    
                plus.ios.invoke(standardUserDefaults, "setObject:forKey:", value, key);    
                plus.ios.invoke(standardUserDefaults,"synchronize");    
            }    
        }   

//oc页面实现通知接收传值方法  
NSUserDefaults* pDefDefaults = [NSUserDefaults standardUserDefaults];  
    if (pDefDefaults) {  
        NSString* pString =  [pDefDefaults objectForKey:@"defaultsName"];  
        NSLog(@"这里是js通知所传的值:%@",pString);  
    }  

返过来,oc要给js传值也可以通过发送通知进行传值。  

*/  

demo:下方  
收起阅读 »