prettyprint

2017年12月22日 星期五

我的 Hello, World


第一個簡單的 App 該怎麼寫?許多書都攏統的寫了一堆,最後 code 程式碼出現了,試跑後,一個完美的結果出現,這時我們學到了什麼?

好像教寫程式就是千篇一律這樣教法,這樣的寫法,能不能換個另外的方式?這樣的教法好像讓我想起了 Assembly 組合語言的年代,即程式語言一直在進步,但教法上依然逗留在石器時代。為何不這樣教?

我的 App 主要的目的用途是什麼?那我需要什麼樣的介面?然後,我又怎樣去實作這個 App 呢?

例如:我想寫一個 Hello, World 的 App 作為練習。那我最後 UI 的呈現方式可能有:

1. 在 iPhone 的畫面上只顯示 "Hello, World!"
2. 按下一個按鈕 Button,然後輸出一個文字字串 "Hello, World!"
3. 還是,按下一個按鈕後,會跳出視窗,視窗上顯示“Hello, World!" 這字串

針對第一個項目,若只是顯示"Hello, World!" 這字串,那在 UI 上我只要加入 Label 這UI Control 控制項即可。

既然 iPhone App 是物件導向設計 Objective Oriented Design,每個物件一定有屬性與方法。例如:Label 有個屬性 Text,而我們只要設定 Text 的值為 "Hello, Wold!" 就好。

若是第二個項目,我們的 UI 需要一個按鈕,點選 click 按鈕後,會將結果 “Hello, World!" 顯示出來。

點選按鈕,然後就顯示文字,這需要寫程式。但,寫完程式後,按鈕這個 UI 又怎麼跟程式 Code 有關聯呢?

最後若是選第三個項目,我們除了要知道第二個項目的運作細節,還要處理按下按鈕後,跳出的視窗細節:這視窗屬於那類的視窗?除了顯示 "Hello, World!" 這文字,如何結束關閉視窗?等等。

第三個項目包含相當多的實作觀念要了解。例如:我們選定跳出的視窗是 Alert 警告視窗。我們會用 UIAlertController 來實作一個 Alert 視窗物件。

為何要用 UIAlertController 呢?由 Apple 官網文件 UIAlertController 得知其繼承 Inheritance 自 UIViewController。 Controller 就像管理者,管理視窗 View 要怎麼呈現。

我們在新增 HelloWorld 這專案 Project 時,選定 Simple View App 這個模板 Template,系統的 default 就帶出一個簡單的 iPhone 畫面,這畫面在 code 程式碼   ViewController.swift 被定義為

class ViewController: UIViewController {
...
}

每個 View 都會由一個 Controller 去管理,這就是為何我們新增 Alert 這個視窗時,必須新增 Controller 的原因。

這看似簡單的第三個項目,實際上已經包含很多 OO (Objective Oriented) 概念及 iPhone App 的設計概念。對剛開始研讀就想一窺就裡的人負擔算是蠻大的。但,學中做,做中學,也是學習的一種方式。有些開發的精髓要隨著 Code 寫久的人才能領略。

PS.  Apple 除了提供 Playground 這互動工具外,另外一個很棒的程式語言測試工具,即 REPL (Read-Evaluate-Print-Loop),這工具在Terminal 環境下操作。

範例 1 :

新增專案後,在 Label 的 Text 屬性設定 "Hello, World!" 即可。



範例 2:

這次我們改用 Button 這個 UI Control,在其Text 屬性設定為 "Hello, World!" ,然後點選 Button 此新增按鈕,按下 Control 鍵不放,之後拖曳至 ViewController.swift,此時會跳出Connect 視窗,將 UI 與 Code 做個關連。


加入程式 print("Hello, World!") 如下:


點選 Hello, World! 這個按鈕後,會將字串 "Hello, World!" 輸出到命令列視窗 (Console)。

範例 3:

在這個範例中,我們實作下列程式:

class ViewController: UIViewController {

