
原生Android制作精简打包SDK项目(Android Studio-V3.5)
因为之前已经开发了原生的Android项目,所以现在要集成uniapp开发的应用到原生里面,为了方便处理,只能自己制作一个可打包的SDK项目(语言表达不好,见谅哈)
我这边的Android Studio版本是3.5的,我用的是MacMini电脑,所以Android模拟器用的是网页MuMu。
1、按照正常的流程,我们新建一个基于Java语言开发的Android原生项目(可以正常运行起来的项目);
2、从uniapp官网下载最新的Android官方SDK项目
https://ask.dcloud.net.cn/article/103
3、然后我们打开官方SDK项目压缩包,项目列表如下:
4、我们打开SDK,里面的资源库和文件全在这里面,所以从这里面找文件即可;
5、我们把SDK->libs下面的lib.5plus.base-release.aar和uniapp-release.aar拖进我们Android原生项目的libs路径下
6、然后我们配置Android原生项目下的build.gradle(我这里直接是copy官方SDK->HBuilder-Integrate-AS项目下的build.gradle)
7、在build.gradle加入需要的一些第三方库
implementation 'com.android.support:appcompat-v7:29.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
/uniapp所需库-----------------------开始/
implementation 'com.android.support:recyclerview-v7:29.1.0'
implementation 'com.alibaba.android:bindingx-core:1.0.3'
implementation 'com.alibaba.android:bindingx_weex_plugin:1.0.3'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation "com.facebook.fresco:animated-gif:1.13.0"
/uniapp所需库-----------------------结束/
// 基座需要,必须添加
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.alibaba:fastjson:1.1.46.android'
8、接来下就是配置AndroidManifest.xml文件了;我们不需要添加什么特殊的东西,只要记住application的name要设置成android:name="io.dcloud.application.DCloudApplication"
9、然后设置启动页面就可以了
10、接下来就是重点了,把自己的uniapp导入到项目中;
(1)在原生Android项目的main下面创建assets文件夹,里面添加apps(注意是apps,不是app)和data两个子文件夹
(2)去官网的SDK项目中把data下面的全部文件copy到自己项目下的data文件夹下
(3)把uniapp生成的本地包项目导入到apps下面
(4)切记,一定要把data下面的dcloud_control.xml的appid改成项目id。否则是启动不了项目的
11、按照官方文档的提示,在drawable下面添加好icon、push和splash三张图片
12、运行项目就可以正常运行起来了。
因为我这里用的模板不是很多,所以添加的第三方库没有,这个按自己的需求去添加,我这边只是告诉如何自己创建SDK打包项目。
写的不算很好,高手勿喷。
因为之前已经开发了原生的Android项目,所以现在要集成uniapp开发的应用到原生里面,为了方便处理,只能自己制作一个可打包的SDK项目(语言表达不好,见谅哈)
我这边的Android Studio版本是3.5的,我用的是MacMini电脑,所以Android模拟器用的是网页MuMu。
1、按照正常的流程,我们新建一个基于Java语言开发的Android原生项目(可以正常运行起来的项目);
2、从uniapp官网下载最新的Android官方SDK项目
https://ask.dcloud.net.cn/article/103
3、然后我们打开官方SDK项目压缩包,项目列表如下:
4、我们打开SDK,里面的资源库和文件全在这里面,所以从这里面找文件即可;
5、我们把SDK->libs下面的lib.5plus.base-release.aar和uniapp-release.aar拖进我们Android原生项目的libs路径下
6、然后我们配置Android原生项目下的build.gradle(我这里直接是copy官方SDK->HBuilder-Integrate-AS项目下的build.gradle)
7、在build.gradle加入需要的一些第三方库
implementation 'com.android.support:appcompat-v7:29.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
/uniapp所需库-----------------------开始/
implementation 'com.android.support:recyclerview-v7:29.1.0'
implementation 'com.alibaba.android:bindingx-core:1.0.3'
implementation 'com.alibaba.android:bindingx_weex_plugin:1.0.3'
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation "com.facebook.fresco:animated-gif:1.13.0"
/uniapp所需库-----------------------结束/
// 基座需要,必须添加
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.alibaba:fastjson:1.1.46.android'
8、接来下就是配置AndroidManifest.xml文件了;我们不需要添加什么特殊的东西,只要记住application的name要设置成android:name="io.dcloud.application.DCloudApplication"
9、然后设置启动页面就可以了
10、接下来就是重点了,把自己的uniapp导入到项目中;
(1)在原生Android项目的main下面创建assets文件夹,里面添加apps(注意是apps,不是app)和data两个子文件夹
(2)去官网的SDK项目中把data下面的全部文件copy到自己项目下的data文件夹下
(3)把uniapp生成的本地包项目导入到apps下面
(4)切记,一定要把data下面的dcloud_control.xml的appid改成项目id。否则是启动不了项目的
11、按照官方文档的提示,在drawable下面添加好icon、push和splash三张图片
12、运行项目就可以正常运行起来了。
因为我这里用的模板不是很多,所以添加的第三方库没有,这个按自己的需求去添加,我这边只是告诉如何自己创建SDK打包项目。
写的不算很好,高手勿喷。

