#25 串接第三方 API-以SpaceX API與YouTube API實現解析 JSON 資料、與WKWebView資料傳遞

實現功能

  • 串接SpaceX API,解析回傳的 JSON 資料
  • 自訂型別並顯示資訊於UI上
  • 串接YouTube API以內嵌SpaceX所提供的YouTube影片
  • 透過WKWebView傳遞SpaceX所提供的Reddit網頁
  • 讀取資料時顯示UIActivityIndicatorView (目前使用固定秒數,還沒實現等資料讀取完才結束讀取)

SpaceX API

此API將會顯示SpaceX最新的火箭發射資訊,有很細節的資料與介紹。比較感興趣的是每次發射行動都會有一個logo、YouTube直撥網址與Reddit討論網頁。原本範例內容有提供flickr的圖片,計畫顯示成collectionView但不是每次都有。

此API是從以下文章分享找到了,也有列出其他有趣的應用。有興趣的朋友可以參考看看。

自訂資料型別

此資料結構比較多的連結包含在links裡,會宣告比較多層的物件。

struct SearchResponse: Codable {
let links: Link
let details: String
let name: String
let date_unix: Date

struct Link: Codable {
let patch: Patch
let reddit: Reddit
let flickr: Flickr?
let presskit: URL?
let webcast: URL
let youtube_id: String
let article: URL?

struct Patch: Codable {
let small: URL
let large: URL
}
struct Reddit: Codable {
let launch: String
}
struct Flickr: Codable {
let small: [URL]
let original: [URL]
}
}
}

抓取網路資料

func fetchItems() {
let urlStr = "https://api.spacexdata.com/v4/launches/latest"
if let url = URL(string: urlStr) {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
do {
self.searchResponse = try decoder.decode(SearchResponse.self, from: data)

DispatchQueue.main.async {
//待會處理UI相關資訊

}

}catch {
print(error)
}
}else {
print("error")
}
}.resume()
}

}

Main thread的內容

實例化字串資料

self.nameLabel.text = self.searchResponse?.name
self.detail = self.searchResponse?.details
self.redditStr = self.searchResponse?.links.reddit.launch

抓取圖片的function

self.fetchImage(url: self.searchResponse!.links.patch.small)                            

此寫法不是很完整與安全,之後專案會再優化

func fetchImage(url: URL){
URLSession.shared.dataTask(with: url ) { data, response, error in
if let data = data {
DispatchQueue.main.async {
self.petalImage.image = UIImage(data: data)
}
}
}.resume()
}

解析發射日期的Date資料

if let releaseDate = self.searchResponse?.date_unix {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let releaseDateStr = dateFormatter.string(from: releaseDate)
elf.releaseDateLabel.text = releaseDateStr
}

安裝youtube api

  • 需透過CocoaPods安裝youtube api
  • 由於此專案只要內嵌播放器,沒使用到api key

Embed YouTube Videos in iOS Applications with the YouTube Helper Library | YouTube IFrame Player API | Google Developers

import與宣告YTPlayerView()

import youtube_ios_player_helper
let playerView = YTPlayerView()

將抓取的youtube_id賦值給playView

if let videoID = self.searchResponse?.links.youtube_id {
self.playerView.load(withVideoId: videoID)
}
}

開啟頁面3秒後自動播放(之後實現讀取就播放)

Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { _ in
self.playerView.playVideo()

WKWebView資料傳遞

在顯示網頁viewController內

import WebKit

宣告接收網址的變數

var urlStr: String
init?(coder: NSCoder, urlStr: String){
self.urlStr = urlStr
super.init(coder: coder)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

宣告介面更新的函式

func updateUI() {
if let url = URL(string: urlStr) {
let request = URLRequest(url: url)
webview.load(request)
}
}

成果展現

--

--