Swift 3.0 Class Note – Audio(播放音樂 & 錄音相關)

Presenter : Wei Wei

播放系統音效

  • 函式庫:AudioToolbox
  • AudioServicesPlayAlertSound(SoundID)

github : git@github.com:dan12411/HelloSystemSound.git

播放APP內的音樂

  • 函式庫:AVFoundation
  • 物件:AVAudioPlayer (with Error Handling)
  • 丟入音樂檔 -> 找到檔案位置 -> 產生url -> 產生AVAudioPlayer
    • 找到檔案位置:Bundle.main.path(forResource: “Right", ofType: “mp3″)
    • 產生url:URL(fileURLWithPath: path)
  • %e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-10-06-%e4%b8%8b%e5%8d%882-27-10丟檔案會跳出的選單

github : git@github.com:dan12411/HelloPlayAudio.git

 播放手機內的音樂

  • 函式庫:MediaPlayer
  • 需加上Privacy – Microphone Usage Description
  • 物件:MPMusicPlayerController
  • Protocol : MPMediaPickerControllerDelegate
  • func :
    • mediaPickerDidCancel(使用者按下Cancel,把MediaPicker收起來)
    • mediaPicker(使用者選到某首歌,就開始播放音樂)

github : git@github.com:dan12411/HelloMediaPlayer.git

手機錄音並播放錄音檔

  • 函式庫:AVFoundation
  • 需加上Privacy – Microphone Usage Description
  • 物件:AVAudioRecorder(錄音)、AVAudioPlayer(播放錄音)、isRecording(記錄狀態是否在錄音)
  • Protocol : AVAudioRecorderDelegat
  • 找到存檔路徑 -> 產生url -> 設定錄音相關的數據 -> 產生AVAudioRecorder -> 錄完產生AVAudioPlayer
  • fun : audioRecorderDidFinishRecording(錄完要做的事)
  • AVAudioSession.sharedInstance().setCategory(調整 session 狀態, with Error Handling)

github : git@github.com:dan12411/HelloRecordAudio.git

 

Swift 3.0 Class Note – Type Method, Singleton, DatePicker, Enum, Error Handling

Presenter : Wei Wei

Instance Method(實例方法) vs. Type Method(型別方法)

  • Type Mehod 與 Object-C的Class Method類似
  • 實例方法是被型別的某個實例呼叫的方法
  • 型別方法是定義型別本身呼叫的方法
  • 型別方法的寫法:
    • 屬性前加關鍵字static
    • 函式前加關鍵字class

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-10-07-%e4%b8%8b%e5%8d%8812-41-00

ref: Methods

Singleton(單例模式)

  • 單例模式確保每個指定的類別只存在一個實例對象,並且可以全局訪問那個實例。
  • 單例的寫法
    • 一樣屬性前加關鍵字static & 函式前加關鍵字class
    • init(){}前加private : 只有自己可以初始化自己

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-10-07-%e4%b8%8b%e5%8d%8812-41-35

ref: Singleton

Date

  • Date<–>DateFormatter<–>String
  • 藉由DateFormatter轉換Date和String
  • .date 現在的時間
  • DateFormatter() 生出DateFormatter (.date or .string 轉換Date和String)

  • .datastyle 調整顯示時間格式
  • .dataFormat 調整時間格式
  • %e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-10-07-%e4%b8%8b%e5%8d%8812-33-05
  • 製作倒數計時器
    • class : Timer
    • 用Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.countdown), userInfo: nil, repeats: true)實現,每隔一秒,實作countdown

github : git@github.com:dan12411/HelloDatePicker.git

Enum(列舉相同類型的選項)

  • 初衷:避免拼字錯誤
  • 可加上相關值(Associated Value)

  • 可加上Mehods

  • 可加上Raw Value(記要給型別)

  • 常常搭配 Switch 使用,系統已知列舉,最後不用寫default

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-10-07-%e4%b8%8b%e5%8d%8812-43-54

螢幕快照 2016-10-07 下午1.09.15.png

Error Handling(關鍵詞throws搭配try, do & catch)

  • 用Enum定義錯誤(服從Error protocol)
  • 加上關鍵詞 “throws" 標明錯誤處理的程式碼
  • 加上關鍵詞 “try" 呼叫方法
  • 改寫函式內的程式碼,e.x., 用guard抓出錯誤
    • guard 與 if..else 不同在於,可以把通過條件後的動作,寫在大括弧 {} 外
  • 用do & catch輸出錯誤訊息

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-10-07-%e4%b8%8b%e5%8d%8812-50-26

