ニフクラ mobile backend(NCMB)では各種言語向けにSDKを提供しています。その中で最も新しいSwift SDKについて、その使い方を紹介します。
この記事では複数回に分けて、カメラメモアプリを作ってみます。Swift SDKの使い方はもちろん、NCMBの基本的な利用法を学ぶのに役立ててください。前回は画面の仕様とSwift SDK導入までを解説しました。今回は認証処理の実装と、写真アップロード処理までを作成します。
なお、今回のコードはNCMBMania/camera_memo_swift: Swift SDKを使ったカメラメモアプリのコードですにアップしてあります。
認証画面について
認証処理を行う画面は LoginView.swift
になります。前回も書きましたが、NCMBの処理を抜いたSwiftUIのコードは次のようになります。
//
// LoginView.swift
// camera
//
// Created by Atsushi on 2021/06/23.
//
import SwiftUI
import NCMB
struct LoginView: View {
@State private var userName: String = ""
@State private var password: String = ""
@Binding var isLogin: Bool
var body: some View {
VStack(spacing: 16) {
TextField("ユーザ名", text: $userName)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(maxWidth: 280)
SecureField("パスワード", text: $password)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(maxWidth: 280)
Button(action: {
signUpOrLogin()
}, label: {
Text("新規登録/ログイン")
})
}
}
func signUpOrLogin() {
// ここに認証処理を実装します
}
}
認証処理について
今回はユーザ登録とログインを一つの画面で行うようにします。もちろん分けて実装しても問題ありません。実装は signUpOrLogin
内で行います。まず入力されたユーザ名 userName
とパスワード password
を使ってユーザ登録処理を実行します。
let user = NCMBUser()
user.userName = userName
user.password = password
// ユーザ登録処理の実行
user.signUpInBackground(callback: { _ in
})
もしすでに一度ユーザ登録を行っている場合、この処理はエラーになります。しかし、それを無視してそのままログイン処理を実行します。
NCMBUser.logInInBackground(userName: userName, password: password, callback: { _ in
self.isLogin = NCMBUser.currentUser != nil
})
ログイン処理がうまくいっていれば NCMBUser.currentUser
にログインユーザの情報が入ってきます。ログインユーザ情報が入っている(= nil ではない)状態であれば isLogin が true になります。
signUpOrLogin
関数の実装は次の通りです。
func signUpOrLogin() {
let user = NCMBUser()
user.userName = userName
user.password = password
user.signUpInBackground(callback: { _ in
NCMBUser.logInInBackground(userName: userName, password: password, callback: { _ in
self.isLogin = NCMBUser.currentUser != nil
})
})
}
メモ入力画面について
ログインが完了すると isLogin が true になります。その結果、 UploaderView.swift
にて写真選択/入力画面が表示されます。
// 以下抜粋
if isLogin {
VStack(spacing:30){
MemoView(imageData: $imageData)
HStack(spacing:60){
Button(action: {
self.source = .photoLibrary
self.isImagePicker.toggle()
}, label: {
Text("Photo library")
})
Button(action: {
self.source = .camera
self.isImagePicker.toggle()
}, label: {
Text("Take Photo")
})
}
// 以下略
写真を撮影または選択すると、そのデータは imageData
に入ります。そうすると MemoView
にて選択した写真が表示されます。
var body: some View {
// 画像データがあれば表示
if imageData.count != 0 {
Image(uiImage: UIImage(data: self.imageData)!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: 250)
.cornerRadius(15)
.padding()
TextField("メモ", text: $text)
.textFieldStyle(RoundedBorderTextFieldStyle())
.frame(maxWidth: 280)
Button(action: {
// アップロード処理(後述)
}, label: {
Text("Upload")
})
.alert(isPresented: $uploaded, content: {
Alert(title: Text("アップロード完了"), message: Text("写真をアップロードしました"), dismissButton: .default(Text("閉じる"))
)
})
}
}
アップロード処理について
Upload
ボタンをタップするとNCMBへのアップロード処理を開始します。まずファイル名をUUIDを使ってユニークなものを生成し、その名前を使ってNCMBFileオブジェクトを作ります。
let fileName = "\(UUID()).jpg"
let file = NCMBFile(fileName: fileName)
次にそのデータへのアクセス権限として NCMBAcl を設定します。ログインユーザだけが読み書き可能としています。それを NCMBFile オブジェクトの acl に設定します。
var acl = NCMBACL.empty
let user = NCMBUser.currentUser
acl.put(key: user!.objectId!, readable: true, writable: true)
file.acl = acl
アップロードは saveInBackground
メソッドで実行されます。引数として、写真データを渡します。保存処理は非同期です。
file.saveInBackground(data: self.imageData, callback: { result in
switch result {
case .success:
// 処理成功
case let .failure(error):
print("保存に失敗しました: \(error)")
return;
}
})
アップロード処理が成功したら、続けてメモを保存します。メモ用のNCMBObjectを作ります。クラス名(DBでいうテーブル名相当)はMemoとします。
let memo = NCMBObject(className: "Memo");
そしてフィールド(DBでいうテーブルのカラム名)として、メモの入力内容 text
とアップロードしたファイル名 fileName
を設定します。ACLもファイルと同じものを設定します。
memo["text"] = text
memo["fileName"] = fileName
memo.acl = acl
そしてデータストアもファイルストアと同じく saveInBackground
で保存処理を行います。保存がうまくいったら入力内容を消したり、キーボードを非表示にしています。
memo.saveInBackground(callback: {_ in
self.uploaded.toggle()
self.text = ""
DispatchQueue.main.async {
UIApplication.shared.closeKeyboard()
}
})
まとめ
今回は認証処理とファイルストアへのアップロード、データストアへの保存処理を作成しました。とても簡単にクラウドへの保存処理が行えますので、ぜひ使ってみてください。
次回は保存したデータを取得して一覧表示する処理を作成します。