最近Path这个应用很火爆,网上也出现了不少仿Path菜单的项目。即使在原生APP里边,Path的效果也是非常赞的。我突然想,Web APP是不是也能做出类似Path那样的效果呢?于是就有了OPath这个项目,它的客户端部分是完全用PhoneGap+HTML5开发的。
        坦白的讲,OPath比Path差得不是一点半点,但是比很多国产的原生应用体验要好,下边是演示视频。

看完视频如果你对效果还满意的话,请接着往下看。我会和大家分享如何做一个这样的应用,包括整个前端(HTML5)和后端(PHP)。这个项目也是在MIT协议下完全开源的(同样包括前端和后端),项目链接在文章最末尾。PS:我只在iPod Touch4的iOS5系统上进行了测试,其他平台可能存在兼容性问题,需要自行测试和修复。

框架选择      
        PhoneGap就不用说了,有了它才能打包。我们要选的里边的前端框架。虽然之前我已经做了一个基于Jquery Mobile的Tab类模板,但是很明显,Path并没有采用Tab方式的菜单。加上Path的控件都是自己的风格,所以自己渲染样式是逃不掉的,于是最后我选择了采用 Mobile-boilerplate  + iScroll4 来做这个项目。

<ignore_js_op>

(Mobile-boilerplate)

Mobile-boilerplate 是一个移动设备用的HTML5空白模板,它处理掉了非常多的兼容细节,比如viewport之类的。想了解详情的同学可以去看Mobile-boilerplate里边的注释,写得非常详细,还有相关issue的链接。

下载Mobile-boilerplate将解压出来的目录作为我们项目的根目录。Mobile-boilerplate已经包含了js和css目录,其中js下的libs里边有JQuery。

<ignore_js_op>

我首先在Mobile-boilerplate的模板基础上做了下登录页面,完成后的效果是这样的:

<ignore_js_op>

这个界面很简单,直接用CSS来实现就可以了,遵守Mobile-boilerplate的结构,在css/style.css中部200行左右的位置开始写入自己的css。

<ignore_js_op>

API接口的用户认证

接下来我们说说API方式用户认证的实现。在OPath项目中,我们采用用户名+密码换token,以后操作通过token鉴权的方式。因为这种方式实现起来很方便。做PHP的同学都知道,PHP的Session机制是通过PHP SESSION ID来标示用户的,一般情况下这个标示通过Cookie存储在浏览器中。

我们的思路就是,将这个SESSION ID直接作为token就好啦。于是我们实现了get_token接口:

<ignore_js_op>

       最核心的逻辑就这几行token在生成后,通过json格式返回给客户端。

  1. session_start();
  2. $token = session_id(); // 将Session id作为token
  3. $_SESSION['token'] = $token; // 在Session中存储用户信息,供以后的操作认证使用。
  4. $_SESSION['uid'] = $user['id'];
  5. $_SESSION['name'] = $user['name'];
  6. $_SESSION['email'] = $user['email'];
  7. $_SESSION['level'] = $user['level'];

复制代码

客户端发送Ajax请求和解析参数

现在回到客户端这边来,当用户在登录页面填好账号后,我们需要将这些数据发送到服务器端,换取token。使用JQuery,这个很简单:

我们用 jQuery.parseJSON 解析返回的JSON数据,然后在登录正确后,将账号和token保存到本地。这里的kset其实是我写的一个快捷函数,它只是简单封装了下HTML5的LocalStorage。

  1. function kset( key , value )
  2. {
  3. window.localStorage.setItem( key , value );
  4. }
  5. function kget( key )
  6. {
  7. return window.localStorage.getItem( key );
  8. }
  9. function kremove( key )
  10. {
  11. window.localStorage.removeItem( key );
  12. }

复制代码

