練習紀錄-api上櫃投信買賣超 part2

Astrid
8 min readJul 17, 2021

--

四分之三成品

reloadData() 要放在哪個scope

CodingKey 改JSON屬性名

到最頂最底不能滑:tableView.bounces = false

省略前三個字: dropFirst(_:)

買進、賣出、買賣超:超過3位數用逗號分開

UILabel 換行

reloadData() 要放在哪個scope

我在part1中提到,做這個練習,最困擾我的是:一樣的程式碼,每次build出來的app,都不一樣。後來我發現了,癥結點就是我把tableView.reloadData()放在viewDidload裡。由於不確定下載資訊要多少時間,所以也無法確定在viewDidload中,下載完成了沒,在viewDidloadtableView.reloadData(),很可能根本沒有資料可以reload。造成我之前的慘痛經驗 — 有一次成功build的經驗(想必那次的下載速度特別快),但再也成功不了,甚至開始懷疑起電腦與網速。

最保險的做法,就是把放在確定資訊下載完畢後的地方,也就是URLSession.dataTask(with: url) { (Data?, Response?, Error?)}當中closure處理Data?的部分。這個closure是在.resume()執行完畢(也就是資料下載完成後,會才會執行的程式碼。

要注意的是,URLSession預設是在background queue作業,記得要把reloadData放到main queue,因為這是在處理畫面。

URLSession預設是在background queue,記得要把reload放到main queue,因為這是在處理畫面。

CodingKey 改JSON屬性名

JSON原始的屬性名第一個字是大寫

上櫃買賣超JSON原始的屬性名第一個字是大寫,而在swift約定成俗的習慣用法,第一個字是大寫的只有型別。因此我們最好能把屬性的名字改成第一個字小寫。如果直接改的話,會出現錯誤,因為要讓swift成功拆解JSON的第一要件就是屬性名要跟JSON的一模一樣(大小寫也要一樣),所以需要經過特別的處理才能「改名」。

這個特別的處理是:

在模擬資料的struct裡,做一個名字叫CodingKeys的enum。

enum CodingKeys: String, CodingKey{
case 新名 = “舊名”
case 新名 = “舊名”
case 新名 = “舊名”
case 舊名
}

*enum的名稱一定要叫CodingKeys(記得加s),enum的 raw value設為String,並遵從protocol CodingKey (型別沒有s)。

*case 要把所有的屬性寫出來,就算沒有要改名也要寫。沒改名的情形直接寫case 舊名 即可,後面不用等於。

其實就是先用enum完成改名程序,然後下面就直接用新名來指定哪個屬性是什麼型別。把extension寫在上面是為了要容易理解。

而在下載完資料之後,呼叫各屬性的方法跟原本一樣,直接用新名字即可。

到最頂最底不能滑:tableView.bounces = false

tableView.bounces 預設是true。

這是在設定滑到最頂端與最底端,沒有資料時,能否繼續滑的選項。

而當 tableView.bounces = true的狀況下,會有兩個選項自動伴隨而來。

tableView.alwaysBounceVertical = false

tableView.alwaysBounceHorizontal = false

省略前三個字: dropFirst(_:)

“Date”: “1100714”

日期我只想要顯示後面四個數字,所以我把前三個字丟掉。我使用了instance method叫dropFirst(_:)它會return SubString。

但使用後才發現,原來無法把SubString 指派給只接受String的Label.text。

SubString真實身份是String.SubSequence,跟String是不一樣的型別。

所以後來就把String加在前面,把return 的SubString變成String。

把String加在前面,把return 的SubString變成String。line39

我成功把日期從1100716變成0716了!

買進、賣出、買賣超:超過3位數用逗號分開

我參考這些文章:Swift: Add separator on Integer using NumberFormatter

…………………..利用 NumberFormatter 顯示 Money

…………………..NumberFormatter

…………………..groupingSeparator

…………………..NumberFormatter.Style

做法是分別在Formmater 和 Int 寫extension。再在呼叫買進、賣出、買賣超這三個String資料時,把它們轉為String,後使用設定好的formmater。

NumberFormatter 的作用是將數字變成特定的字串格式。

A formatter that converts between numeric values and their textual representations.

他有一個屬性叫 .groupingSeparator可指定要用什麼當分隔的東西,我設定逗號。另外一個屬性 .numberStyle則是一組enum內有apple幫我們內建好的各種格式。我們使用的是.decimal,就是每三位數加都點分開的格式。

Examples of formatting styles for different locales

在Int中寫extension,讓這個computed property可以回傳被我們在Formatter改好的格式。

接下來就可以使用啦!請看第42–44行。

42–44行,我們透過在Int, Formatter擴充達到我們希望三位一逗點的顯示。

成果是:

UILabel 換行

參考文章有:

研究顯示文字的 UILabel

iOS SDK | UILabel 分行設定

//12 研究 label 的欄位: Line Breaks & Autoshrink

目前看到比較長的個股名稱,它不足顯示的字就沒有被顯示出來。

91APP should be 91APP*-KY。 譜瑞- should be 譜瑞-KY。

91APP 的全名為91APP*-KY。 譜瑞- 的全名為 譜瑞-KY。

奇怪的是,我設定好自動換行了,而當Label放不下時,它卻沒有自動換行。

Lines 0 ,代表沒有限制行數。Line Break:Character Wrap則是完全不省略文字的模式。

Lines 0 ,代表沒有限制行數。Line Break:Character Wrap則是完全不省略文字的模式。這是目前剩下的問題。

練習紀錄-api上櫃投信買賣超 part1

練習紀錄-api上櫃投信買賣超 part3

--

--