android中NJS方式使用原生录制视频
我们公司有业务要需要做限制拍摄时间的视频录制功能,官方提供的API太坑 太坑 太坑 太坑,压根不能用
感谢这位同行分享的代码:
https://ask.dcloud.net.cn/question/25816?item_id=108332&rf=false
我基于该分享的代码进行改进,成功在本地存储了mp4文件,望对大家有帮助
var Camera = plus.android.importClass('android.hardware.Camera')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceView = plus.android.importClass('android.view.SurfaceView')
,LinearLayout = plus.android.importClass('android.widget.LinearLayout')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceHolder = plus.android.implements('android.view.SurfaceHolder');
var mainActivity = plus.android.runtimeMainActivity()
,cameraView = new LinearLayout(mainActivity)
,surfaceView = new SurfaceView(mainActivity)
,cameraCount = Camera.getNumberOfCameras()
,cameraInfo = new Camera.CameraInfo()
,mediaRecorder = new MediaRecorder()
,cameraId = null
,camera = null
,surfaceHolder = null
,videoFilePath = plus.io.convertLocalFileSystemURL('_downloads/') + Date.now() + '.mp4';
//查询可用摄像头
for (var i = 0;i < cameraCount;i++) {
Camera.getCameraInfo(i, cameraInfo);
if(plus.android.getAttribute(cameraInfo, 'facing') !== cameraInfo.CAMERA_FACING_BACK) continue;
cameraId = i;
break;
}
if(cameraId === null) throw Error('无后置摄像头');
cameraView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
cameraView.addView(surfaceView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mainActivity.setContentView(cameraView);
camera = Camera.open(cameraId);
camera.setDisplayOrientation(90);
camera.unlock();
surfaceHolder = surfaceView.getHolder();
mediaRecorder.setCamera(camera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoSize(1280, 720);
mediaRecorder.setVideoFrameRate(20);
mediaRecorder.setPreviewDisplay(plus.android.invoke(surfaceHolder, 'getSurface'));
mediaRecorder.setOutputFile(videoFilePath);
mediaRecorder.prepare();
mediaRecorder.start();
//camera.release();
setTimeout(function(){
mediaRecorder.stop();
camera.release();
}, 3e3);
我们公司有业务要需要做限制拍摄时间的视频录制功能,官方提供的API太坑 太坑 太坑 太坑,压根不能用
感谢这位同行分享的代码:
https://ask.dcloud.net.cn/question/25816?item_id=108332&rf=false
我基于该分享的代码进行改进,成功在本地存储了mp4文件,望对大家有帮助
var Camera = plus.android.importClass('android.hardware.Camera')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceView = plus.android.importClass('android.view.SurfaceView')
,LinearLayout = plus.android.importClass('android.widget.LinearLayout')
,MediaRecorder = plus.android.importClass('android.media.MediaRecorder')
,SurfaceHolder = plus.android.implements('android.view.SurfaceHolder');
var mainActivity = plus.android.runtimeMainActivity()
,cameraView = new LinearLayout(mainActivity)
,surfaceView = new SurfaceView(mainActivity)
,cameraCount = Camera.getNumberOfCameras()
,cameraInfo = new Camera.CameraInfo()
,mediaRecorder = new MediaRecorder()
,cameraId = null
,camera = null
,surfaceHolder = null
,videoFilePath = plus.io.convertLocalFileSystemURL('_downloads/') + Date.now() + '.mp4';
//查询可用摄像头
for (var i = 0;i < cameraCount;i++) {
Camera.getCameraInfo(i, cameraInfo);
if(plus.android.getAttribute(cameraInfo, 'facing') !== cameraInfo.CAMERA_FACING_BACK) continue;
cameraId = i;
break;
}
if(cameraId === null) throw Error('无后置摄像头');
cameraView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
cameraView.addView(surfaceView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
mainActivity.setContentView(cameraView);
camera = Camera.open(cameraId);
camera.setDisplayOrientation(90);
camera.unlock();
surfaceHolder = surfaceView.getHolder();
mediaRecorder.setCamera(camera);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoSize(1280, 720);
mediaRecorder.setVideoFrameRate(20);
mediaRecorder.setPreviewDisplay(plus.android.invoke(surfaceHolder, 'getSurface'));
mediaRecorder.setOutputFile(videoFilePath);
mediaRecorder.prepare();
mediaRecorder.start();
//camera.release();
setTimeout(function(){
mediaRecorder.stop();
camera.release();
}, 3e3);

rich-text在h5下丢失样式解决办法
跟vue的v-html丢失样式解决办法一样,在css中用 .xxx >>> .xxx 解决 (样式穿透),在less中用 .xxx /deep/ .xxxx
跟vue的v-html丢失样式解决办法一样,在css中用 .xxx >>> .xxx 解决 (样式穿透),在less中用 .xxx /deep/ .xxxx

uniapp开发小程序,全局应用websocket
以前写vue页面的时候写过聊天室,这次用uniapp开发小程序,用到了websocket,记录下心得体会
前言:
后台使用了nodejs的express-ws模块,分享一篇介绍express-ws非常好的帖子https://www.jianshu.com/p/136da96d3d48
对于前端人员,不用管后台socket如何实现的,用的什么模块,因为socket只是个协议
在uniapp中,也不用纠结用框架自带的websocket的api,还是引入socket.io.js。
既然框架已经给我们集成这个功能了,直接用就对了,非常方便
首先在app.vue中建立连接
注:在任意组件下建立socket连接均可,框架提供的api是全局的
onShow: function() {
console.log('App Show')
uni.connectSocket({
url: 'wss://localhost', //仅为示例,并非真实接口地址。
success: () => {
console.log('socket success');
},
fail: (err) => {
console.log(err)
},
complete: () => {}
});
},
onHide: function() {
console.log('App Hide')
uni.closeSocket({
code:1000,
reason:'App Hide'
})
}
建立连接后,在任意组件中调用相关api即可,实在是简单得不能简单了
以下是测试结果
ps:也可以用uni.connectSocket() 接口创建SocketTask 对象,在main.js中全局注册,优点是使用更方便,缺点是关闭连接后,需在代码中实现重新打开连接!
以前写vue页面的时候写过聊天室,这次用uniapp开发小程序,用到了websocket,记录下心得体会
前言:
后台使用了nodejs的express-ws模块,分享一篇介绍express-ws非常好的帖子https://www.jianshu.com/p/136da96d3d48
对于前端人员,不用管后台socket如何实现的,用的什么模块,因为socket只是个协议
在uniapp中,也不用纠结用框架自带的websocket的api,还是引入socket.io.js。
既然框架已经给我们集成这个功能了,直接用就对了,非常方便
首先在app.vue中建立连接
注:在任意组件下建立socket连接均可,框架提供的api是全局的
onShow: function() {
console.log('App Show')
uni.connectSocket({
url: 'wss://localhost', //仅为示例,并非真实接口地址。
success: () => {
console.log('socket success');
},
fail: (err) => {
console.log(err)
},
complete: () => {}
});
},
onHide: function() {
console.log('App Hide')
uni.closeSocket({
code:1000,
reason:'App Hide'
})
}
建立连接后,在任意组件中调用相关api即可,实在是简单得不能简单了
以下是测试结果
ps:也可以用uni.connectSocket() 接口创建SocketTask 对象,在main.js中全局注册,优点是使用更方便,缺点是关闭连接后,需在代码中实现重新打开连接!
收起阅读 »
5+app调用第三方地图导航 android版
/**
* 调用第三方导航 高德优先 百度
* @param lon
* @param lat
* @returns {boolean}
*/
// com.baidu.BaiduMap
// com.autonavi.minimap
function dh(lon,lat){
if(plus.runtime.isApplicationExist({pname:'com.autonavi.minimap'})){
//用户已安装高德地图
plus.runtime.openURL('androidamap://navi?sourceApplication=com.knssshy.sj&lat='+lat+'&lon='+lon+'&dev=0',function(e) {
plus.nativeUI.confirm( "检查到您未安装\"高德地图\".");
} );
}else if(plus.runtime.isApplicationExist({pname:'com.baidu.BaiduMap'})){
//用户已安装百度地图
plus.runtime.openURL('bdapp://map/direction?destination='+lat+','+lon+'&coord_type=gcj02&mode=driving&src=com.knssshy.sj',function(e) {
plus.nativeUI.confirm( "检查到您未安装\"百度地图\".");
} );
}else{
alert('你没有安装导航软件(高德/百度).')
}
}
在JS中直接调用函数dh(lon,lat)就能打开第三方地图进行导航了,lon lat为坐标值。
/**
* 调用第三方导航 高德优先 百度
* @param lon
* @param lat
* @returns {boolean}
*/
// com.baidu.BaiduMap
// com.autonavi.minimap
function dh(lon,lat){
if(plus.runtime.isApplicationExist({pname:'com.autonavi.minimap'})){
//用户已安装高德地图
plus.runtime.openURL('androidamap://navi?sourceApplication=com.knssshy.sj&lat='+lat+'&lon='+lon+'&dev=0',function(e) {
plus.nativeUI.confirm( "检查到您未安装\"高德地图\".");
} );
}else if(plus.runtime.isApplicationExist({pname:'com.baidu.BaiduMap'})){
//用户已安装百度地图
plus.runtime.openURL('bdapp://map/direction?destination='+lat+','+lon+'&coord_type=gcj02&mode=driving&src=com.knssshy.sj',function(e) {
plus.nativeUI.confirm( "检查到您未安装\"百度地图\".");
} );
}else{
alert('你没有安装导航软件(高德/百度).')
}
}
在JS中直接调用函数dh(lon,lat)就能打开第三方地图进行导航了,lon lat为坐标值。
收起阅读 »
在uniapp h5中在线引入高德地图js api的方法分享
高德文档:https://lbs.amap.com/api/javascript-api/guide/abc/load
查询了好久都没有找到解决方法,弄好了分享一下.
//这里要加window., loadScrpit的callback才会执行
window.mapInit = function(){
let mapObj = new AMap.Map('iCenter');
mapObj.plugin('AMap.Geolocation', function () {
let geolocation = new AMap.Geolocation({
enableHighAccuracy: false,//是否使用高精度定位,默认:true
timeout: 5000, //超过5秒后停止定位,默认:无穷大
});
mapObj.addControl(geolocation);
geolocation.getCurrentPosition();
//返回定位信息
AMap.event.addListener(geolocation, 'complete', function (res) {
console.log(res);
});
//返回定位出错信息
AMap.event.addListener(geolocation, 'error', function (err) {
console.log(err);
});
});
}
// 页面onload调用此方法
function loadScrpit(){
var script = document.createElement('script');
script.src = "https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&callback=mapInit";
document.body.appendChild(script);
}
高德文档:https://lbs.amap.com/api/javascript-api/guide/abc/load
查询了好久都没有找到解决方法,弄好了分享一下.
//这里要加window., loadScrpit的callback才会执行
window.mapInit = function(){
let mapObj = new AMap.Map('iCenter');
mapObj.plugin('AMap.Geolocation', function () {
let geolocation = new AMap.Geolocation({
enableHighAccuracy: false,//是否使用高精度定位,默认:true
timeout: 5000, //超过5秒后停止定位,默认:无穷大
});
mapObj.addControl(geolocation);
geolocation.getCurrentPosition();
//返回定位信息
AMap.event.addListener(geolocation, 'complete', function (res) {
console.log(res);
});
//返回定位出错信息
AMap.event.addListener(geolocation, 'error', function (err) {
console.log(err);
});
});
}
// 页面onload调用此方法
function loadScrpit(){
var script = document.createElement('script');
script.src = "https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值&callback=mapInit";
document.body.appendChild(script);
}
收起阅读 »

扫码黑屏
扫码黑屏这个问题一直在华为和小米等手机不定时出现。
1、先解决办法如下。在退出的时候释放扫码对象并关闭
mui.init({
beforeback: function() {
//返回true继续页面关闭逻辑
if(scan != null) {
scan.close()
scan = null;
}
return true;
}
})
2、没有使用demo的用法,这里在mui.plusReady中使用setTimeOut 300之后初始化扫码
var scan=null;
mui.plusReady(function() {
setTimeout("scanInit()", 300)
})
function scanInit() {
var filter = [plus.barcode.CODE128];
scan = new plus.barcode.Barcode('bcid', filter);
scan.onmarked = onmarked;
scan.onerror = onerror;
scan.start();
}
以上用了之后确实没有出现过黑屏
扫码黑屏这个问题一直在华为和小米等手机不定时出现。
1、先解决办法如下。在退出的时候释放扫码对象并关闭
mui.init({
beforeback: function() {
//返回true继续页面关闭逻辑
if(scan != null) {
scan.close()
scan = null;
}
return true;
}
})
2、没有使用demo的用法,这里在mui.plusReady中使用setTimeOut 300之后初始化扫码
var scan=null;
mui.plusReady(function() {
setTimeout("scanInit()", 300)
})
function scanInit() {
var filter = [plus.barcode.CODE128];
scan = new plus.barcode.Barcode('bcid', filter);
scan.onmarked = onmarked;
scan.onerror = onerror;
scan.start();
}
以上用了之后确实没有出现过黑屏
收起阅读 »
码灵程序员导航-一个帮助开发者成长的网址导航

uniapp发布到iOS Appstore被拒绝
We discovered that your app contains hidden features. Attempting to hide features, functionality or content in your app is considered egregious behavior and can lead to removal from the Apple Developer Program.
Specifically, we found that your app includes AliPay (支付寶), which provides access to external payment mechanisms and enables the purchase of content, services, or functionality by means other than the in-app purchase API.
If you feel that we have misunderstood how your app functions and that your app is compliant with the App Store Review Guidelines, please reply to this message in Resolution Center to explain how this feature works.
The next submission of this app may require a longer review time, and this app will not be eligible for an expedited review until this issue is resolved.
这个是发布到苹果Appstore的被拒绝的信息,说的是我在代码中使用了支付宝的sdk
问题排查:
1.uniapp可能封装了sdk,需要去检查是否打包的使用进行了引入;

很明显,没有勾选,说明不是这个问题导致的;
2.需要排查是不是打得iOS的ipa包里面包含了支付宝的信息,需要解压看下;
把ipa修改成zip,双击解压
会看到一个XXX.app的文件,右键该文件会看到“显示包内容”,点击即可
打开infoplist,会发现里面有过alipay,苹果多半是看到这个,给拒绝了
因为info.plist是iOS打包必须要有的,很多配置都是写在里面,我找了一下发现xbuild工具里面没有修改info.plist的地方,只能通过离线进行通过xcode打包了。
我先操作一下试试,看看这次修改了是否能通过审核,再来更新。
We discovered that your app contains hidden features. Attempting to hide features, functionality or content in your app is considered egregious behavior and can lead to removal from the Apple Developer Program.
Specifically, we found that your app includes AliPay (支付寶), which provides access to external payment mechanisms and enables the purchase of content, services, or functionality by means other than the in-app purchase API.
If you feel that we have misunderstood how your app functions and that your app is compliant with the App Store Review Guidelines, please reply to this message in Resolution Center to explain how this feature works.
The next submission of this app may require a longer review time, and this app will not be eligible for an expedited review until this issue is resolved.
这个是发布到苹果Appstore的被拒绝的信息,说的是我在代码中使用了支付宝的sdk
问题排查:
1.uniapp可能封装了sdk,需要去检查是否打包的使用进行了引入;
很明显,没有勾选,说明不是这个问题导致的;
2.需要排查是不是打得iOS的ipa包里面包含了支付宝的信息,需要解压看下;
把ipa修改成zip,双击解压
会看到一个XXX.app的文件,右键该文件会看到“显示包内容”,点击即可
打开infoplist,会发现里面有过alipay,苹果多半是看到这个,给拒绝了
因为info.plist是iOS打包必须要有的,很多配置都是写在里面,我找了一下发现xbuild工具里面没有修改info.plist的地方,只能通过离线进行通过xcode打包了。
我先操作一下试试,看看这次修改了是否能通过审核,再来更新。 收起阅读 »

关于Apple发布的 App Updates for HTML5 Apps 的说明
2019年9月6日,Apple发布一份声明,原文见此:https://developer.apple.com/news/?id=09062019b
这份声明着重强调的是Appstore更新的4.7规定,即:
- In June, we updated guideline 4.7 sections 4, 5, & 6, to further narrow these exceptions and clarify an existing restriction. Apps containing or running code that is not embedded in the binary cannot provide access to real money gaming, lotteries, or charitable donations, among other changes
翻译成中文是:
- 6月,我们更新了指南4.7第4、5和6节,以进一步缩小这些例外的范围并阐明现有限制。包含或运行未嵌入二进制文件中的代码的应用程序无法访问真钱游戏,彩票或慈善捐款以及其他更改
Apple强调,新app必须符合此规定,否则不予上线。同时给予老app 6个月的宽限期,在2020年3月前完成更新改造,否则会下架。
现在已经2020年3月了,每天都有uni-app做的应用新上架Appstore,他们都符合新规定,包括官方的hello uni-app。
但是一些不明真相的人仍然在传谣,技术圈里也如此多谣言令我们很遗憾。
DCloud建议开发者始终明白Apple害怕什么、想要什么:
Apple害怕的是:
- 提供体验不佳的网页应用,与在Safari里访问没有区别
- 通过动态更新绕过Apple的政策(不管是违反了法律,涉及黄赌毒,还是虚拟商品未通过iap支付,绕开Apple的分成)
- 优质的app都在Android上,而iOS上无法上架,导致用户都跑去用Android去了
Apple想要的是:
- 需要开发者提供优质应用,以吸引Apple的手机用户
- 如果涉及虚拟支付,一定要让Apple分钱
只要你的app体验良好,Apple手机用户喜欢,不违法、不侵害Apple利益,Appstore不会拒绝你。
贸易战虽然起起伏伏,但Apple对中国的政策是很谨小慎微的。比如香港暴徒曝光警察位置的App,Google不肯下架,Apple主动下架,因为它不想在中国找事情,卖iPhone是最重要的。
另外,自从iOS13将uiwebview设为私有API,而wkWebview限制非常多,这导致老的5+App和wap2app体验受限,想提供优质体验的应用,建议开发者尽快升级为uni-app。
uni-app不是一个网页套壳应用,它的js根本不运行在webview里(所以也没有document等对象),也不受wkwebview的各种限制。而如果使用nvue的话,视图层也不在webview里,和html5一点关系都没有。
2019年9月6日,Apple发布一份声明,原文见此:https://developer.apple.com/news/?id=09062019b
这份声明着重强调的是Appstore更新的4.7规定,即:
- In June, we updated guideline 4.7 sections 4, 5, & 6, to further narrow these exceptions and clarify an existing restriction. Apps containing or running code that is not embedded in the binary cannot provide access to real money gaming, lotteries, or charitable donations, among other changes
翻译成中文是:
- 6月,我们更新了指南4.7第4、5和6节,以进一步缩小这些例外的范围并阐明现有限制。包含或运行未嵌入二进制文件中的代码的应用程序无法访问真钱游戏,彩票或慈善捐款以及其他更改
Apple强调,新app必须符合此规定,否则不予上线。同时给予老app 6个月的宽限期,在2020年3月前完成更新改造,否则会下架。
现在已经2020年3月了,每天都有uni-app做的应用新上架Appstore,他们都符合新规定,包括官方的hello uni-app。
但是一些不明真相的人仍然在传谣,技术圈里也如此多谣言令我们很遗憾。
DCloud建议开发者始终明白Apple害怕什么、想要什么:
Apple害怕的是:
- 提供体验不佳的网页应用,与在Safari里访问没有区别
- 通过动态更新绕过Apple的政策(不管是违反了法律,涉及黄赌毒,还是虚拟商品未通过iap支付,绕开Apple的分成)
- 优质的app都在Android上,而iOS上无法上架,导致用户都跑去用Android去了
Apple想要的是:
- 需要开发者提供优质应用,以吸引Apple的手机用户
- 如果涉及虚拟支付,一定要让Apple分钱
只要你的app体验良好,Apple手机用户喜欢,不违法、不侵害Apple利益,Appstore不会拒绝你。
贸易战虽然起起伏伏,但Apple对中国的政策是很谨小慎微的。比如香港暴徒曝光警察位置的App,Google不肯下架,Apple主动下架,因为它不想在中国找事情,卖iPhone是最重要的。
另外,自从iOS13将uiwebview设为私有API,而wkWebview限制非常多,这导致老的5+App和wap2app体验受限,想提供优质体验的应用,建议开发者尽快升级为uni-app。
uni-app不是一个网页套壳应用,它的js根本不运行在webview里(所以也没有document等对象),也不受wkwebview的各种限制。而如果使用nvue的话,视图层也不在webview里,和html5一点关系都没有。