iOS Webapp的桌面图标及更新

2024-02-28 19:10
文章标签 更新 ios 桌面图标 webapp

本文主要是介绍iOS Webapp的桌面图标及更新,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

iOS允许网站开发者像NativeApp一样在iOS设备的主屏幕为其网站添加一个启动Icon,这个代表着网站的Icon在苹果官方开发者文档里被称为“ Web Clip”,它的作用类似于桌面浏览器的书签,用户通过点击Icon能直接快速打开这个url的网站。

为了给某个网页或者整个网站指定一个漂亮的桌面启动图标,iOS Safari提供了两个私有接口: apple-touch-icon 和 apple-touch-icon-precomposed。


/ Apple-touch-icon

设置方法

通过在页面HTML的头部添加 <link> 标签
<link rel="apple-touch-icon" href="touch-icon-iphone.png" />
<link rel="apple-touch-icon-precomposed" href="touch-icon-precomposed.png" />


这两个标签都是用来指定桌面图标的,但两者有个细微的区别,
•通过 apple-touch-icon 添加的图标是会带iOS图标统一的高光效果
•通过 apple-touch-icon-precomposed 添加的图标则是设计原图,不带高光渐变效果的。


 
图片大小

为了给不同的iOS设备指定其启动图标,在iOS Human Interface Guide中提到,推荐以下四种尺寸:
 

相应地,要指定不同分辨率的设备的图标,可以添加相应的 <link> 标签序列,官方建议的顺序是这样的:
<link rel="apple-touch-icon" href="touch-icon-iphone.png" />
<link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png" />
<link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone-retina.png" />
<link rel="apple-touch-icon" sizes="144x144" href="touch-icon-ipad-retina.png" />


通过 <link> 的 <sizes> 属性可以特别地声明这个图标是为哪种分辨率设备准备的,如果没有指明 <sizes> 属性的大小,则默认值为57×57。

 

如果所有的 <link> 标签序列中都没有符合官方推荐的最适尺寸的话,那么iOS会从所有比推荐的最适尺寸大的图标中选择尺寸最小的那一个,如果所有的 <link> 标签序列中的图标都比当前推荐的最适尺寸小的话,iOS会从这些图片中自动选择最大的那个来作为启动图标。

 

特别地,如果整个页面都没有指定任何的 apple-touch-icon 的图标的话,iOS则会自动去网站根目录寻找有 apple-touch-icon 和 apple-touch-icon-precomposed 前缀的图标文件。

 

图片格式

用于设置成为桌面启动图标的图片文件,可以是以下三种类别
•纯静态的图片图片的路径可以绝对路径、相对于当前页面的相对路径以及相对于网站根目录的路径。目前发现不仅支持png格式的,jpg和gif也在支持的列表中,如:

 http://av.cm/tick/img/demo.png


但如果是动态gif图片只会截取一帧(第一帧?)来显示

•包含图片文件头的HTTP REQUEST可以不是一个静态的文件,而是由服务器返回的带有图片文件比如 image/png 文件头的请求。就像我们常用的图片
 占位图工具 http://getimg.in 的图片:

http://getimg.in/144x144tcat

这个的优点是可以根据前端需要动态地返回不同的图片,缺点是,每次新的图片都需要请求服务器,从服务器下载。

•base64格式的图片这是一个包含png文件头的长字符串,它可以是一张从静态图片转换的,也可以是从服务器返回的,还可以是canvas生成的。  data:image/png;base64,(xxxxxx)


/ 更新桌面启动图标

不完全动态的桌面图标

首先需要声明的是,webapp不能像nativeapp一样后台推送,在没打开前是不运行的,而webapp里所有的js逻辑都只有在页面打开状态下才能运行,所以动态修改桌面启动图标的方法只有在每次点开后才能生效。

 

基于此,动态桌面图标的使用并不适合比如天气、新闻、twitter等即时性很高、后台主动推送的场景,仅仅适用于用户每次手动打开后便更新内容,更新完之后的icon能作为一个状态的标识供用户参考,比如任务管理工具、记帐软件等。

 

选择canvas作为动态图片来源

使用base64的优点是,可以选择由canvas来动态生成,并且不需要有网络请求,直接在本地完成。

 

而且我们的场景非常特殊:仅iOS的Safari,所以完全可以不用考虑浏览器的支持度。
var canvas = document.createElement('canvas');
canvas.width = 144;
canvas.height = 144;
var context = canvas.getContext("2d");
var baseImg = canvas.toDataURL();   


通过js动态创建和修改指定桌面图标的 <link> 标签

桌面图标在页面里的声明仅仅存在 <link> 中,理论上我们只要动态修改 <link> 标签的图片地址就能实现动态的图标。

首次从safari里将页面添加主屏幕时,iOS会检查页面里的 <link> 标签,读取图片的地址然后生成启动图标。并且这个标签只要在用户执行这步操作之前就有的,即不管是页面模板里静态本来存在的,还是通过js动态创建的,该方法一样生效。
•页面中的link是默认存在的

