-->

2013年4月30日 星期二

使用php及mysql使app具備連線網路資料庫(web database)的能力 (三) - 撰寫 app連線 php

前面兩篇使用php及mysql使app具備連線網路資料庫(web database)的能力 (一) - 建構資料庫使用php及mysql使app具備連線網路資料庫(web database)的能力 (二) - 撰寫 php以 mysql管理資料庫。我們建置了mysql並且知道如何撰寫php去存取mysql。現在,終於可以開始撰寫app的部份了。

本篇會撰寫一個簡單的登入頁面,能夠進行註冊,以及登入,並會顯示註冊及登入成功或失敗。







要達成上述的功能,需要進行http request。雖說Objective-C本身就有提供完成這類工作的方法,但是使用起來太過繁雜,不容易使用。而網路上有許多open source提供了這方面的功能,筆者在此使用 AFNetworking來完成這部份的工作。因此,你必須先到這裡下載這個開放原始碼,稍後會在app中使用到。下載完成後,可以開始撰寫程式碼了!

建立專案,及使用者介面

首先,開一個single view樣板的專案,使用storyboard。並將UI設計成如下。筆者這裡提供已經設計好的原始碼,可到這裡下載。如果你懶得進行以下的實作內容,你也可以到這裡下載已經完成的程式碼。

對帳號密碼做簡單的認證

一般對於帳號密碼都會做一些限制,例如不能使用特殊符號,或者字數必須介於多少之間等等。在AAViewController.m中的@end前加入程式碼,這兩個方法分別是驗證帳號跟密碼是否滿足設定的條件。分別是帳號只能由a-z、0-9、A-Z等組成,且必須介於1-18字元之間。密碼則是必須介於6-18個字元之間。

使用AFNetworking

前面筆者提過,此app使用AFNetworking做http request等動作。首先將AFNetworking資料夾拖曳進專案內。並在AAViewController.m中加入:

等等,為什麼還有一個MBProgressHUD.h?MBProgressHUD也是開放原始碼,其功能是像UIActivityIndicator一樣,但是有更酷炫的效果,有興趣的可以到這裡觀看詳細內容。最後我們定義了伺服器的位址,這個位址就是api.php的位址,沒錯就是在使用php及mysql使app具備連線網路資料庫(web database)的能力 (二) - 撰寫 php以 mysql管理資料庫中,我們所撰寫的php,類似但是其內容有些微的不同,稍後筆者會從新撰寫所需要的api.php。我們還是先來把app的部份搞定。

首先實作sign up這個button的action:

這串程式碼相對較長,不過筆者已經加入註解,相信大家應該很容易看,一些瑣碎的細項,相信各位都可以看懂得。這裡直接解說15-54行的程式碼的作用。

這段程式碼,是產生client這個物件,並定義根目錄是hostRootURL。設定POST的key及keyvalue,這些key及keyvalue為什麼要這麼設定,稍後會做解釋。最後使用client的一個方法,將這些參數POST給api.php。

在postPath.....的方法中,提供兩個block分別是成功及失敗。其中的responseObject就是網頁的回應。可以透過stringWithData:encoding的方法將其轉換NSString,並以NSLog輸出,一般使用在開發階段,幫助除錯。由於筆者在api.php中設計其response要以JSON格式輸出。因此,筆者以NSJSONSerialization將responseObject轉成NSDictionary。並取其key值來判定註冊是否成功。

failure的block也是一樣的,因此筆者就不再贅述。

再來進行"sign in" button的action實作,內容如下。如果你看懂上述的內容,相信你有能力看懂這個實作內容,你會發現,他們完全一樣。現在,這個app已經能夠溝通php,再透過php去控制mysql了。最後,還需要完成api.php的部份。

完成api.php

新增api.php,程式碼如下。筆者假設各位已經了解function及class的用法,前者就像是objective-c裡面的方法,後者則像是類別,若是初學者,可到這裡完成簡單的php課程。而function內的程式碼,在使用php及mysql使app具備連線網路資料庫(web database)的能力 (二) - 撰寫 php以 mysql管理資料庫都解說過了。因此,筆者只針對幾個新出現的方法做解說。

第2行開始的try{...}catch(Expection $e){...},會執行try{...}的程式碼,若有錯誤,則會執行catch(Expection $e){...},並捕獲錯誤訊息在$e中。在11行筆者echo出錯誤訊息,若有發生錯誤,則api.php的response就會是錯誤訊息,還記得在上一小節中,AFNetworking的postPath...方法中的responseObject,api.php的response就會被擷取到其中。因此,將responseObject編碼並輸出,就可以知道這個request發生什麼事情了。

再try{..}中,一開始require的config.php就是伺服器的環境參數,跟使用php及mysql使app具備連線網路資料庫(web database)的能力 (二) - 撰寫 php以 mysql管理資料庫是一樣的。

而sleep(3)是讓程式碼暫時停頓,筆者用來模擬以個反應較慢的伺服器。接著產生一個api物件,並執行handleCommand這個方法。最後,產生一個陣列,以"api"這個key值對應api_response,api_response也是一個陣列,用來存放api中註冊及登入的結果。最後以json_encode將其輸出,也就是它是api.php的response,同上一段,ios app中會對其編碼,並輸出。

我們接著看class API{...},function __construct($config){...}是new一個API物件時,要給予的初始化方法,內容相信各位一定不陌生,我們在上一篇文章中一起做過了。接著看handleCommand,這是在try{...}中,產生完api物件之後,執行的方法,它做了什麼事?一開始它使用了isset,來判定$_POST['cmd']是否存在,isset的詳細資料可以看這裡。若存在的話,就進入switch中,使用trim來取得純string的部份,switch分兩個方法,一個是signIn令一個是signUp。

還記得上述有提到要設定POST的key及keyvalue,我們以NSDictionary *param存放這些key-value。以下是param的物件程式碼。AFNetworking會將它POST給api.php並存在$_POST中。藉由這個方式,可以使用app來告訴php要執行什麼事情。當然,必須先把php建置好。後面的三個function內容都與使用php及mysql使app具備連線網路資料庫(web database)的能力 (二) - 撰寫 php以 mysql管理資料庫大同小異,筆者就不再贅述。

現在,執行你的iphone模擬器,別忘了開啟伺服器,來測試編寫好的app吧!慢著,現在我們改到實機上測試,出現問題了,無法連接伺服器。你還必須修改一個東西,你的伺服器位址。打開系統設定->網路,找到你得IP位址去替換掉localhost。大功告成!現在可以在實機上對伺服器進行存取了。

注意:如果你跟筆者一樣使用浮動ip的話,記得再測試之前都要確認一下你的ip位址,避免不必要的錯誤。

reference:

http://www.php.net/

https://github.com/AFNetworking/AFNetworking

https://github.com/jdg/MBProgressHUD

沒有留言:

張貼留言