0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Swift SDKを使ってカメラメモアプリを作る(その2:認証処理と写真アップロードまで)

Last updated at Posted at 2021-06-23

ニフクラ 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()
    }
})

まとめ

今回は認証処理とファイルストアへのアップロード、データストアへの保存処理を作成しました。とても簡単にクラウドへの保存処理が行えますので、ぜひ使ってみてください。

次回は保存したデータを取得して一覧表示する処理を作成します。

イントロダクション (Swift) : クイックスタート | ニフクラ mobile backend

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?