LocalStorage里边的数据是持久化的,在应用被关闭后依旧存在。顺便说下,在Chrome和Safari的调试工具里边,Resource的Tab里边可以直接看到当前应用的LocalStorage还有IndexedDB的数据,不用去找其他的工具来查看这些值。这在调试应用的时候非常方便。
         由于开发的应用是HTML5的,我首先会实现标准浏览器支持的部分,用Safari来进行调试;在最后才实现需要PhoneGap的部分,进行真机调试,这样可以节省很多调试时间。

<ignore_js_op>

Path主页面         Path的主页面很帅,实现细节也很多,我挑重点说。先放一张做完后的效果:

<ignore_js_op>

整体的布局上,其实我们可以直接沿用iScroll4的Demo,顶栏固定,将原来的Footer换成那个加号按钮就可以了。加号按钮的实现网上有CSS版本的,但是在Android上会出现严重的毛边,所以我直接用图片代替了。(Android上CSS圆角毛边的问题非常烦人,从这个地方可以一眼认出是否是WebAPP;iOS上则非常干净。)考虑到iPod Touch(我主要用这个)的杯具性能,我只简单做了个位置移动效果,觉得细节不够的同学可以自己加旋转和弹簧效果,用JQuery很容易做。说实话我觉得原版Path的那个加号按钮展开后很难按准 T__T

页面上方的Profile Picture部分放到iScroll的wrapper内,scroll最上方;下边的【加载更多】按钮,放到wrapper内,scroll最下方。均通过CSS指定固定高。

<ignore_js_op>

其他的布局细节可以查看path.html和style.css源文件。

Retina屏幕下的图片模糊问题

在iScroll的基础上,我很快就完成了主页面的布局,但是当我放到头像和图片后,杯具发生了!在Android上看的时候很正常,但是在Touch上图片会变得非常模糊。按Mobile-boilerplate的viewport设定,整个页面宽度应该会变成 设备宽,对Touch来说就是320px。很快我就意识到这应该是Retina屏幕带来的问题,因为Retina屏将标准屏幕一个像素改用4个像素显示,所以图像和周围的矢量图对比起来就模糊了。而在Android上都采用一个像素显示,所以没有这个问题。
  
      Google了下,网上的解决方案是这样的:对于直接的图片应用,比如说:

  1. <img src=”image.png”/>

复制代码

采用Retina屏幕的iOS设备会去找同目录下的 image@2x.png进行显示。对于通过CSS引用的图片,比如说:

  1. <div id=”avatar”></div>

复制代码

则需要使用link标签按条件载入专用的CSS。

  1. <link rel="stylesheet" media="only screen and (-webkit-min-device-pixel-ratio: 2)" type="text/css" href="../iphone4.css" />

复制代码

我测试了下,没有成功,更主要的还是觉得这个方案不爽,额外CSS什么的弱爆了。然后自己试出来了一个方案:

因为模糊的原理已经很清楚了,那么只要朝这个方向去想就行。对于直接引用图片的情况,很容易想到解决方案:原本100*100的图片,我做成200*200,然后在img标签中指定高和宽为100*100。这样在Retina屏幕上可以按像素点进行显示,在其他屏幕的设备上,浏览器会自己先缩放后显示,测试效果很清晰。通过CSS引用的情况比较麻烦,我睡了一觉才想出来,如果div#avatar要显示100*100的背景,那么将它的高和宽指定为200*200,配上200*200的背景图片,最后,Zoom:0.5。

其他页面需要注意的地方
         其他页面基本上都是体力劳动了,Path Feed列表渲染时有两个需要注意的细节:一是我们用的模板本身是用<script>标签的,所以模板里边就不能再有这个标签了。在显示每条Feed时,需要显示对应的用户头像,这个头像当做背景显示的,由于不能用script标签,只好把url先放到标签里,渲染完后统一处理。
         二是当Feed里边有图片的时候,iScroll的高度会受影响。需要在图片加载完全后,再重新调用iScroll的refresh方法。在Feed中图片过多时,Feed页面会卡,这个问题可以通过串行载入图片资源的方式来解决,在当前这个版本里边,没有实现。