http://av.cm/tick/test/DefaultLink.html

•通过点击触发生成的link,仍然可以生成到桌面

http://av.cm/tick/test/ClickAddLink.html


我们期望的场景是,用户在webapp里进行了一项操作,这个操作更新了整个webapp的状态,我们希望这个状态的改变能在桌面的启动图标里体现出来。

 

拿task工具来举例,用户在点开之前,桌面图标上显现任务队列里还有3个任务,当添加了一个新的任务之后,桌面图标上的任务数字应该变成4。当所有的任务都被打勾完成之后,桌面图标也应该反馈这样的状态,比如显示0条任务或者其它鼓励类的图标。

 

所以理论上,我们要做的就是在每次操作之后,通过js在一个canvas中绘出新的图案,再将这个canvas转化成base64的图片,动态创建到一个 <link> 标签添加至head就行了。

 

但事实上并不是这样。

 

webapp的桌面图标渲染

当在webapp里创建了一个 <link> 再退出后,发现桌面的启动图标并没有像我们期望的那样被更新。

 

经过死乞白赖的测试后发现,在webapp里进行添加和修改的 <link> 标签并不能被iOS读取和渲染到,虽然 <link> 标签在页面里的确存在着,但并不会被更新到桌面。因为webapp里的图标是在body.onload的时候被渲染的。

 

是的,尽管这样听上去很不科学,但是他还是发生了。下面的两个demo的功能都把webapp打开的次数画进canvas,然后生成到桌面图标里,只不过第一个demo的添加方法是在 body.onload 时触发,第二个是在用户点击操作时才触发。


•body.onload 自动触发

http://av.cm/tick/test/BodyLoadSetIcon.html本页面将在每次body.onload事件后读出打开的次数,生成下面的图片,并把这个图片添加至head。先添加页面至主屏幕,在webapp模式下打开再退出检查桌面启动图标。图标上的数字标识出页面被打开的次数,在每次打开再退出后图标上的数字将加1。

•通过点击操作添加link

http://av.cm/tick/test/ClickSetIcon.html本页面在载入的时页面头部并没有link标签,通过点击操作读出打开的次数,生成下面的图片,并把这个图片添加至head。先添加页面至主屏幕,在webapp模式下打开再退出检查桌面启动图标。在每次打开再退出后图标上的数字始终没有被修改。


既然已知图标是在 body.onload 时被渲染的,那么我们需要在每次操作之后都要进行一次reload操作,并且在body.onload的时候再生成图片添加 <link> 标签。为了保证在每次页面重载的时候状态不丢失,需要把状态保存起来,考虑到webapp特殊的使用场景和环境,使用LocalStorage就非常方便。

 

最终的逻辑

所以,更新桌面图标的方法都应该绑定在 body.onload 上,整个流程看上去应该这个样子的:


1.页面载入(包括从桌面打开页面时),读取LocalStorage,根据LocalStorage转换成状态,通过canvas生成体现状态的图片并转换成base64格式,创建 <link> 添加到 <head> 里
2.在打开的页面里进行操作,把操作完的状态在到LocalStorage中,然后通过 location.reload() 重新载入一次页面,执行第一步。

 

基本上所有与更新Icon的关键逻辑都在 body.onload 时执行完毕,其它的中间态都只是对状态的更新。


/ Tick-Task

这里有一个简单的DEMO,以webapp形式实现的任务工具。主要演示了上面提到的更新桌面启动图标的逻辑。


 
http://av.cm/tick/
 

第一次添加到主屏幕时显示的是从Safari里默认的初始图片(这里是一个灯泡),当更新了任务列表之后,桌面上的启动图标将会显示任务列表里未完成的任务,除此之外:


•当在safari中打开时,根据 navigation.standalone 判断当前网页是否以webapp运行。如果不是则显示添加到主屏幕的提示。
•添加任务或者完成任务会将条目内容存到LocalStorage,并且刷新页面,根据所剩未完成条目数生成图片添加到link。
•使用Manifest保存全部静态资源,保证每次页面重载时的体验,并且在离线状态下仍然可用。
•使用开源的页面摇晃检测js库 – shake.js,完成条目后摇晃手机可以清除已完成任务,并播放声音。

 

你还可以在github上查看详细的代码,并且如果愿意的话提出改进。

Try and enjoy it.


/ 最后

webapp因为权限的原因,尚不能做到:


•webapp不能像nativeapp一样后台push,在没打开前是不运行的,而webapp里所有的js逻辑都只有在页面处理打开状态下才能运行,所以动态修改桌面启动图标的方法只有在每次点开后才能生效。
•目前尚未找到像更改桌面图标一样动态地更改标题的方法。
•未找到给webapp添加气泡的方法。

 

但是,Apple在iOS设备的主屏幕上为webapp开了一扇窗户,我们也许可以通过这扇窗为用户带来特别的体验。

 

来源:腾讯ecd

转载于:https://www.cnblogs.com/ligun123/archive/2013/05/27/3101020.html

这篇关于iOS Webapp的桌面图标及更新的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/756360

相关文章

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :