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

在這一堂課程中,我們將看到OCUnit這套Objective-C的Unit testing framework,還有看到Objective-C一些有趣的使用方式,可以幫助我們深入研究Cocoa Touch中framework的內部結構,最後還會提到如何幫應用程式設計多國語言版本,以下是筆者的一些整理,還請多多指教!
評論
評論

在這一堂課程中,我們將看到 OCUnit 這套 Objective-C 的 Unit testing framework,還有看到 Objective-C 一些有趣的使用方式,可以幫助我們深入研究 Cocoa Touch 中 framework 的內部結構,最後還會提到如何幫應用程式設計多國語言版本,以下是筆者的一些整理,還請多多指教!

Unit Testing

Unit Testing 是近年來很熱門的一種測試方法,特點有:

  • 測試特定某部份的功能性
  • 盡量減少外部的相依性
  • 在開發期間頻繁測試

伴隨著 Unit Testing,Test-Driven Development(簡稱 TDD)也逐漸的受大家矚目、採用,TDD 顧名思義,就是在開發程式之前先行撰寫測試的 cases,並且隨著開發一一通過這些預先撰寫的 cases。

用個比喻,編譯器是用來檢查程式的語法正確性,而 unit test 則是檢查語意是否正確。因此,許多 unit testing 的 framework 會在每次編譯完成後進行測試,以確保程式的開發順利。而這樣的框架在 Python 平台有 PyUnit、Java 平台有 JUnit,同樣的,在 Cocoa 的平台上也有 OCUnit 來幫助我們撰寫各種 cases 並且進行 unit testing。而 OCUnit 跟 XCode 也做了完美的結合,可以自動在每次 build 完成後進行測試,並且顯示錯誤。

雖然聽起來有點奇怪,不過 OCUnit 在 Cocoa 中是被稱作 SenTest,所以如果你在文件中看到任何 SenTest 有關的類別,其實就是 OCUnit 測試框架的一部份。

那我們要如何開始撰寫測試程式呢?首先我們必須先建立一個 SenTestCase 的子類別,而這個子類別中所有以 test 開頭的方法都會自動被執行進行測試,而在那些方法中,我們可以使用 SenTestCase.h 中所定義好的 Macros,像是 STAssertNotNil(someObject, @"Some object was nil"); 可以檢查某物件是否並非為 nil,若為 nil 則顯示第二個參數的字串。

此外 SenTestCase 還提供了 - setUp 和 - tearDown 兩個方法可以重載,而這兩個方法分別會在每個 test 方法的執行前和執行後被呼叫。也就是說,我們可以在這兩個方法中建立新的物件,這樣就可以確定每個測試方法之間所使用的物件不會互相干擾。

在課程影片以及投影片的第 14 到第 20 張中有簡單的測試範例,有興趣的讀者還請自行參考。

Objetive-C 的樂趣

Objetive-C 本身是個相當有趣的語言,或許讀者在剛剛閱讀前一部分的時候曾經感到疑惑,為什麼 SenTestCase 可以找到所有以 test 開頭的方法呢?還是有什麼其他有趣的技巧呢?

在學習這些技巧之前,我們得先看看電腦中的 /usr/include/objc 目錄,這裡面包含了 Objetive-C 中的許多定義標頭檔,包含以下:

  • objc.h -- 定義了 id、nil、BOOL 等基本類型
  • message.h -- 定義了 objc_msgSend() 這個方法,用來處理 [foo bar] 這樣的方法呼叫
  • runtime.h -- 在執行期間檢視以及操作 class、protocol 和 methods

而這裡面最有趣的莫過於 runtime.h,裡面包含了以下檢視類別和方法的函式:

  • Method *class_copyMethodList(Class cls, unsigned int *outCount); -- 取得某類別的所有方法,outCount 為方法總數,以陣列方式回傳
  • SEL method_getName(Method m); -- 取得某方法的名稱,也就是 selector
  • IMP method_getImplementation(Method m); -- 取得某方法的實做,也就是實際執行的程式片段
  • char *method_copyReturnType(Method m); -- 取得某方法的回傳值

而得到了這些資訊之後,我們甚至可以修改內容:

  • BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types); -- 增加方法到某個類別中
  • IMP method_setImplementation(Method method, IMP imp); -- 修改方法的實做
  • void method_exchangeImplementations(Method m1, Method m2); -- 交換兩個方法的實做

你可能會很好奇,那為什麼不用 Category 來加入、修改方法就好了呢?背後的原因是,Category 先天上就限制了我們只能做有限的修改,假使我們想要呼叫類別原本所擁有的方法,在 Category 上是無法做到的。

然而,Apple 建議大家盡量不要使用以上這些技巧在公開發佈的軟體當中。事實上,這些修改會影響整個程式的執行,假使你使用了其他人所撰寫的類別方法,你所作的修改很有可能也會影響到那些由他人撰寫的程式碼,而造成一些難以理解的 bugs 產生。

多國語系

大家都知道 iPhone OS 本身就是一個多國語言的作業系統,我們可以輕易的在設定中切換所想要使用的語言,而整個系統中的內建應用程式也會隨之改變,而對於應用程式開發者而言,我們也可以透過同樣的機制處理。

要注意的是,iPhone OS 會自動的幫我們判斷在取用多國語系的資源時所要使用的語言,在做後續的操作時都不需要另外做去指定語言。

多國語言化的整個過程可以分成兩個步驟:

  • 國際化 (i18n) -- 將程式修改成可以支援多國語言的版本
  • 在地化 (l10n) -- 針對每個語言設計所需要的資源

在 iPhone OS 上,我們可以所需要處理的部份僅制於使用者端的顯示元素,這些元素可能會是字串、圖片或是 Nib 等。

以字串來講,對於那些使用者介面上的文字,我們可以將其另外存成.strings 檔案,這檔案透過 UTF-16 編碼紀錄了一組組 key-value 的值。而我們可以透過下列方法來取用這些字串:

// 讀取 Localizable.strings 中的字串 NSLocalizedString(@"Hello", @"Greeting for welcome screen"); // 讀取特定某個 table 的字串,本例為 Greetings.strings NSLocalizedStringFromTable(@"Hello", @"Greetings", @"Greeting for welcome screen");

而為了方便我們能夠快速的建立這些 strings 檔,我們可以在終端機下面使用 genstrings 這個指令,會自動的掃描我們的.m 檔並且產生出.strings 的檔案。

至於對於其他的圖片、nib 檔這類資源而言,我們則是可以透過 XCode 中的下列選項建立多重語系的版本:
而在之後我們就可以在 XCode 中看到同一個資源擁有了多個版本:

結論

我們逐漸走向了課程的尾聲,不知道大家是不是也跟我一樣從 CS193P 的一系列課程中學到很多呢?在下一次,也就是最後一次的正課中,我們將看到如何在 iPhone 平台上使用 OpenGL ES 建立 3D 應用程式,還請各位讀者繼續指教。

參考資源


NEC 以專業的生物辨識驗證技術,為人類生活打造更準確又安全的身份識別方式

NEC 具有多重比對臉部檢測法、攝動空間法、適應領域混合比對等先進技術,讓辨識更準確又快速,不但多次奪下美國國家標準暨技術研究院(NIST)評鑑第一名,在一對多的人臉辨識速度上也是業界之首。
評論
Photo  Credit:NEC 台灣政府公共解決方案事業群群總經理張裕昌
評論

你有沒有在機場使用過 e-Gate 快速通關系統呢?這種利用生物特徵的辨識技術既方便又安全,早在幾年前就已經是很多政府機關使用的成熟技術,讓我們跟著生物特徵辨識領導廠商 NEC 一起瞭解這種技術的原理吧。

生物辨識面面觀

身份辨識是電腦資安領域中很重要的一環,過去我們常常使用「知識辨識」方式來辨識使用者身份,但是使用輸入密碼的方式可能會被忘記,或是容易被破解的問題。至於「持有物辨識」是某種 USB 加密鑰匙,雖然可以省下記憶密碼的麻煩,但也有機率會不小心遺失。

生物辨識則是利用身體上獨一無二的特徵進行驗證,具備唯一性且不易盜用的先天優勢。其實這也不是很新的技術,早在數千年前人類就開始使用生物辨識,比如我們出門看到隔壁鄰居的臉,就能認出他是老王,這就是生物辨識的概念;但是要教會電腦辨識生物特徵,可就不是這麼簡單的事了。

生物辨識驗證領域全球領導廠商 NEC 從 1970 年代便開始研發指紋辨識、掌紋辨識和人臉辨識等技術。目前除了上述技術之外,NEC 也已開發出虹膜辨識、語音辨識,以及原創的耳道聲波辨識技術,這些獨特且高度準確的生物辨識驗證技術解決方案在全球各地都有實際應用的經驗。

