【Swift】Google Books APIsで本を表示するiOSアプリを作る方法!
この記事からわかること
- Google Books APIsの使い方
- Swiftで本を表示するiOSアプリの作り方
- JSONを扱うには?
- Google Books APIsで必要なパラメータの種類
- 表紙画像が表示されない問題の解決法
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
参考文献:公式リファレンス:Google Books APIs
Google Books APIsとは?
Google Books APIsとはGoogleが提供している書籍コンテンツ情報を取得できるRESTfulなAPIです。タイトルや著者、表紙画像やレビューなどさまざまな書籍に関する情報を取得することができます。また任意のパラメータを渡すことでキーワードに一致した書籍を検索することも可能です。またAPIを取得するためのアクセスに認証が不要で、料金もかからないのでさまざまなサービスやアプリに活用されています。
ですが商用利用や一部のデータへのアクセスに制限があるので詳細な利用規約と制限事項については、Google Books APIの公式ドキュメントを確認することをおすすめします。
「楽天ブックス書籍検索API」や「openBD」などをありますが、今回は「Google Books APIs」を使用してSwiftで本を表示するiOSアプリを作ってみたいと思います。
Google Books APIsのURLと中身
Google Books APIsでアクセスするURLは以下の通りです。?q=キーワード
部分に検索したい単語を渡すことでキーワードに一致する書籍の情報を取得することができます。
書籍の検索
書籍IDに一致する書籍情報を取得
取得できるのはJSON形式の文字列です。「書籍の検索」で実行した場合は一致した複数のアイテムが返ってくるのでtotalItems
(一致したアイテム数)なども返ってきます。
おすすめ記事:JSONファイルの構造とは?配列と連想配列の違いを理解して正しい記法を覚えよう!
取得した1アイテムの書籍情報
{
"kind": "books#volume",
"id": "k474zAEACAAJ",
"etag": "fXMSr0WPQK8",
"selfLink": "https://www.googleapis.com/books/v1/volumes/k474zAEACAAJ",
"volumeInfo": {
"title": "詳細!SwiftUI iPhoneアプリ開発入門ノート",
"subtitle": "iOS13+Xcode11対応",
"authors": [
"大重美幸"
],
"publisher": "ソーテック社",
"publishedDate": "2019-12",
"description": "SwiftUIでアプリ開発がスピードアップ!新手法SwiftUIを全力で学ぶならこの1冊!今までやってきた人もこれから始める人も。SwiftUIを丁寧にやさしく解説。Swiftシンタックスの基礎知識も図解入りでしっかり学べます。",
"industryIdentifiers": [{
"type": "ISBN_10",
"identifier": "480071253X"
},
{
"type": "ISBN_13",
"identifier": "9784800712530"
}
],
"readingModes": {
"text": false,
"image": false
},
"pageCount": 335,
"printedPageCount": 335,
"dimensions": {
"height": "24.00 cm",
"width": "19.00 cm"
},
"printType": "BOOK",
"categories": [
"Reference / General"
],
"maturityRating": "NOT_MATURE",
"allowAnonLogging": false,
"contentVersion": "preview-1.0.0",
"panelizationSummary": {
"containsEpubBubbles": false,
"containsImageBubbles": false
},
"imageLinks": {
"smallThumbnail": "http://books.google.com/books/content?id=k474zAEACAAJ&printsec=frontcover&img=1&zoom=5&imgtk=AFLRE73233mfYsggs-WwK5YMmIclFBXmJr6_llqs5fE4tDQTDeRsoFMnp7rbNECqooJHbUmEblyAfomPaFzQU4uPYBIbuBvpc06YkQfoJAxgmRTF0gaZ20qIqCZ1T7lzyMGOVCUfkjgl&source=gbs_api",
"thumbnail": "http://books.google.com/books/content?id=k474zAEACAAJ&printsec=frontcover&img=1&zoom=1&imgtk=AFLRE70VvDfYqtTCepJ5VvVEI8hGpzZ-bcbKpTKo0QF0Q3ZQXuKavnx4OSj2vs3jfanfoMaGkuTNPUlj0ksqtdiMWV3dOgpo7j9Ti3airCgwzkufBb9qCsFDCeLlFyGTLzQmAXtr1NDX&source=gbs_api"
},
"language": "ja",
"previewLink": "http://books.google.co.jp/books?id=k474zAEACAAJ&hl=&source=gbs_api",
"infoLink": "https://play.google.com/store/books/details?id=k474zAEACAAJ&source=gbs_api",
"canonicalVolumeLink": "https://play.google.com/store/books/details?id=k474zAEACAAJ"
},
"saleInfo": {
"country": "JP",
"saleability": "NOT_FOR_SALE",
"isEbook": false
},
"accessInfo": {
"country": "JP",
"viewability": "NO_PAGES",
"embeddable": false,
"publicDomain": false,
"textToSpeechPermission": "ALLOWED",
"epub": {
"isAvailable": false
},
"pdf": {
"isAvailable": false
},
"webReaderLink": "http://play.google.com/books/reader?id=k474zAEACAAJ&hl=&source=gbs_api",
"accessViewStatus": "NONE",
"quoteSharingAllowed": false
}
}
※ちなみにpublishedDate
はYYYY-MM
やYYYY-MM-dd
、YYYY
など年数のみのものや日付まで入っているものもあるので注意してください。
検索で複数返ってきた場合
{
"kind": "books#volumes",
"totalItems": 1080,
"items": [
{
// 書籍1
},
{
// 書籍2
},
]
~~~~~~~~~~~~~~~~~~~^
}
開発する前に
開発する前にAPI絡みのアプリに導入しておくと便利なライブラリを2個紹介します。今回は両者とも使用するのでプロジェクトに組み込んでおいてください。
今回使用するライブラリ
- Alamofire・・・HTTP通信接続ライブラリ
- SwiftyJSON・・・JSON文字列変換ライブラリ
表紙画像URLがHTTP通信なので表示されない
Google Books APIsで取得できる表紙画像のURLはhttp://~
になっているためそのまま取得しようとしてもiOS9以降ではブロックされてしまいます。今回は設定を変更してHTTP通信を許可していきます。
以下の手順で設定しておいてください。
1.info.plistにKeyを追加
2.App Transport Security Settings>Allow Arbitrary Loadsを追加
3.Allow Arbitrary LoadsにYesを設定
さてここまできたらこのように書籍の表紙とタイトルが表示されたアプリを作っていきます。
実装方法
まずは取得した書籍1つの情報を保持するModelを作ります。保持させるデータは最小限にしてあります。
class Book: Identifiable {
var id: String?
var title: String?
var thumbnailUrl: String?
}
続いてAPI処理部分です。ここで先ほどライブラリを2つとも使用します。取得したJSONはモデルにマッピングしてcompletion
で返します。
import Alamofire
import SwiftyJSON
import UIKit
class GoogleBooksAPIRepository {
private var keyword: String = "SwiftUI"
public func getAPI(completion: @escaping ([Book]) -> Void) {
AF.request("https://www.googleapis.com/books/v1/volumes?q=\(keyword)").response { response in
do {
var json = try? JSON(data: response.data!)
completion(self.setVolume(json!))
} catch {
print(error.localizedDescription)
}
}
}
private func setVolume(_ json: JSON) -> [Book] {
let items = json["items"].array!
var books: [Book] = []
for item in items {
let bk = Book()
bk.id = item["id"].stringValue
bk.title = item["volumeInfo"]["title"].stringValue
bk.thumbnailUrl = item["volumeInfo"]["imageLinks"]["thumbnail"].stringValue
books.append(bk)
}
return books
}
}
View部分は以下のようになります。ここはあまり説明する部分はないですがAsyncImage
を使用して画像取得がうまくいかない時にプログレスを表示させています。
struct ContentView: View {
@State var books: [Book] = []
var body: some View {
VStack {
List(books) { item in
HStack {
AsyncImage(url: URL(string: item.thumbnailUrl!)) { image in
image.resizable()
} placeholder: {
ProgressView()
}.frame(width: 100, height: 100)
Text(item.title!)
}
}
}.onAppear {
GoogleBooksAPIRepository().getAPI { results in
books = results
}
}
}
}
Google Books APIのパラメータの種類
Google Books APIでは様々なパラメータが用意されており柔軟な検索が実装可能になっています。その一部を少し掲載しておきます。
複数のキーワードを検索する
複数のキーワードを検索したい場合は+
で繋いで指定します。
https://www.googleapis.com/books/v1/volumes?q=小川糸+ライオン
取得件数の上限を設定
取得件数に上限を設けたい場合はmaxResults=n
形式で指定できます。&
で繋げることができます。
https://www.googleapis.com/books/v1/volumes?q=小川糸&maxResults=5
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。