Thought页面这部分没有太多问题,采用了之前Tab模板的Div切换方式,从而逼近原生应用的切换速度。

<ignore_js_op>

通过PhoneGap实现拍照和头像设置

头像和拍照使用PhoneGap调用了本地设备,按PhoneGap的说明,加载PhoneGap的JS文件并在页面初始化时注册好事件。

<ignore_js_op>

在点击了拍照按钮或者头像按钮后,调用摄像头,并通过PhoneGap提供的的文件传输对象FileTransfer进行上传。FileTransfer可以模拟一个完全的HTTP请求,所以服务器端并不需要特殊出来,按带file标签的标准From请求处理即可。

<ignore_js_op>

需要额外处理的是,iOS拍摄的图片方向很可能不对。这是因为iOS本地的相册在显示图片时,根据拍摄时的方向自动做了调整。要在服务器端正确的显示图像,必须根据图片中的Exif信息调整方向。在将家里的小浪摆好Pose并通过各个方向的拍摄后,我写好了调整方向的函数。

<ignore_js_op>

所有的代码,我已经放到上,大家可以下载 http://code.google.com/p/o-path/ 。这些代码是MIT协议,可以随意商用。

开发以外
兼容性
         由于各个平台对CSS和HTML5 的支持差异很大,所以很难在全部平台做到完美,像之前提到过的,Android的CSS圆角毛边问题,Div切换时部分图层不定期隐藏的问题;另外PhoneGap还有各种BUG和问题,比如iOS应用从后台呼出时有短暂的白屏闪烁问题;比如OPath里边我使用了1.2版本,这个版本在iOS下拍照正常,但是在Android下呼叫不出摄像头,换成1.0版本就可以,这说明PhoneGap在平台兼容性上问题依然不少。
         个人感觉,在现阶段,一个PhoneGap应用要想做到完美的体验并在各个平台保持体验一致,难度非常大。不过如果能忍受一些小细节,或者能做好优雅降级的话,PhoneGap应用是能超过很多原生应用的。
代码安全性
          采用PhoneGap打包的应用,不管是APK还是IPA,只要将扩展名改为zip,解压后在www目录就可以得到这个应用的全部源代码。

<ignore_js_op>

这使得盗版成本非常的低,必要的时候需要对js进行混淆。最可靠的方式是将部分核心逻辑放到云端,通过api使用。

转载自:http://ftqq.com/2011/12/30/how-t ... html5-and-phonegap/

如何用HTML5+PhoneGap写个Path项目的更多相关文章

  1. 如何用tomcat发布自己的Java项目

    如何用tomcat发布自己的Java项目 tomcat是什么?它是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器.我们用Java开发出来的web项目,通过tomcat发布出来,别人就可 ...

  2. 01.html5+phonegap跨平台移动应用开发

    一.html5+PhoneGap基础知识 (1)html5介绍 HTML5是用于取代1999年所制定的 HTML 4.01 和 XHTML 1.0 标准的 HTML 标准版本,现在仍处于发展阶段,但大 ...

  3. [置顶] 如何用PYTHON代码写出音乐

    如何用PYTHON代码写出音乐 什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深 ...

  4. 为PhoneGap写一个android插件

    为PhoneGap写一个android插件,要怎么做? 其实这句话应该反过来说,为android写一个PhoneGap插件,要怎么做? 这里以最简单的Hello World!为例,做个说明: 1.第一 ...

  5. 怎么在myeclipse中导入已经写好的项目

    经常我们需要学习别人写好了的源码来提升自己的编码能力,本文将介绍如何从外部导入别人已经写好的项目到我们myeclipse里面.同时也将介绍怎么给导入的工程改名的问题.                 ...

  6. phonegap创建的ios项目推送消息出现闪退现象

    使用phonegap创建的ios项目,推送消息时,当程序在前台运行或者在后台运行状态下,推送消息过来,可以解析并且跳转: 但是在程序从后台退出的状态下,当消息推送过来的时候,点击通知栏,打开程序,程序 ...

  7. 推荐一本写给IT项目经理的好书

    原文地址:http://www.cnblogs.com/cbook/archive/2011/01/19/1939060.html (防止原文作者删除.只能拷贝一份了) 推荐一本写给IT项目经理的好书 ...

  8. 我写了个项目,帮你学习HTTP接口测试!

    端午节我写了一个项目,帮助你学习HTTP接口测试. GitHub地址: https://github.com/defnngj/learning-API-test 整个项目基于Flask和 Reques ...

  9. 一步一步手写GIS开源项目-(2)地图平移缩放实现

    系列文章目录 一步一步手写GIS开源项目-(1)500行代码实现基础GIS展示功能 一步一步手写GIS开源项目-(2)地图平移缩放实现 项目github地址:https://github.com/Hu ...

