[CS193P] 第十二堂課摘要及心得筆記

評論
評論

在這一次的 CS193P 課程中,我們將學習如何使用 Web View 來在 iPhone 應用程式上顯示網頁內容,並且透過 Core Location 和 Map Kit 來取得使用者的地理位置和顯示地圖,就讓我們一起來看看吧!

UIWebView

UIWebView 是 UIKit 所提供來顯示網頁內容的 View,背後使用的瀏覽技術就如同 iPhone 的 Safari 一樣,換而言之,就如同 Safari 能夠開啟 PDF/DOC 等檔案格式,透過 UIWebView 這些內容也理所當然的能夠在我們的應用程式中顯示。

UIWebView 的資料來源主要有三者:

  1. 本機上的 HTML 字串
  2. 本機上的資料 + MIME type
  3. 遠端的 URL

需要注意的是,UIWebView 對於網頁的一些功能有所限制,像是 JavaScript 最多只能執行 5 秒,而最多也只能使用 10MB 的記憶體空間。

而我們要如何建立 UIWebView 呢?我們當然可以透過 Interface Builder 來建立,也可以使用程式碼。而當我們建立好 View 之後,可以使用以下 API 來提供顯示資料給 View:

- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL; - (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL; - (void)loadRequest:(NSURLRequest *)request;

而這三種 API 也就是上面所說的三種不同的資料來源,分別是 HTML 字串、資料和 URL。這邊的 NSURLRequest 是一個包裝過後的物件,負責紀錄所要擷取的 URL 和快取原則。此外,UIWebView 也有以下 Properties 和方法:

@property BOOL loading; // 是否在讀取中? @property BOOL canGoBack;  // 是否有上一頁? @property BOOL canGoForward; // 是否有下一頁? - (void)reload; // 重新讀取  - (void)stopLoading; // 停止讀取  - (void)goBack; // 回到上一頁  - (void)goForward; // 回到下一頁  // 以下是設定值 @property BOOL scalesPageToFit // 是否自動縮放頁面 @property BOOL detectsPhoneNumbers; // 是否自動偵測電話號碼並轉成可點的連結

就如同大多數複雜的類別一樣,UIWebView 當然也會有對應的 delegate 方法:

- (void)webViewDidStartLoad:(UIWebView *)webView; - (void)webViewDidFinishLoad:(UIWebView *)webView; // 開始讀取頁面 - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error; // 讀取失敗 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; // 判斷是否要讀取新的頁面

Core Location

Core Location 是在 Cocoa Touch 中所提供用來處理地理訊息的 framework,包含了以下類別:

  • CLLocation -- 地理位置資訊
  • CLLocationManager -- 用來協助取得 CLLocation
  • CLHeading -- 用來表示羅盤指向的位置

要注意的是,Core Location 並不包含任何 UI 元件,而是只負責單純的位置管理而已。而 Core Location 在運作上,會透過 iPhone 上得三種方式來定位:

  • GPS -- 最準確但也最慢
  • Wi-Fi -- 速度跟時間都處於中間
  • 基地台三角定位 -- 最快但也最不準

而我們要如何確定 iPhone 使用的是哪一種定位方式呢?我們可以透過設定不同的準確度來達成,假設我們設定誤差只能在 1 公尺以內,那 iPhone 自然會使用 GPS 來取得位置。而當我們需要獲得當前的座標時,我們需要建立新的 CLLocationManager,如下方程式碼:

@property CLLocation *location; // 取得的位置 @property id  delegate; // 設定 delegate @property CLLocationDistance distanceFilter; // 當使用者移動多遠之後才會更新座標  @property CLLocationAccuracy verticalAccuracy; // 設定準確度 - (void)startUpdatingLocation // 開始更新座標 - (void)stopUpdatingLocation // 停止更新座標 - (void)startUpdatingHeading // 開始更新羅盤方向 - (void)stopUpdatingHeading // 停止更新羅盤方向

此外,為了能夠接收得到的資料,我們也需要設定 delegate,並且實做以下方法:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation; // 取得座標 - (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading; // 取得羅盤方向 - (void)locationManager:(CLLocationManager *)manager didFailLoadWithError:(NSError *)error; // 處理錯誤

Map Kit

最後我們要談的就是 Map Kit,也就是 iPhone 上用來顯示地圖的元件。而想當然爾,背後的技術是透過 Google 地圖,所以地圖資訊算是相當完整,也因此支援衛星雲圖的功能。除此之外,Map Kit 也可以用來轉換 CLLocation,將其座標位置轉成平常使用的地址。

而在 Map Kit 的 API 中,MKMapView 顧名思義就是用來顯示地圖的 View 元素,除了顯示地圖之外,MKMapView 也提供了地圖上的標記跟顯示使用者當下位置的功能,擁有以下 Properties:

@property MKCoordinateRegion region; // 顯示區域 @property CLLocationCoordinate2D centerCoordinate; // 中央座標 @property MKMapType mapType; // 地圖類型 @property NSArray *annotations; // 地圖上的標記 @property MKUserLocation userLocation; // 使用者的位置

除了這些 Property 之外,也有許許多多的 delegate 方法,有興趣的讀者還請參考投影片 21、22 兩頁,或者是 MKMapView 的 Class Reference

而我們剛剛有看到 MKMapView 有提供地圖標記的功能,而這些地圖標記並非獨立的類別,而是實做 ProtocolMKAnnotation 來完成。或者是也可以直接使用 MKPlacemark:

- (void)initWithCoordinate:(CLLocationCoordinate2D *)coordinate addressDictionary:(NSDictionary *)dictionary;

至於使用者的當前位置,則是透過 MKUserLocation,具有以下 properties:

@property BOOL updating (getter = isUpdating); // 是否在更新中 @property CLLocation *location; // 目前的位置 @property NSString *title; // 標題  @property NSString *subtitle; // 次標題

最後,Map Kit 也提供了從地理座標找地址的功能,透過 MKReverseGeocoder:

- (void)initWithCoordinate:(CLLocationCoordinate2D)coordinate; @property id  delegate; - (void)start; - (void)cancel;

當然也有 delegate:

- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark; - (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error;

結論

這次的課程內容包含了 UIWebView 和 Map Kit 的相關介紹,這兩者在 iPhone 應用程式中常常出現,實用度也是相當的高!在下一次的課程中,我們將一同探討如何在 iPhone 中整合手機中的通訊錄設計一些應用程式,還請期待!

參考資源


精選熱門好工作

Video/Image Processing Software Engineer

PicCollage 拼貼趣
臺北市.台灣

獎勵 NT$20,000

iOS 工程師

FunNow
臺北市.台灣

獎勵 NT$20,000

BD商務開發 (無經驗可)

WeMo Scooter
臺北市.台灣

獎勵 NT$4,000

評論