ニフクラ mobile backend(NCMB)では各種言語向けにSDKを提供しています。その中で最も新しいSwift SDKについて、その使い方を紹介します。
この記事では複数回に分けて、カメラメモアプリを作ってみます。Swift SDKの使い方はもちろん、NCMBの基本的な利用法を学ぶのに役立ててください。初回の画面仕様と認証処理に続き、前回は認証処理の実装と、写真アップロード処理までを作成しました。今回は保存したデータの表示、写真データのダウンロードについて紹介します。
なお、今回のコードはNCMBMania/camera_memo_swift: Swift SDKを使ったカメラメモアプリのコードですにアップしてあります。
メモデータの取得
メモデータの取得は ImageView.swift
にて実装します。すでに紹介済みですが、もう一度画面構成を掲載します。
struct ImageView: View {
@State var memos: [NCMBObject] = []
// LazyVGrid用
var columns: [GridItem] = Array(repeating: .init(.fixed(200)), count: 2)
var body: some View {
ScrollView(.vertical) {
LazyVGrid(columns: columns, alignment: .center, spacing: 200) {
Foreach (Memos, Id: \.objectid) { Memo In
Gridimageview(Memo: Memo)
}
}
.onAppear() {
getAllPhotos()
}
}
}
func getAllPhotos() {
// メモデータを取得します(後述)
}
}
メモデータの取得は getAllPhotos
にて行います。まずNCMBを検索するためのNCMBQueryを用意します。対象となるクラス名(DBでいうテーブル相当)は保存したのと同じMemoです。
let query = NCMBQuery.getQuery(className: "Memo")
そして検索を実行します。検索結果はそのまま memos
の中に入れます。
query.findInBackground(callback: { result in
switch result {
case let .success(array):
self.memos = array
case let .failure(error):
print("取得に失敗しました: \(error)")
}
})
memosの中にデータが入ると、ForEachで繰り返し描画されます。この時、ユニークキーは objectId としてください。
ForEach (memos, id: \.objectId) { memo in
GridImageView(memo: memo)
}
グリッド表示について
メモのグリッド表示は GridImageView.swift
にて行います。こちらもすでに紹介済みですが、再度掲載します。
struct GridImageView: View {
@State private var imageData: Data? = .init(capacity:0)
@State var memo: NCMBObject? = nil
@State private var isShowing = false
var body: some View {
GeometryReader { geometry in
if imageData?.count ?? 0 > 0 {
Image(uiImage: UIImage(data: imageData!)!)
.resizable()
.scaledToFill()
.frame(width: geometry.size.width, height: geometry.size.width)
.clipped()
} else {
Rectangle().fill(Color.clear)
}
}.onAppear() {
loadImage()
}.onTapGesture {
isShowing = true
}.fullScreenCover(isPresented: $isShowing) {
ModalView(isActive: $isShowing, memo: memo!, imageData: imageData!)
}
}
func loadImage() {
// 画像を読み込みます(後述)
}
}
画像データを読み込む
ファイルストアから画像データを読み込む処理は loadImage
関数で行っています。ファイルストアではHTTPSアクセスも可能ですが、ACL(アクセス制限)を行っている場合にはデータを取得する方が良いでしょう。こうすることで、他のユーザからは読まれないデータとして利用できます。
まずメモデータからファイル名を取得します。
if let fileName : String = self.memo?["fileName"] {
}
この fileName を使ってNCMBFileオブジェクトを作ります。
let file : NCMBFile = NCMBFile(fileName: fileName)
ファイルデータの取得は fetchInBackground
にて行います。
file.fetchInBackground(callback: { result in
})
処理がうまくいっていればデータが取得できますので、それをimageDataとして適用します。
switch result {
case let .success(data):
self.imageData = data
case let .failure(error):
print(error)
}
imageDataが入れば、それをUIImageのdataとして適用し、Imageオブジェクトで画像として表示します。
if imageData?.count ?? 0 > 0 {
Image(uiImage: UIImage(data: imageData!)!)
.resizable()
.scaledToFill()
.frame(width: geometry.size.width, height: geometry.size.width)
.clipped()
} else {
Rectangle().fill(Color.clear)
}
これでファイルストアから取得した画像データを描画できます。
画像をタップした際の処理
画像をタップした場合にはモーダル表示を行っています。
}.onTapGesture {
isShowing = true
}.fullScreenCover(isPresented: $isShowing) {
ModalView(isActive: $isShowing, memo: memo!, imageData: imageData!)
}
このModalViewは ModalView.swift
にて定義しています。ここでは受け取ったNCMBObjectと画像データをそのまま描画しています。
struct ModalView: View {
@Binding var isActive: Bool
@State var memo: NCMBObject
@State var imageData: Data
var body: some View {
HStack {
Spacer()
VStack {
Spacer()
GeometryReader { geometry in
Image(uiImage: UIImage(data: imageData)!)
.resizable()
.scaledToFill()
.frame(width: geometry.size.width, height: geometry.size.height)
.clipped()
}
if let text: String = memo["text"] {
Text(text).padding()
}
Button("閉じる") {
isActive = false
}
Spacer()
}
Spacer()
}
.padding()
.background(Color(.black))
}
}
これでカメラメモアプリの完成です。
まとめ
今回のカメラメモアプリを通して、NCMBの次の機能を利用しました。
- 認証機能
- ID/パスワードによるログイン
- ログアウト
- ファイルストア
- ファイルアップロード
- ファイルダウンロード
- データストア
- ファイルストアと紐付けたメモを保存
認証機能とデータストアはよく利用される機能ですし、スマートフォンアプリでは写真データもよく利用するでしょう。今回のコードを参考にSwift SDKをぜひご利用ください。