    @IBAction func showMessage(_ sender: UIButton) {
        //print("Hello, World!")
        let alert = UIAlertController(title: "My First App", message: "Hello,World!", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }   

}

記得要在生成一個 Alert 物件後,要以 self.present() 顯示出來。



執行後,點選 OK 選項按鈕,此 Alert 會關閉。

範例 4:

在 Terminal 環境下,輸入 xcrun swift 指令,即進入 Swift 的 REPL 此互動環境:

要進入 Swift 環境,需要輸入下列指令:

$ sudo xcode-select -s /Applications/Xcode.app/Contents/Developer/

然後輸入:

xcrun swift




/end

開發iPhone App, 選擇 Swift 或 Objective-C?


Swift 語言優於 Objective-C,這爭議由Simon Ng 知名作家的"iOS 10 App 程式設計實力超進化實戰攻略“一書的範例可看出:

Objective-C

const int count = 10;
double price = 23.55;
NSString *firstMessage = @"Swift is awesome.";
NSString *secondMessage = @"What to you think?";
NSString *message = [NSString stringWithFormat:@"%@%@",firstMessage, secondMessage];
NSLog(@"%@",message);

Swift

let count = 10
var price = 23.55
let firstMessage = "Swift is awesome."
let secondMessage = "What to you think?"
let message = firstMessage + secondMessage
print(message)

哇!Swift 在語法Syntax上的表達簡潔而有力!

首先,每行程式 (Statement) 的結尾: Swift 不用分號(; semicolon) 來作為每行程式的結尾。這是 C/C++/C#/Java 慣用的寫法。

第二:常數與變數的宣告。在Swift的常數以 let 宣告,而變數則以 var 宣告。這點與 Objective-C 在常數宣告必須特別指定用 const 並無法說俗優俗劣。但,Swift 的常數或變數不需要特別定義其資料型態 (Data Type),而是Swift 可以根據其指定的值來推論 (Infer) count 是整數型態,而 price 是 double 資料型態。

當然 ,Swift 宣告整數或變數時,也可定義其 Data Type。例如:

let count : Int = 10
var price : Double  = 23.55

第三:字串的宣告簡潔。Swift 在字串(String)的宣告是直覺式的,僅以 firstMessage = "Swift is awesome." 表達。但,Objective-C 卻需用很繞口的符號來完成一件事。例如:

NSString *firstMessage = @"Swift is awesome.";

在字串前面用 * 符號 (*firstMessage) 對初學者而言會問:這是什麼玩意啊?殊不知這是 C 語言的餘孽。在 C 裏頭,符號 * 代表指針(pointer),所以 firstMessage 儲存的是指向 "Swift is awesome." 這一串值的位置。

讀到此,是不是有點頭痛?學 C 的功力好壞就看 Pointer 是否運用自如得體!

第四:字串的串接 (Concat) 上,Swift 是大大優於 Objective-C。後者對初學者而言看似用了奇怪的語法。2 個字串的串接在直覺上不是“第一個字串” 串接 (concat) "第二個字串“就好了嗎?至於串接(concat)這指令是用加號(+)或是其他符號都可。

字串的操作(插入/刪除/修改某字元/字串)在 Objective-C 較為複雜。被宣告為 NSString 的字串是常數字串,不能變更,必須透過 NSMutableString 宣告為變數字串才行。對 Swift 而言就沒有這麼麻煩,字串是否為常數或變數只是由 let 或 var 的宣告定義。

最後,在字串的顯示上,Objective-C 需定義顯示字串的格式 (print format),而 Swift 則由其編譯器去推論判斷。

結論:

Swift 的簡潔語法可大大增加程式的開發速度,同時在程式碼維護的易讀 (Readable) 也有加分的作用。用 Swift 編譯出的執行檔 executable code,根據官方說法,其執行效能又優於 Objective-C。Swift 這種種的優點讓程式開發者不心動也難 ?!

/end
prettyPrint();