NEC 將這些生物辨識驗證技術以「Bio-IDiom」品牌運用在各式應用中,並且以有效的組合運用這些技術,從而打造出「任何人都能安全無慮地使用數位內容」的世界。

NEC  在生物辨識驗證技術有 50 多年的經驗與龐大的研發團隊,並且具有多項領先技術。/Photo  Credit:NEC

領先業界的人臉辨識技術

以人臉辨識技術為例,它是透過攝影鏡頭補捉人臉的畫面,並透過電腦分析臉部各個特徵點的資訊,來判斷受檢人員是不是與登錄的資料相符。

人臉辨識技術有許多優點,由於人臉是平常人們用來判斷對方身份的方法當中最自然的一種,所以使用者的心理負擔很小,使用過程中也無需動手操作,而且一般攝影機就可辨識,讓建置更快速且低成本。此外它還具備有效防止弊端的特色,例如辨識的時候系統能夠留儲「臉部影像記錄」,讓管理者可以目視確認是否相符。

NEC 具有多重比對臉部檢測法、攝動空間法、適應領域混合比對等先進技術,讓辨識更準確又快速,也能在人臉被遮蔽或影像不清楚的情況下正確辨識,不但多次奪下美國國家標準暨技術研究院(NIST)評鑑第一名,在大規模一對多的人臉辨識準確度上也是業界之首。

生物辨識有使用方便、不易被盜用的優點,近年的應用越來越廣泛。/Photo Credit:NEC
除了人臉辨識之外,NEC 也有多種不同的生物辨識驗證技術可以交互搭配使用。/Photo  Credit:NEC

奧運史上首次使用人臉辨識入場

NEC 為 2020 東京奧運和東京帕拉林匹克運動會(Tokyo 2020)成功提供人臉辨識系統,為奧運的安全、可靠和高效舉辦做出貢獻。NEC 台灣政府公共解決方案事業群群總經理張裕昌在訪談中表示:「NEC 提供的臉部辨識系統,用於驗證運動員、工作人員、志工和其他比賽相關成員的身份,當他們進入奧運和帕運選手村、國際廣播中心(International Broadcasting Center, IBC)以及主新聞中心(Main Press Center, MPC),系統會自動進行臉部辨識。該系統為 NEC 生物辨識驗證技術『Bio-IDiom』的核心技術,採用準確度世界第一的臉部辨識技術。」

NEC 提供的臉部辨識系統,用於驗證 2020 東京奧運和東京帕拉林匹克運動會運動員、工作人員、志工和其他比賽相關成員的身份。/Photo Credit:NEC

One ID 帶來更便利的生活

機場是有高度安全考量的場所,因此無論在航空公司櫃台報到、海關查驗、登機口查驗,甚至在免稅店購物都需要旅客出示護照以確認身份,不但過程相當耗時,同時也增加了經常拿進拿出而遺失護照的風險。

以 NEC 提出的 One ID 解決方案為例,旅客只需要登錄其臉部影像,就能在機場辦理與進行各種手續,例如報到、托運行李、安檢、登機等,而不需要出示護照與登機證,不僅能加速程序的進行,還能達到全程零接觸,降低染疫風險。

全球最大航空公司聯盟星空聯盟(Star Alliance)、NEC 集團及國際航空電訊集團公司(SITA)達成一項新協議,在不久的將來,星空聯盟成員航空公司的飛行常客計劃之客戶,將能在任何參與此協議的機場與航空公司使用生物識別進行身份驗證。/Photo Credit:NEC
NEC 希望透過更多元的生物辨識技術改善人類的生活,透過只要伸出手指就能確實證明兒童身份的指紋辨識技術,就可以不受出生國家或地區左右,建立確實執行給予所有兒童合法出生證明與出生登記的環境,同時也打造兒童在成長過程中必要的、確保享有身為國民應有的公共醫療、教育機會與社會之保障。/Photo Credit:NEC

張裕昌提及,目前 NEC 的技術已經達到相當高的準確度與可靠性,未來的發展重點不再是改善辨識準確度,而是發展更多元的辨識種類,以及透過系統整合的方式,結合多種不同技術,以因應更多差異化的使用需求。

此外張裕昌總經理也特別提到,以 NEC 獨家的嬰兒指紋辨識技術為例,可以克服嬰兒指紋會隨時間變化的問題,有助於協助戶政系統不完善的國家追蹤嬰兒疫苗接種情況,發揮降低夭折比例的功效,為人類社會做出實質貢獻。