Dcard APP Demo| Part2:內文與留言

功能介紹:

使用function prepare傳資料
以xib檔做畫面佈置
解析內文與留言之API
時間格式解析
以NSMutableAttributedString做附有圖片的內文
將專案裡的檔案分類

1. 使用function prepare傳資料:

func prepare(for segue: UIStoryboardSegue, sender: Any?)經由Segue進入下一個頁面前會被觸發,將要傳遞的資料在func中定義好,再藉由let controller = segue.destination as? PostViewController決定要將資料傳至那個頁面。

2. 以xib檔做畫面佈置:

畫面佈置上與使用storyboard差異不大,都需要拉元件和拉IBOutlet,同樣地也使用了StackView和AutoLayout將畫面做了編排呈現,唯一的不同是需要使用程式碼控制什麼時候顯示哪個畫面。

使用storyboard時通常會透過辨識碼來取得reuse的cell,由於使用了xib檔佈置畫面,我們必須透過func register註冊cell並設置它的辨識碼,註冊完後就可以使用func dequeueReusableCell重複使用cell,再將取得的response設置於cell的元件上。

3. 解析內文與留言之API:

內文所使用的API網址

https://www.dcard.tw/service/api/v2/posts/文章ID

觀察回傳的response發現,有anonymousSchool和anonymousDepartment,兩者=true時school跟department都會是nil(心情版和感情版可以完全隱藏,校名的部分會變成匿名),所以在定義所使用的資料型別時要記得設成optional。

留言所使用的API網址

https://www.dcard.tw/service/api/v2/posts/文章ID/comments

同樣的觀察留言所回傳的response,一篇正常的留言會像上圖一樣,接著我們定義會使用到的資料型別,這時你會發現為何我content、school和gender設成了optional,這是因為當有留言被刪除時,會沒有以上三個response不設成optional會導致留言出錯,全部都顯示不出來。

如下圖所示這是一篇被刪除的留言,可以看到它沒有content、school和gender,且可以由hiddenByAuthor的值去判斷這篇貼文是不是被刪除了,再去將畫面上做一些變化。

被刪除的留言。

4. 時間格式解析:

此API回傳的時間格式createdAt是代有小數點的ISO8601格式。

因此不能單純使用 ISO8601DateFormatter解析,這邊我們必須於property formatOptions做一些設定,我們設定了[.withInternetDateTime, .withFractionalSeconds],前者指的是標準的 ISO8601 格式,而後者則是包含小數的秒,接著就可以正常解析了。

為了更貼近原版的Dcard,我在時間顯示上做了一些判斷,利用dateComponents(_:from:to:)要比較的部分放在集合Set中,再設定起始時間和結束時間,接著就會得出他們相差幾天或幾小時,超過七天的則會直接顯示幾月幾號,在內文跟留言處都做了同樣的判斷,上面被刪除的留言可以看出。

5. 以NSMutableAttributedString做附有圖片的內文:

先將回傳response的content用func split以”\n“做拆分並回傳Array。

extension UIImage增加需要的功能

同樣extension NSMutableAttributedString

接者使用forEach(_:)剛剛拆分完的content Array,若包含”http”的部分則代表有圖片的url,就在label中加入圖片接者換行,反之則直接加入文字並換行,效果可看操作影片。

後記:

過程中遇到了一些大大小小的問題,有部分解決了,有部分沒得到妥善的解決,這邊跟大家報告個。

1. 留言無法正常顯示:

其實我在上述解析API時有說到,就是當留言被刪除時response中並不會有content、school和gender,則會造成抓不到留言而不能正常顯示,只要將接收的資料型別設成Optional即可解決這個問題。

2. content頁面的contentLabel無法正常顯示內容,一開始以為是AutoLayout的問題,經過了很多測試還是找不到問題,於是便詢問了彼得潘,在經過了一番波折,我將autoLayout設成與彼得潘提供給我的版本相同,但contentLabel依舊沒有自己拉長,我便檢查了其他部分,發現彼得潘的版本是如此將資料給contentLabel,

不使用DispatchQueue.main.async,contentLabel會正常依內容決定高度。

而我是使用了DispatchQueue.main.async,效果如下

使用DispatchQueue.main.async,contentLabel會壓縮成很小。

此問題目前我還沒有解,如果有任何想法歡迎留言告訴我。

3. 發現有些貼文讀不出來,檢查postman的response發現可能是因為內文中有影片,在response content中的http部分,分為圖片和影片,但只做處理圖片的部分導致遇到影片會出現error。

有想到解決辦法但還在摸索中,往後會再補上解決辦法。

4. 圖片顯示問題,遇到橫向的圖片在處理上成效未達預期,會被強制拉長造成比例有問題的狀況。

此問題同上,努力鑽研中。

以上。

操作影片:

程式碼:

參考網站:

--

--