首页>>iPhone >>开发
如何用HTML5制作iPhone App【转】
楼:1
九品仙
2011-6-24 21:41:09
如何用HTML5制作iPhone App【转】
http://html5age.com/2011/03/28/how-to-use-html-make-iphone-app.html

27-01_offline_html5_iphone_app_lead_image

你在这一年中很受挫,我知道的。所有的object-c的开发者都有一段在iphone上写程序的痛苦经历。你曾经想找一两篇iphone开发的初级教程,但是它的C语言太难学了。

我不想说一些让你放弃的消极的话:你可以放弃它,这意味着这些时间你可以做些别的。

你可以作一个native app 和别的app 一样,并且,很大程度上,它看起来就是一个完美的仿冒的应用程序。

只要你会 HTML(5),CSS 和 Javascript 就能做到。

我将向你演示 如何 制作一个 离线的iPhone应用程序,说白点就是我会一步一步教你怎么作一个俄罗斯方块游戏(Tetris game)。

Offline?

什么是离线?离线意味着,我们有一个自定义的icon和界面让他们看起来像本地应用程序,无论手机是否链接了网络都能是使用。

这个app就像手机中的普通应用程序一样当它离线时也会可以运行。

这虽然是一个详细的iPhone教程,但更多的技术来自于所有手机都内嵌的支持html5浏览器。

看下面的图片,它没有URL 的输入框 也没有浏览器导航在底部,看起来就是一个本地的手机应用程序。

final_result_html5_iphone

Prework

利用html5的offline caching,你访问服务器文件可以改变文件的HTTP Headers

Apache对这个支持的非常好,你只要修改.htaccess 文件就行了。这有一个教程 《使用htaccess修改HTTp headers》

还有一件事你需要做,你的iPhone unit中的 Safari的网页浏览器中需要打开debug bar,进入设置:.app > Safari > Developer on your iPhone,然后打开debug console。这可以方便你查看潜在的JavaScript 错误。

一旦你创建了你的app,你就应该将这个关闭以便于在测试你的HTML5 iPhone app时得到完整的体验。

debug_console_iphone

About the App
Icon and Startup Screen

icon需要是57px x 57px。

iPhone会将所有的icon图片做圆角处理,创建阴影效果。

其次图片必须是PNG或者JPG格式。

这个是我在俄罗斯方块游戏中使用的图片。

iphone_icon

起始屏幕需要320px x 460px 也必须是PNG或JPG格式。

这个是我用的起始屏幕图片。

opening_screen

Some tips before you start

保持小(small),少(sparse)和简单(simple).

  • 小:手机程序开发需要缓存文件,所以要保持文件的大小。
  • 少:需要处理的文件的数量越少越好.
  • 简单:从一些简单的想法开始,在做的过程中把持住复杂度,这样你会完成的更快。
Application Cache

这是一个新标准,点这里查看更多。

应用程序缓存允许浏览器检测网页是否需要网络才能工作。

