作業#54 利用API回傳JSON輸入假資料模仿IG主頁&貼文頁面

Poga
彼得潘的 Swift iOS / Flutter App 開發教室
10 min readJan 14, 2022

--

目的:練習利用API回傳的JSON格式取得IG資料並模仿製作出來

原本想練習解析JSON格式用串接API的方式抓取資料,但後來發現API有點問題詢問過Peter後,原來這個IG的API非正式的所以改成用手動輸入去使用資料,這次練習模仿出自家狗狗的IG頁面

畫面

主頁

使用CollectionViewController製作出主頁的相片牆,使用CollectionReusableView製作帳號資訊畫面

貼文

使用UITableView製作貼文一格一格的的畫面

資料API

可用下方的這一串加上帳號名稱取得資料

https://www.instagram.com/帳號名稱/?__a=1

ex:我要使用的帳號

https://www.instagram.com/wooyouxtaro/?__a=1

網址打開後會出現這樣的畫面,以下是JSON格式

Postman

我們可以用Postman去解析我們的JSON格式的資料,如果沒有的話可以透過以下連結下載還有使用教學

Postman畫面

Postman輸入網址後可以用pretty去顯示JSON格式的資料,他會用比較好閱讀的方式顯示,然後開始尋找我們需要的資料

主頁資訊欄
"biography":自我介紹
"external_url":自我介紹裡的連結"edge_followed_by":粉絲"edge_follow":追蹤的人"full_name":名字"profile_pic_url_hd":大頭照"edge_owner_to_timeline_media":貼文數貼文
"display_url":貼文圖片URL
"edge_media_to_caption":貼文內容"edge_media_to_comment":留言人數"edge_liked_by":按讚數

IG API參考連結:

輸入資料

主頁

建立主頁資訊欄的類別

貼文

自訂資料型別

建立貼文資料的類別

CollectionViewController-主頁

一開始發現CollectionViewController不能拉View進去製作帳號資訊欄的時候挺緊張的,還好找到之前學長做的使用CollectionReusableView來製作

CollectionReusableView

畫面使用stackView一層一層的包起來去排版,紅線框起來則是使用到stackView的部分

自訂類別

製作客製化的CollectionReusableView跟CollectionViewCell大同小異,都要用自訂類別在CollectionViewController裡去改變裡面的內容,可以用awakeFromNib去初始一些東西,這裡我就設定大頭照的ImageView變成圓形

CollectionViewCell

CollectionViewCell顯示照片牆的部分設定AutoLayout,塞滿整個CollectionViewCell,設定AspectRatio 1:1寬度暫時先隨便設定,暫時而已後面會以程式去控制寬度

自訂類別

設定每格圖片是(畫面寬度減掉中間間隔/3),然後在awakeFromNib改變AutoLayout設定的寬度

CollectionViewDataSource

在CollectionViewController生成資料

Items數量:貼文數量總數

抓圖

用URLSession去抓圖,用@escaping獲得的data可以在function結束後繼續使用

CollectionViewCell — cellForItemAt

  1. 使用catchPhoto按照indexPath.row帶入每格圖片的URL
  2. 不過如果只是一般抓圖直接給Item去顯示會出現,如果圖片還沒載完就滑動CollectionView會出現圖片在不對的位子,因此先檢查原本的indexPath是否還在原本的位子,如果不是就不顯示在那個位子上,那每次滑動時都會呼叫CollectionViewDataSource要顯示什麼,所以滑動回正確位子就會顯示出來
  3. 另外為了貼文頁面不用再重新抓圖,將抓好的裝進一個空的Array傳送過去下一頁顯示

網路抓圖顯示問題參考連結:

CollectionReusableView — viewForSupplementaryElementOfKind

跟CollectionViewCell類似的方式去改變顯示的內容,另外ofKind要設定CollectionReusableView顯示的種類,那我們要設定成.elementKindSectionHeader

主頁切換至貼文頁

聲明變數用來儲存我們要傳送的資料,然後利用IBSeagueAction去傳送

didSelectItemAt可以獲得使用者所點擊的是哪格然後去執行程式,這便按下去後儲存使用者所點擊的indexPath.row,希望使用者點擊下去是直接出現貼文所在位置而不是從頭開始,然後最後performSegue,儲存位置要在performSegue前不然會跳過去下一頁執行不到

關於IBSegueAction參考連結:

TableViewController-貼文

畫面配置主要是最下方的幾個Label,這四個Label我以stackView包起來,這樣只要其中一個沒有內容就可以用isHidden隱藏起來,另外三個則可以自動縮在一起

UITableViewCell自訂類別

一樣先將畫面上的元件拉@IBOutlet進來,然後在awakeFromNib中讓大頭照變成圓形

接收資料

可以用init的方式在初始化的時候獲得上一頁傳過來的資料

設定NavigationBar的title

通常NavigationBar上的標題都只會有一行文字而已,如果我們想客製化的標題,可以在navigationItem.titleView加入我們想要顯示的view

viewDidLoad

viewDidLoad時就設定好我們的NavigationBar的title,以及將tableView用scrollToRow捲動到使用者所點選的文章

TableViewDataSource

基本上DataSource的顯示方式TableView跟CollectionView顯示客製化的cell是大同小異,另外比較特別的是需要在cellForRowAt轉換時間以及貼文的顯示方式

時間轉換

在API的資料中提供的貼文時間是秒數,我們需要將貼文的時間轉換成日期

字串體轉換

我希望在貼文前能夠像真的IG一樣顯示帳號,但不想另外使用一個Label因為有些貼文並不會在帳號後換行而是直接有內容,所以可以利用NSAtrributedString將帳號字體特別改成粗體,再將貼文型別也改成NSAtrributedString,最後用NSMutableAtrributedString將兩個合在一起

操作畫面

參考連結:

GitHub連結:

--

--