随机推荐

  1. 2016CVTE编程题:兔子藏洞

    兔子藏洞 题目描述 一只兔子藏身于20个圆形排列的洞中(洞从1开始编号),一只狼从x号洞开始找,下次隔一个洞找(及在x+2号洞找),在下次个两个洞找(及在x+5号洞找),以此类推...它找了n次仍然没 ...

  2. mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换等

    mp3 音频 音乐 tag ID3 ID3V1 ID3V2 标签 读取信息 获得图片 jpeg bmp 图片转换(上) MP3文件格式(二)---ID3v2 图:ID3V1标签结构 图:ID3V2标签 ...

  3. 图解TCP/IP读书笔记(二)

    图解TCP/IP读书笔记(二) 第二章.TCP/IP基础知识 一.TCP/IP出现的背景及其历史 年份 事件 20世纪60年代后半叶 应DoD(美国国防部)要求,美国开始进行通信技术相关的研发 196 ...

  4. QT静态编译

    Qt静态编译(链接)和动态编译区别 Qt的静态编译译(其实应该叫链接,不是编译),将各模块编译成静态库,这样在编译自己写的Qt程序时,会将这些静态库编译(链接)到你的EXE文件中去的.Qt的动态编译, ...

  5. 当前主流的安卓APP开发IDE

    什么是主流的开发安卓APP的方式? 我是去年4月份接触的Android开发,因此特别有感触,可以明显的感受到安卓APP主流开发方式的改变. 去年,2015年年初,各大安卓开发群大部分大牛在用Eclip ...

  6. 实用Linux命令,不求最全但求实用-------iptables命令实战

    开始配置 我们来配置一个filter表的防火墙. (1)查看本机关于IPTABLES的设置情况 [root@tp ~]# iptables -L -n Chain INPUT (policy ACCE ...

  7. SQL Server ->> 关于究竟ALTER INDEX ... REBUILD会不会导致改变索引选项和Filegroup的验证

    其实之前做过类型的验证,不过影响不是特别深,只是记得不会改变DATA COMPRESSION,那今天再次遇到这个问题就再拿出来验证一下.随便写个脚本验证下.ALTER INDEX ... REBUIL ...

  8. 【用户分析-用户场景】这TM才是产品思维!

    @奶牛Denny :很长一段时间里,市场推广/营销(Marketing)在中国似乎是一个大家很忌讳的词汇.市场推广无非就是夸大包装,炒作一下,卖卖情怀——很多人都是这么觉得的,因为确实有一部分急功近利 ...

  9. 常用加密算法的Java实现总结

    常用加密算法的Java实现(一) ——单向加密算法MD5和SHA 1.Java的安全体系架构 1.1           Java的安全体系架构介绍 Java中为安全框架提供类和接口.JDK 安全 A ...

  10. 一些practice和总结(转载)

    转自 http://boundary.cc/2013/05/java-app-server-develop/ by JOKER on 2013/05/05 最近状态不是很好,负能量堆到积爆表,静下心来 ...