Swift 3.0 Class Note – 轉場(segue, storyboard reference) 與 資料傳遞, Generic

Presenter : Wei Wei

轉場

  • Storyboard上的ViewController,class是連結到swift檔案中的class,而非整個檔案,因為同名,容易混淆,也就是同一個swift檔,可定義多個class給不同的ViewController,也可以分開用多個swift檔來管理
  • XIB 就像是stroyboard的前身
  • 五種轉場方式(換到下個畫面)
    1. 從item直接拉segue到目的地
    2. 從Controller拉segue到目的地
      • seque給定identifier
      • 拉item action,再用perform segue指定用哪個segue
      • 使用時機:某個Controller的畫面,多種情況會觸發,只要在storyboard設計一次,再從程式觸發
      • 注意事項:傳入不存在的Storyboard會crash
      • 例子:檔案的Go to View 2 & Got to View 2-1 Button
    3. 用程式碼觸發,不用拉segue
      • 先找到目的地的storyboard,UIStoryboard(name: “Main", bundle: nil)
      • 目的地的Controller填上storyboard ID :myStorybard.instantiateViewController(withIdentifier: “redview")
      • 再用present or push的方式來轉場
      • 回到前一畫面dismiss(vs. present) or pop(vs. push)
      • 回到第一個畫面popRoot
      • 注意事項:由上而下或由左往右切換,似乎進入和回來都要同一種,不然沒辦法切換
      • 例子:檔案的Go to View 3 & Back Button 、Go To New View(跨storyboard)
    4. storyboard reference
      • storyboard reference,填入目的地Storyboard & Reference ID
      • 例子:Go To Yellow Button
    5. 執行逃生門(unwind Segue)
      • 目的地畫面的ViewController寫好@IBAction func functionName (_segue: UIStoryboardSegue)
      • 來源畫面拉上一Button,並跟來源畫面storyboard頂部的exit連結上
      • 例子:檔案的Back To Main Button

github : git@github.com:dan12411/HelloNavigationController.git

資料傳遞

  • 資料傳到下一頁的方法:用prepare(for segue)方法,給定segue.identifier & destionationViewController
  • 四種資料回傳的方法
    1. 利用protocol (最常見的做法):觸發條件 – 按下Back按鈕
      • 設定一個protocol
      • 第二個畫面ViewController產生delegate
      • 讓第一個畫面ViewController當delegate
      • 服從此protocol
      • 第一個畫面ViewController & 第二個畫面ViewController的媒介底下實作function(setColor)
      • 相較於Callback的優點:you can create a base class that conforms to the protocol delegate and avoid code redundancy
      • 相較於Callback的缺點:delegation is harder to implement
    2. 執行逃生門方法 by unwind Segue (很酷的方法):觸發條件 – 按下Back To Main按鈕
      • 目的地畫面的ViewController寫好@IBAction func functionName (_segue: UIStoryboardSegue)
      • 來源畫面拉上一Button,並跟來源畫面storyboard頂部的exit連結上
      • 目的地個畫面用@IBAction下用segue.source as? SecondViewController跟第二個畫面要資料
      • 實作function(setColor)
    3. Notification (通知中心):觸發條件 – viewWillDisappear(SecondViewController),使用時機 – 同時要通知多個ViewController時,比較方便
      • SecondViewController在viewWillDisappear底下寫code
      • 一樣先得到被選的顏色
      • 發出通知NotificationCenter.default.post
      • ViewController設置接收通知後要做的事
      • ViewController在viewDidLoad設置接收器addObsever
      • ViewController拆除接收器deinit{…removeObsever}
      • 優點:不需要編寫多少代碼、簡單實現1對多的方式,相較於 Delegate 可以實現更大的幅度的通信、能够傳遞參數(object和userInfo)
      • 缺點:編譯期間不會檢查通知是否能够被觀察者正確的處理、需要在通知中心移除觀察者、通知名稱不一致,會出現不同步的情况、測試的时候,通知傳遞的過程很難控制和跟踪、不能從觀察者獲得任何的回饋信息
    4. AppDelegate (萬佛朝宗的概念):觸發條件 – viewWillAppear(ViewController)
      • 藉由UIApplication.shared.delegate as? AppDelegate傳值
      • 用到Class Method & singlton的觀念

more : iOS: Three ways to pass data from Model to Controller

  • 讓鍵盤跳出來:myTextfield.becomeFirstResponder()

  • 讓鍵盤掉下去:myTextfield.resignFirstResponder()

  • 05781322-058F-4B0C-9B09-C33B4C02645E-85338-00016F525E02E73D.gif

    Generic(泛型)

  • 定義出一個適用任意型別的函式及型別。可以避免重複的程式碼且清楚的表達程式碼的目的
  • 陣列(Array)和字典(Dictionary)都是泛型的。
  • 額外觀念:輸入輸出參數(inout)

ref : Swift 起步走 – 泛型、函式

螢幕快照 2016-10-07 下午1.02.29.png

 

Swift 3.0 Class Note – Closure & Search Display

Presenter : Wei Wei

Closure

  • Closure 是沒有名字的(func)函式

  • Closure Swift是一個值,有型別,屬Reference Type

  • 把函式寫成Closure的步驟:

    1.把名字刪掉,存進一個變數

    2.把參數和回傳值放進大括號裡面,加上關鍵詞“in"

// Func //
func addClosure (number1:Int, number2: Int) -> Int {
number1 + number2
return result
}

// Closure //
let addClosure: (Int, Int) -> Int = {
(number1:Int, number2: Int) -> Int in
let result = number1 + number2
return result
}
  • Closure 可當某函式的參數

  • Closure 可當某函式的回傳值

  • Closre 不僅可回傳值,還可把附近的值回傳出去

  • Closure 可以跟陣列配合使用

  • Closure 簡寫步驟

    1. 如果已經知道參數跟回傳值的型別的話,可以省略closure裡的參數和型別

    2. 如果closure 有回傳值,而且程式碼是一行的話,可以省略return

    3. 可以用$0 $1 …等代表參數

    4. 如果closure 是最後一個參數的話,可以把closure 寫在小括號外面

    5. 如果closure 是唯一個參數的話,可以省略小括號

/// 篩選有文字"o"
import Foundation
fruitArray.filter({
(fruit: String) -> Bool in
return fruit.contains("o")

})

/// 省略版
fruitArray.filter{ $0.contains("o") }

git@github.com:dan12411/HelloClosureBasic.git

Search Display

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-09-30-%e4%b8%8b%e5%8d%885-24-32       0c289a08-9778-49ed-920a-15d1e1a2e627-22061-00010c60e9e850ee

  • 架構上先有一個TableViewController (i.e. SearchTableViewController)
  • 設定資料來源Array – appleProducts
  • 設定Delegate的Section, Row, Cell
  • 再來是重頭戲:
    • 需要新增一UISearchResultsUpdating的protocol
    • 需要新增一UISearchController用來執行搜尋工作的類別
    • 需要新增一UITableViewController用來顯示搜尋結果
    • 需要新增一Array儲存搜尋結果
    • 實作UISearchResultsUpdating下的函式updateSearchResults產生搜尋結果&重新整理資料,會使用到optional binding 、 Array的filter方法 & lowercased
    • TableDataSource部分
      • 用if…else 區隔 SearchTableViewController & ResultTableController的資料
    • viewDidLoad()部分
      • 產生 searchController,指定用resultController顯示搜尋結果

      • 連結SearchTableViewController

      • 設定搜尋時,取消反灰

      • 設定顯示搜尋結果的 tableView 負責告訴顯示結果的 tableView 要顯示什麼資料

    • viewWillAppear()部分
      • tableView 降下 20

      • 把搜尋欄加到Header

git@github.com:dan12411/HelloSearchResultsController.git

Swift 3.0 Class Note – UIPickerView, Protocol, POP v.s OOP

Presenter : Wei Wei

UIPickerView(選單)

  • AutoLayout 要點:( 其實很簡單) 設定好  x & y 座標 , width, height
  • 和UITableView類似:
    1. UIPickerViewDataSource 決定選單有幾類的選項 `numberOfComponents`

    2. UIPickerViewDataSource 決定各類的選項,有幾項 `numberOfRowsInComponent`

    3. UIPickerViewDelegate 決定各項標題 `titleForRow`
    4. UIPickerViewDelegate 選取某項後的方法 `didSelectRow`
    5. UITableView的Section對應UITableView的Component

github : git@github.com:dan12411/HelloPickerView.git

Protocol (協定)

  • 不實際定義方法,服從的class(類別)需實作方法
  • 一個class 可服從多個協定,但只能繼承一個父類別(super class)
  • %e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-09-29-%e4%b8%8b%e5%8d%885-58-46
  • 在storyboard將PickerView連結到ViewController,相當於程式碼第86行
  • 第64~66 行& 76~81行,相當於Apple已經幫我們寫好的部分
  • 第70~72 行,相當於我們自己寫上實作的方法
  • POP 相對於 OOP的優點
    1. OOP 如果很多class,容易忘記override
    2. class只能單一繼承super class,缺乏彈性
    3. protocol可當一種型別使用
    4. class 效率較差、資料容易被誤改

ref. :

  1. POP@WWDC
  2. struct or class
  3. POP@Swift

Swift 3.0 Class Note – iOS Application Life Cycle & Memory Management

Presenter : Wei Wei

Application Life Cycle

  • @UIApplicationMain是一個函式,生成UIApplication物件
  • UIApplication 負責初始化並顯示UIWindow,並負責載入應用程式的第一個UIViewUIWindow表單中
  • UIApplication 的另一個任務是説明管理應用程式的生命週期,而UIApplication通過 UIApplicationDelegate的代理來履行任務
  • UIApplication會負責接收事件,而 UIApplicationDelegate則決定應用程式如何去回應這些事件,UIApplicationDelegate可以處理的事件包括應用程式的生命週期事件(比如程式啟動和關閉)、系統事件(比如來電、記事項警告)
  • info.plist告訴@UIApplicationMain要用哪個storyboard

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-09-26-%e4%b8%8b%e5%8d%887-29-21

  • Application Life Cycle (APP層次)
  • View Life Cycle (APP層次下的View Controller層次)
  • 用print的方式在模擬器下觀察變化

Memory Management(ARC)

  • class有屬性就一定要給初始值,有初始值就不用寫init(程式會偷偷幫你寫)

  • 生成實體前只有藍圖,不佔記憶體
  • 有實體才會開始:1. 啟動記憶體 2. 執行init

  • Reference Type & Value Type
  • Retain Cycle : 用弱連結解決(weak) or 無主參考(unowned)

%e8%9e%a2%e5%b9%95%e5%bf%ab%e7%85%a7-2016-09-26-%e4%b8%8b%e5%8d%885-15-06

source : http://blog.appformation.pl/retain-cycles-the-hidden-trap-of-arc-part-3/

reference : https://tommy60703.gitbooks.io/swift-language-traditional-chinese/content/chapter2/16_Automatic_Reference_Counting.html

Others

  • 跨平台:Corona SDK + Lua

Computer Science Class Note : 關聯式資料庫和 SQL

Presenter : ihower

前言 & 關連式資料庫

  • 離線或本地快取,APP會需要使用資料庫
  • 資料持久化不能只存記憶體,不靠網路儲存的話
  • 資料庫與excel的差別:Data Type每個 Column 會定義格式
  • 資料驗證,實務上常做在appliaction端,因為會DB language的人少 & 彈性化考量
  • 關連式資料庫(RDBMS)的ACID特性: e.x., Atomicity (transaction交易一起成功一起失敗)
  • v.s 分散式資料庫(用於流量大,需效能好,非transaction特性)
  • sqlite3 用於單機、APP、嵌入式,輕量級
  • MySQL用於網路(多用戶存取)、效能好
  • PostgreSQL物件導向式,用於報表 or 分析

SQL

  • 分成DDL & DML兩種
  • Definition & Manipulation
  • 建立、刪除和更名 Database & CRUD
  • Queries 要小心 case insensitive 不同資料庫預設不同(分辨大小寫)
  • 條件查詢需要注意有沒有索引 Index (B-tree, O(n) -> O(logn)),模糊搜尋需要用另外的 Full-Text Searching 引擎
  • 物件關聯對映(ORM),好處是方便,缺點是多了一層ORM,抽象洩漏法則,可能會出現漏洞而出錯

Database Schema Design

  • Table設計法則:資料庫正規化(Normalization)
  • 讓資料不重複&高度一致性(增加修改資料效率)
    • 一階: 移除重複語意的 columns
    • 二階: 移除重複語意的 row
    • 三階: 移除不依賴 primary key 的資料(選擇Primary key,e.x, UUID)
  • ETL:分成正規化資料庫(有拆表)與分析資料庫(沒拆表)
  • 關聯設計:通常我們不會笨笨地一階兩階..這樣來正規化,可用一種描述關聯的標準圖表(ER-diagram, 介於二、三階之間)
  • 有時候會為了快取,而特意去正規化

Migrations

  • Schema Migration & Data Migration

*N+1 queries 是資料庫效能頭號殺手: 網站效能