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

Astrid
Jul 18, 2021

--

完成品

這次終於把問題都解決,完成我想要做成的樣子了!

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

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

part2最後留下的問題是我的標籤無法自動換行,以及我還沒把程式碼拆成MVC的模式。以下是這篇會提到的主題:

MVC只有viewController是controller(此正確觀念解決標籤無法換行的問題)

delegate = self 的時機

把Data先印出來,檢查下載到的資料是什麼 的方法

reloadData 到底是什麼

MVC只有viewController是controller

我的cell是自己做一個Class。本來是在ContentTableViewCell中,接到下載到的資料,並把資料指定到各Label。但ContentTableViewCell是View,以MVC的概念,Modal與View不能有直接的交流,一定要透過controller。

於是我把資料指定到各Label的程式碼移到ViewController。ContentTableViewCell只留下各標籤屬性。

MVC模式下,ContentTableViewCell只管View的事。
資料指定到各Label的程式碼應在ViewController(line47–53)

移過去後,我的標籤就可成功換行了!請看91App*-KY及譜瑞-KY。

91App*-KY及譜瑞-KY可以顯示全名。

delegate = self 的時機

當呼叫delegate執行任務時,必須確保已經有人當delegate了。

fundmanager.performRequest()中,有一個任務要delegate印出下載到的資料。但我在呼叫fundmanager.performRequest()之後,才說我是delegate,當要執行印出資訊的任務時,根本還沒有人去當delegate,所以console沒有print出東西。

兩個紅框的程式碼順序應該對調。

當我先寫fundmanager.delegate = self 再呼叫fundmanager.performRequest()就成功print出下載的的資訊了。

把Data先印出來,檢查下載到的資料是什麼

利用 JSONSerialization 印出美美縮排的 JSON

透過 encode(to:) 將 JSON 裡的 array 或物件變成字串上傳

JSON Character Encoding:

JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32. The default encoding is UTF-8, and JSON texts which are encoded in UTF-8 are interoperable in the sense that they will be read successfully by the maximum number of implementations; there are many implementations which cannot successfully read texts in other encodings (such as UTF-16 and UTF-32).

大部分JSON的字串都是UTF-8,所以才寫 String(data:Data, encoding: .utf8)

reloadData() 到底是什麼

之前因為reloadData()放錯位置導致畫面沒有cell。後來我就將很多地方都寫了,也因為這樣又導致cell沒有成功顯示。

在 cellForRowAt裏reloadData()導致cell沒有成功顯示
刪掉之後就成功顯示cell了!

所以到底執行reloadData()這行程式碼,實際上是做了什麼事呢?

我們來看一下quick help

文件指出,使用reloadData()會重新load「所有」建造table的方法。也就是說,在我的project中(目前只使用TableViewDataSource),建造table的方法就是

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCellfunc tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

所以reloadData()實際上是同時呼叫了上面兩個func。但我一開始卻又在被reloadData()呼叫的cellForRowAt方法內,又呼叫了reloadData()。造成一個極度不合理的循環,cell也因此無法正確顯示在tableView上。

附上我的原始碼

--

--