iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
自我挑戰組

iOS Junior的菜雞之路系列 第 8

風起雲湧,資料薈萃的API串接

  • 分享至 

  • xImage
  •  

我覺得一個App的精髓之一就在於能夠提供什麼內容,目前看到市面上的大部分App都是會串接API作為使用,能夠提供更多更方便的功能

那麼這次不要再餵假資料了,來餵點真的

之前題目有提到是會類似IMDB的模式,那麼就串接IMDB的API吧!

申請一組開發帳號

我使用的是Rapid API,記得先去註冊一組自己的帳號

然後我使用的是這個IMDb的API提供

如上圖所示,被我用黃色色塊遮住的地方就是關於你的APIKey,用來作為跟這隻API溝通的Key
右邊的Code Snippets其實也有Swift的可以看Code怎麼寫的
我這邊也提供一下我的寫法

Model成型

MVVM中 Model的部分負責串接API下來的資料
先觀察API的資料結構

struct HomeCellViewModel: Codable {
    let d: [LayerTwo]?
}

struct LayerTwo: Codable {
    let img: ImageURL?
    let id: String
    let movieName: String
    let type: String?
    let rank: Int?
    let actress: String
    let startYear: Int?
    let period: String?

    enum CodingKeys: String, CodingKey {
        case img = "i"
        case id
        case movieName = "l"
        case type = "q"
        case rank
        case actress = "s"
        case startYear = "y"
        case period = "yr"
    }
}


struct ImageURL: Codable {
    let imageURL: String

    enum CodingKeys: String, CodingKey {
        case imageURL = "imageUrl"
    }
}

因為有些資料不是API一定會給,所以要使用optional的方式

串API

// 在ViewModel內

// param就是輸入自己想要查詢的內容
func downloadData(param: String) {
    var urlString = "https://imdb8.p.rapidapi.com/auto-complete"
    
    // 一定要有這個Headers才能跟API溝通到
    let headers = [
        "X-RapidAPI-Key": "....(你自己的Key)",
        "X-RapidAPI-Host": "imdb8.p.rapidapi.com"
    ]
    
    urlString += "?q=\(param)"
    let url = URL(string: urlString)!
    var urlRequest = URLRequest(url: url)!
    urlRequest.httpMethod = "GET"
    urlRequest.allHttpHeaderFields = headers
    URLSession.shared.dataTask(with: urlRequest) { data, response, error in
        do {
            if let data = data {
                let decoder = JSONDecoder()
                let result = try decoder.decode(HomeCellModel.self, from: data)
                self.dataList = result
                // 在outputs中定義的,會在VC綁定
                // 其實就是在VC中執行tableView.reloadData()
                self.reloadList?()
            }
        // 下面這麼一大串是為了幫助找出錯誤,因為常常在Decode的時候並不知道是哪邊錯誤
        // 透過這樣Print出來就可以抓出明顯錯誤
        } catch let DecodingError.dataCorrupted(context) {
            print(context)
        } catch let DecodingError.keyNotFound(key, context) {
            print("Key '\(key)' not found:", context.debugDescription)
            print("codingPath:", context.codingPath)
        } catch let DecodingError.valueNotFound(value, context) {
            print("Value '\(value)' not found:", context.debugDescription)
            print("codingPath:", context.codingPath)
        } catch let DecodingError.typeMismatch(type, context)  {
            print("Type '\(type)' mismatch:", context.debugDescription)
            print("codingPath:", context.codingPath)
        } catch {
            print("error: ", error)
        }                               
        
    }
}

如此一來,再把剛剛從VM中拿到的資料一回去Reload其實就能得到API所回傳的資料
再透過前天說的Kingfisher的串接方式,就可以把圖片顯示出來


坑:
最坑的莫非就是Decode Error,每次遇到Decode Error如果沒有上面的func,那麼就找出問題到底在哪邊

還有就是要注意哪些API所給的資料是沒有的,否則Decode Error就會找上門。


上一篇
編排的藝術師UICollectionViewDelegateFlowLayout
下一篇
可不可以把影片放進去一下下就好
系列文
iOS Junior的菜雞之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言