它可以缓存你想缓存的文件,语法非常简单:只要把每个文件(例如:http://yourwebserver.com/picture.png)的绝对目录列在manifest文件(/picture.png)。浏览器会让这些文件离线。

你也可以列出需要缓存文件的URL。但是这个对于离线应用没有效果的(有兴趣的朋友看这里

通过manifest(需要缓存的文件列表)来缓存文件有一个棘手的问题,需要将filetype Header设置为 text/manifest。这也是为什么需要设置HTTP headers来访问web服务器。

Screen Size

设计程序的一个提醒:当你在应用程序模式(app mode)时,屏幕大小为 320px x 460px。当你在网页模式(web mode)时,屏幕会变成320px x356px。这会影响你的HTML5程序的用户界面。

这里你可以看到不同他们的不同。

in_iphone_ui_sidecomp

HTML

iPhone浏览器是一个真正的支持HTML5的浏览器,所以HTML代码完全相同。

更多的详细,请查看Safari Developer‘s corner:

Let’s get coding

程序开始定义markup,下面是俄罗斯方块app的markup。

  1. <!DOCTYPE html>  
  2.   
  3. <html manifest="tetris.manifest">  
  4.   
  5. <head>  
  6.   
  7.     <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>  
  8.   
  9.     <meta name="apple-mobile-web-app-capable" content="yes" />  
  10.   
  11.     <meta name="apple-mobile-web-app-status-bar-style" content="black" />  
  12.   
  13.     <link rel="apple-touch-icon" href="iphon_tetris_icon.png"/>  
  14.   
  15.     <link rel="apple-touch-startup-image" href="startup.png" />  
  16.   
  17.     <link rel="stylesheet" href="tetris.css" type="text/css" media="screen, mobile" title="main" charset="utf-8">  
  18.   
  19.     <title>offline Tetris</title>  
  20.   
  21. </head>  
  22.   
  23. <body>  
  24.   
  25.    <!-- Put your Markup Here -->  
  26.   
  27.    <script type="text/javascript" src="tetris.js"></script>  
  28.   
  29. </body>  
  30.   
  31. </html>  

首先,注意Doctype,这难道不值得为HTML5欢呼吗?

其中<html>标签中的manifest=”cache.manifest” 属性 告诉浏览器,我们需要缓存这个离线页面。

这些是苹果 在HTML5中独有的markup,简单的介绍下:

  • apple-mobile-web-app-capable:  另一种声明这是一个offline app。
  • apple-mobile-web-app-status-bar-style: 当程序离线时隐藏status bar和 nav bar。
  • apple-touch-icon:指向需要成为icon的图片。
  • apple-touch-startup-image:指向起始图片的url。

同时要注意,把CSS放在顶上而把JavaScript放在底部(最好这样做)。

CSS

与大多数网页一样,你还可以使用 -webkit 规则的CSS做一些像动画一样非常酷的特效。但是这个话题有点超出本文的范围了。

下面的CSS很朴素

  1. body {  
  2.     overflow:hidden;  
  3.     background#d7d7d7;  
  4.     margin:0;  
  5.     padding:0;  
  6. }  
  7. #tetris {  
  8.     width320px;  
  9.     height460px;  
  10.     background:#000;  
  11. }  

这个样式只是为了确保div元素能适应iPhone的显示界面。

JavaScript

我用了一个改装过的javascript版本,来自于Dalton Ridenhour;我在Github上发现的.JS本来是用在网页浏览器中的。而我不得不做了一点点修改让它支持键盘。

一般来说,JS 方法在iPhone中运行正常-虽然有些小问题。想想一些类似mouseover在iPhone中存在的事件,我不确定当你没有标准的点击设备时(如:鼠标)能帮到多少。Quirksmode发表了一篇关于events on the iPhone的文章,受益良多。

当你全完成了,你可以在iPhone中打开index.html 测试,应该能够可以见所有运行正常。

接着,下一步是从一个真实的服务器上设置缓存 manifest。

然后你可以添加到主桌面上,然后查看离线模式。

你可以参考一个可以运行的版本,我创建在:

Bonus Section: Offline Data

随着需要离线的文件越来越复杂,你也可以讲用户数据存储在一个离线数据库中。有两个主要的API,一个是保存每个用户的数据,另一个是用来保存每个页面的数据。

第一种是localStorage。localStorage,一种简单的键值对存储方式。

  1. localStorage.dataToStore = 5;  
  2. console.log(localStorage.dataToStore);  
  3. // 5  

举个例子,你可以用它来存储用户的得分。

第二种实际上时一个离线的SQL引擎,一个webdatabase。API更先进一些,这有一点代码:

  1. // Try and get a database object  
  2. var db;  
  3.   
  4. try {  
  5.     if (window.openDatabase) {  
  6.         db = openDatabase("NoteTest""1.0""HTML5 Database API example", 200000);  
  7.         if (!db)  
  8.             alert("Failed to open the database on disk.  This is probably because the version was / 
  9.             bad or there is not enough space left in this domain's quota");  
  10.     } else  
  11.         alert("Couldn't open the database.  Please try with a WebKit nightly with this feature enabled");  
  12. catch(err) { }  
  13.   
  14. // Check and see if you need to initalize the DB  
  15. db.transaction(function(tx) {  
  16.     tx.executeSql("SELECT COUNT(*) FROM WebkitStickyNotes", [], function(result) {  
  17.         loadNotes();  
  18.     }, function(tx, error) {  
  19.         tx.executeSql("CREATE TABLE WebKitStickyNotes (id REAL UNIQUE, note TEXT, timestamp / 
  20.         REAL, left TEXT, top TEXT, zindex REAL)", [], function(result) {  
  21.             loadNotes();  
  22.         });  
  23.     });  
  24. });  
  25.   
  26. // Insert a test Note.  
  27. var note = {  
  28.     id: "1",  
  29.     text:" This is a test note",  
  30.     timestamp: "112123000",  
  31.     left:10,  
  32.     top:10,  
  33.     zIndex:2  
  34. };  
  35. db.transaction(function (tx)  
  36. {  
  37.     tx.executeSql("INSERT INTO WebKitStickyNotes (id, note, timestamp, left, top, zindex) VALUES / 
  38.     (?, ?, ?, ?, ?, ?)", [note.id, note.text, note.timestamp, note.left, note.top, note.zIndex]);  
  39. });   
  40.   
  41. // Get all the notes out of the database.  
  42. db.transaction(function(tx) {  
  43.     tx.executeSql("SELECT id, note, timestamp, left, top, zindex / 
  44.     FROM WebKitStickyNotes", [], function(tx, result) {  
  45.         for (var i = 0; i < result.rows.length; ++i) {  
  46.             var row = result.rows.item(i);  
  47.             var note = new Note();  
  48.             note.id = row['id'];  
  49.             note.text = row['note'];  
  50.             note.timestamp = row['timestamp'];  
  51.             note.left = row['left'];  
  52.             note.top = row['top'];  
  53.             note.zIndex = row['zindex'];  
  54.   
  55.             if (row['id'] > highestId)  
  56.                 highestId = row['id'];  
  57.             if (row['zindex'] > highestZ)  
  58.                 highestZ = row['zindex'];  
  59.         }  
  60.   
  61.         if (!result.rows.length)  
  62.             newNote();  
  63.     }, function(tx, error) {  
  64.         alert('Failed to retrieve notes from database - ' + error.message);  
  65.         return;  
  66.     });  
  67. });  
Wrap Up

离线HTML程序可以做很多东西,游戏,像俄罗斯方块,没有什么是不可能的,但是你需要事先考虑你想做什么是否有必要做成离线程序。雷神之锤3竞技场,可能不行,做一个确信可行的 to-do程序表。

让应用程序遍地开花吧!

资源