今年最受歡迎的電影

從TMDB搜尋Top 20電影排行

--

https://www.themoviedb.org/about/logos-attribution

前陣子研究了TMDB,最近則是來實際應用看看,目前完成了以下功能:

  1. 從TMDB載入2019年度前20部最受歡迎電影排行榜。
  2. 電影海報下拉放大圖片效果。
  3. 首頁電影推薦,從Top 20電影裡面顯示電影海報,每秒換一張圖片。
  4. 使用TableViewCell列出前20部最受歡迎電影,顯示電影名稱及海報、發行日期、電影評分。

成果

iphone 11 pro

最近推出iphone 11剛好也可以更新xcode來用模擬器試用看看,沒看到 iphone 11 pro背後的三顆鏡頭的話,兩支手機正面外觀除了大小不同,看起來好像沒什麼差別;iphone 11 pro我個人蠻喜歡夜幕綠的,改天再去店面看看實機試用一下。

iphone 11 pro夜幕綠

實作紀錄

一、App畫面

首頁畫面命名為FirstMovieViewController ,加入 image view,再用container view 連結搭配 static cell 的 table view controller。

設定畫面的類別,放imageView的FirstMovieViewController 繼承 UIViewController,放電影Top 20清單 TableView的SecondMovieTableViewController 繼承 UITableViewController。

二、從TMDB 載入2019年度前20部最受歡迎電影排行資料

產生URL

TMDB的API URL我是從這裡去設定搜尋條件,依受歡迎度做排序(Sort by popularity)、主要發布日期(primary_release_year:2019),設定完按send request會給我一個URL。

資料為JSON格式

新增Swift File建立自訂型別,針對需要的資料做解析即可,於是我自訂了電影名稱(title)、評分(vote_average)、發布日期(release_date)、電影海報(poster_path),因為怕自己會搞混所以我名稱幾乎都跟API的名稱一樣。

寫function用URLSession連結取得電影海報的資料,透過URLSession的dataTask執行抓資料,並在背景儲存資料array,最後呼叫resume才會開始執行任務。

FirstMovieViewController

接著在imageView裡顯示電影海報。

問題?

一開始抓不到電影海報的資料,圖片都無法顯示,很困惑為何資料都抓到了,image view裡面還是一片空白。

明明就有抓到資料

仔細讀API文件後才發現,TMDB API裡圖片的取得有些限制,必須先指定欲取得的圖片尺寸,才能夠取得圖片資料。

人家API有說,你要指定Size啊!
海報各種尺寸大小

到底要怎麼先指定size再取得海報圖片的URL了,一開始也是不知道該怎麼辦,然後就先擱在一邊環島去了(笑),環島第一天在抵達高雄後,因為時間是正中午天氣很炎熱不想在外面曬太陽,找了一間咖啡廳坐下,打開MacBook Air又開始想~要怎麼寫呢?

環島途中在咖啡廳腦力激盪

不知道是不是因為腦袋有放鬆再開始動腦的關係,靈光一閃想到,如果我已經取得海報poster_path的URL的話,在poster_path的URL前再加上指定的海報Size不就好了嗎?

假設海報poster_path的URL為:ziEuG1essDuWuC5lpWUaw1uXY2O.jpg

尺寸的URL為:https://image.tmdb.org/t/p/w500/

合起來就好了!

其實沒有很難不用想太多(笑),於是我這樣寫:

海報圖片終於顯示出來了!

還是說旅行也能當作充電讓腦袋清晰一點呢(笑~)

三、電影海報下拉放大圖片效果

FirstMovieViewController裡面加入的 image view就是要來放電影海報的,storyboard拉好之後設定 image view的auto layout,高度條件設為 450,之後往下捲動時,將修改高度的條件,增加圖片的高度。

auto layout

連結圖片高度條件的 outlet — imageViewHeightConstraint

設定表格的 contentInset 及背景顏色 — 設定於表格的上方顯示圖片,圖片的高度設定為 450,因此定義常數 imageOriginalHeight 儲存高度 450,然後將表格 contentInset 的 top inset 設為 imageOriginalHeight,讓表格的上方多出一塊高度 450 points 的空間。

捲動時調整圖片的高度和亮度 — 定義 protocol UIScrollViewDelegate 的 scrollViewDidScroll(_:),此 function 將在表格捲動時觸發,並在其中調整圖片的高度和亮度。

從起始位置往下捲動時 scrollView.contentOffset.y 將小於 originalOffsetY,修改圖片的高度條件,依據捲動的距離變高,而從起始位置往上捲動時將設定表格的背景顏色,讓圖片隨著捲動的距離逐漸變暗。

四、從Top 20電影裡面顯示電影海報,每秒換一張圖片

前面設定好圖片位置及下拉放大、向上捲動變暗的功能後,就要來寫每秒換一張圖片的效果了。

本來想要依照排行榜一張一張去換圖片,想不到要怎麼寫,先用亂數產生圖片的方法試試看。

畫面載入後使用timer去執行每秒鐘換一次海報圖片,順序亂數決定。

問題?

用模擬器Run一陣子之後app突然閃退,顯示『 Index out of range 』,看來我的亂數方法不是個好方法(汗…)。

Index out of range

請教小王子之後才知道我每執行亂數一次就重新載一次資料不太好,後來想想還是要依照排行榜一張一張去換圖片比較適當,小王子提供我比較好的方法:改成從TMDB載下來的資料先存成array,再從背景執行,確認movies.count是否大於零,如果為true,則執行self.setMovieInfo(film:self.movies[self.index])設定電影海報圖片及執行self.time()改成每三秒換一次海報圖片。

getMovieInfo取得電影資料
setMovieInfo設定顯示電影海報

當然圖片的URL也要注意,要遵從API的規定,先指定尺寸再取的圖片URL。

載資料失敗會出現提示訊息。

popAlert( )

每三秒換下一張電影海報。

timer執行換海報

原本是設定畫面載入就執行timer一次重新載電影資料,現在改成畫面一載入就執行getMoiveInfo載好電影資料,再依照count去決定海報圖片,執行每三秒換海報圖片的動作,比較不耗資源。

也要設定關閉app畫面即停止timer,以防止在背景持續執行。

五、列出前20部最受歡迎電影,顯示電影名稱及海報、發行日期、電影評分

在SecondMovieTableViewController裡先抓電影資料,並把資料存成array。

SecondMovieTableViewController裡的getMovieInfo

以Table View Cell顯示20部最受歡迎的電影名稱、海報、發行日期及電影評分。

Table View Cell的設定

繼續下個功能,未完待續…

續集(關於預告片URL的研究):

前言(研究TMDB API):

GitHub

歡迎一起腦力激盪:)

參考文章:

如果有值得大家參考的地方再麻煩大家幫我拍拍手喲,謝謝大家耐心閱讀🙇‍♀️

--

--

Julia Wang
彼得潘的 Swift iOS / Flutter App 開發教室

Learning Programming , Hiking , Travels , Tour , Exploring nature 『你必須要很努力,才能看起來毫不費力』