如何制作HTML 5的iPhone應用程序
在過去的一年里,你是不是很沮喪,對于所有的使用Objective-C開發iPhone程序的開發者而言,日子都不那么好過,你是不是為了學習開發iPhone應用程序曾經硬著頭皮去讀著那生澀難懂的學習教程,事實是Objective-C是一門類似C語言的語言,這也就絕定了它不是那么容易學習。
我不是勸你去放棄學習Objective-C,因為世上無難事,只怕有心人。但是條條大路通羅馬,也許你轉換下思路你可以用另一種方法達到相同的目的。
你可以制作一個原生的iPhone應用程序去模仿其他的程序,多半上它也許會成為一個不錯的復制品。
但是你完全可以利用已有的技能(HTML5,CSS,Javascript)去完成上面的事.
下面我會向你們展示如何創建一個具有離線功能的HTML5 iPhone應用程序。更進一步的話,我會向你們展示編寫一個俄羅斯方塊游戲的過程。
離線
到底什么是離線?好吧,它其實意味著當我們的手機沒有互聯網連接時,能夠有一個像本地應用程序樣子的程序圖標,啟動畫面。
這意味這我們的應用程序能夠像原生應用程序那樣在手機離線時使用。
其實這不僅是一篇針對iPhone開發的教程,它同樣適用于所有帶有HTML5功能支持瀏覽器的手機。
OK,下面我們開始吧。看看下面的圖片。沒有地址欄,沒有導航條,它就像是一個原生的應用程序。
準備工作
如果我們要想使用HTML5的離線功能的話,你需要有能夠操作服務器端,因為我們需要更改文件的HTTP的頭信息。(下面我們會詳細講解)
我們使用Apache做為服務器,為了完成任務,我們需要配置.htaccess文件。這里是個教程使用.htaccess改變HTTP頭信息。
其他我們需要做的就是在iPhone設置中打開Safari瀏覽器的調試模式。在你的iPhone中進入Settings.app > Safari > Developer,然后打開調試模式,這樣做的目的是幫助你尋找可能出現的JavaScript錯誤。
一旦你完成你的App,您應該關閉調試模式以便于你正確的測試你的應用程序。
關于你的App
圖標和啟動畫面:圖標的大小57px x 57px。
無論你使用什么樣的圖標,iPhone會自動對它進行圓角處理,創建投影,并增加光澤。
圖標最好使用PNG或JPG格式。
下面是我使用的俄羅斯方塊游戲圖標。
啟動畫面大小最好是320px x 460px,且格式為PNG或JPG。
下面是我使用的啟動畫面。
一些小提示
謹記,簡單就是美(Stay small, sparse and simple.)
Small:雖然可以使用緩存以保存一部分文件,但是保持輕量級也是一個明智的行為。
Sparse:盡可能的減少處理的文件。
Simple:不要盲目擴大范圍,從小的方面著手,會使你事半功倍。
應用程序緩存
這是一個新的標準,詳細信息請看這里。
應用程序緩存允許我們提前告知瀏覽器我們的應用程序使用了那些文件。瀏覽器將會把這些文件緩存下來(有時也會失敗)。這個文件的語法格式很簡單,僅僅就是在manifest文件中列舉了文件的相對(例如 /picture.png)或絕對地址(例如 http ://yourwebserver.com/picture.png),瀏覽器會在離線時保留這些文件。
你也可以列舉一些文件地址代表你不想緩存的,但是這跟我們的離線應用程序沒有什么關系(如果你有興趣的話,看這個文檔)。
還有一件重要的事是manifest(就是你需要緩存的文件列表)的filetype頭信息必須被設置成text/manifest。這就是我們為什么需要有一個web服務器以使我們能夠設置HTTP頭信息。
屏幕尺寸
當設計你的應用程序時,你需要注意:當你出入App模式時,你的屏幕可利用面積是320px x 46px。當你處于網頁模式時你的屏幕可利用面積是320px x 356px。這會影響你的程序的用戶界面。
下面就是處于兩種模式下的不同點
HTML
你的App其實就是一個網頁,因此跟在瀏覽器中展示的沒什么不同。iPhone的瀏覽器對HTML5的支持程度也是排在前列的,如果你想深入了解的話,請移步Safari開發者中心:
#p#
開始編寫代碼
應用程序以一些標記開始,下面的就是我的俄羅斯方塊游戲的標記。
- <!DOCTYPE html>
- <html manifest="tetris.manifest">
- <head>
- <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
- <meta name="apple-mobile-web-app-capable" content="yes" />
- <meta name="apple-mobile-web-app-status-bar-style" content="black" />
- <link rel="apple-touch-icon" href="iphon_tetris_icon.png"/>
- <link rel="apple-touch-startup-image" href="startup.png" />
- <link rel="stylesheet" href="tetris.css" type="text/css" media="screen, mobile" title="main" charset="utf-8">
- <title>offline Tetris</title>
- </head>
- <body>
- <!-- Put your Markup Here -->
- <script type="text/javascript" src="tetris.js"></script>
- </body>
- </html>
首先注意Doctype。哦也以后在也不用寫那么長的Doctype了。
在HTML標簽里manifest=”cache.manifest”屬性是告訴瀏覽器我們需要緩存那些文件。
這些是在HTML5頁面中Apple的專屬標記,這里是他們的一些簡要說明:
apple-mobile-web-app-capable: 這是又一個地方告訴瀏覽器,它一個離線應用程序
apple-mobile-web-app-status-bar-style:當處于離線時隱藏狀態欄和導航欄。
apple-touch-icon:告訴瀏覽器程序圖標的地址。
apple-touch-startup-image: 告訴瀏覽器啟動畫面的地址。
還有一點請注意,最好把CSS文件放在上面,JavaScript文件放在下面。
CSS
它跟個普通網頁沒什么兩樣,但是你可以利用一些特殊的CSS -webkit特性做一些很炫很酷的事情,像動畫等。下面是一個很簡單的指導,這已經超出了本文的知識范疇。
簡單的CSS代碼
- body {
- overflow:hidden;
- background: #d7d7d7;
- margin:0;
- padding:0;
- }
- #tetris {
- width: 320px;
- height: 460px;
- background:#000;
- }
主要是設置div元素在網頁中適配iPhone的視圖。
JavaScript
我使用的是Dalton Ridenhour修改版本的JS庫,是我在Github上找到的,這個JS庫適用與大多數的瀏覽器。我唯一做的修改就是讓它在沒有鍵盤時也可以使用。
一般情況下,JavaScript能在iPhone上很好的工作,但是也有例外。想想一下mouseover這個事件,它是存在與iPhone瀏覽器上的,但是如果沒有一個標準的指示設備,我很好奇它怎么使用。Quirksmode寫了一篇很不錯的文章講解了iPhone瀏覽器上的事件。
如果上面的事情你已經完成了,你就可以測試你的程序了,只要在iPhone上打開index.html,你就能看到一個最基本的程序已經完成了。
下一步就是把你的程序放到服務器上,然后正確的設置好cache.manifest文件,并放置到你的程序根目錄里。好了,看看你的緩存文件工作了沒有。
這是我寫的一個完成版,你可以在這里查看
http://tetris.alexkessinger.net
補充說明:離線數據
其實除了可以保存離線文件之外,我們也可以保存離線數據。我們主要使用兩個API:第一個是localStorage。localStorage是一個很易于使用的鍵/值對應的存儲形式,我們可以使用這個API像這樣:
localStorage.dataToStore = 5; console.log(localStorage.dataToStore); // 5
我們可以利用上面的方式保存用戶數據。
第二種方式是離線web SQL數據庫(點擊鏈接查看W3C官網的說明)。這個API使用起來有點復雜。下面是一些代碼片段。
- // Try and get a database object
- var db;
- try {
- if (window.openDatabase) {
- db = openDatabase("NoteTest", "1.0", "HTML5 Database API example", 200000);
- if (!db)
- alert("Failed to open the database on disk. This is probably because the version was /
- bad or there is not enough space left in this domain's quota");
- } else
- alert("Couldn't open the database. Please try with a WebKit nightly with this feature enabled");
- } catch(err) { }
- // Check and see if you need to initalize the DB
- db.transaction(function(tx) {
- tx.executeSql("SELECT COUNT(*) FROM WebkitStickyNotes", [], function(result) {
- loadNotes();
- }, function(tx, error) {
- tx.executeSql("CREATE TABLE WebKitStickyNotes (id REAL UNIQUE, note TEXT, timestamp /
- REAL, left TEXT, top TEXT, zindex REAL)", [], function(result) {
- loadNotes();
- });
- });
- });
- // Insert a test Note.
- var note = {
- id: "1",
- text:" This is a test note",
- timestamp: "112123000",
- left:10,
- top:10,
- zIndex:2
- };
- db.transaction(function (tx)
- {
- tx.executeSql("INSERT INTO WebKitStickyNotes (id, note, timestamp, left, top, zindex) VALUES /
- (?, ?, ?, ?, ?, ?)", [note.id, note.text, note.timestamp, note.left, note.top, note.zIndex]);
- });
- // Get all the notes out of the database.
- db.transaction(function(tx) {
- tx.executeSql("SELECT id, note, timestamp, left, top, zindex /
- FROM WebKitStickyNotes", [], function(tx, result) {
- for (var i = 0; i < result.rows.length; ++i) {
- var row = result.rows.item(i);
- var note = new Note();
- note.id = row['id'];
- note.text = row['note'];
- note.timestamp = row['timestamp'];
- note.left = row['left'];
- note.top = row['top'];
- note.zIndex = row['zindex'];
- if (row['id'] > highestId)
- highestId = row['id'];
- if (row['zindex'] > highestZ)
- highestZ = row['zindex'];
- }
- if (!result.rows.length)
- newNote();
- }, function(tx, error) {
- alert('Failed to retrieve notes from database - ' + error.message);
- return;
- });
- });
總結
通過離線Web App,我們可以做很多東西。做游戲也是可以的,就像我做的俄羅斯方塊,但是你最好想清楚哪些東西適合做成離線應用。像Quake 3競技場估計做不出來,做一個待辦事項的App肯定是綽綽有余。
【編輯推薦】