0
0

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.

NCMBのSwift SDKを使って日報アプリを作る(その1:画面の説明とSDKの導入)

Posted at

NCMBのSwift SDKを使ってデモアプリを作ってみます。今回は業務系でよくあるニーズの日報アプリを作ってみます。実際にはデータストアやファイルストアを使うので、応用すれば汎用的に使えるはずです。

今回は画面の説明とSDKの導入までを進めます。

コードについて

今回のコードはNCMBMania/swift_daily_reportにアップロードしてあります。実装時の参考にしてください。

利用技術について

今回は次のような組み合わせになっています。

  • Swift 5.5
  • Xcode 13.0
  • NCMB Swift SDK 1.2.1

仕様について

今回はシンプルにするために認証は利用していません。入力された日報データをデータストアに保存しますが、写真が追加されている場合にはファイルストアにも保存します。また、レポート画面では日付を使ってデータストアの検索を行い、一致するデータの一覧表示を行います。

利用する機能について

チャットアプリで利用するNCMBの機能は次の通りです。

  • データストア
    • 日報データの保存
    • 日報データの検索
  • ファイルストア
    • 写真のアップロード
    • 写真のダウンロード

画面について

今回はSwiftUIを以下の5つのViewに分けています。

ContentView.swift

タブを2つ表示します。1つ目は入力画面(InputView)、2つ目はレポート画面(ReportView)です。

struct ContentView: View {
    var body: some View {
        TabView {
            InputView()
                .tabItem {
                    VStack {
                        Image(systemName: "pencil")
                        Text("入力")
                    }
            }.tag(1)
            ReportView()
                .tabItem {
                    VStack {
                        Image(systemName: "list.bullet")
                        Text("レポート")
                    }
            }.tag(2)
        }
    }
}

Simulator Screen Shot - iPod touch (7th generation) - 2021-10-06 at 14.57.17のコピー.png

InputView.swift

日報の入力画面です。本文と日付が基本で、任意で写真を追加できます。ナビゲーションバーに保存ボタンを追加して、押すとデータをデータストアに保存します。

struct InputView: View {
    @State private var date = Date()     // 日報の日付
    @State private var text = ""         // 日報の本文
    @State private var showAlert = false // アラート表示用のフラグ
    @State private var message = ""      // アラートのメッセージ
    
    @State var imageData : Data = .init(capacity:0) // // 選択された写真データ
    @State var source:UIImagePickerController.SourceType = .photoLibrary // カメラまたはフォトライブラリ
    @State var isImagePicker = false // 写真ピッカーを表示する際のフラグ
    
    var body: some View {
        NavigationView {
            VStack(spacing: 10) {
                // 画像モーダルへの遷移用
                NavigationLink(
                    destination: Imagepicker(
                        show: $isImagePicker,
                        image: $imageData,
                        sourceType: source
                    ),
                    isActive:$isImagePicker,
                    label: {
                        Text("")
                    })
                // 日報の日付を選択
                DatePicker("日付",
                    selection: $date,
                    displayedComponents: .date
                )
                // 日報の内容を記述するTextEditor
                TextEditor(text: $text)
                    .frame(width: UIScreen.main.bounds.width * 0.8, height: 200)
                    .overlay(
                        RoundedRectangle(cornerRadius: 5)
                            .stroke(Color.blue, lineWidth: 2)
                    )
                // 画像が指定されれば、サムネイル表示
                if imageData.count != 0 {
                    Image(uiImage: UIImage(data: self.imageData)!)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(height: 100)
                        .cornerRadius(15)
                        .padding()
                }
                // 写真選択モーダルの表示
                Button(action: {
                    self.source = .photoLibrary
                    self.isImagePicker.toggle()
                }, label: {
                    Text("写真を選択")
                })
            }
            .navigationBarTitle("日報入力", displayMode: .inline)
            .toolbar {
                // 右上のアイコンで保存しょりを実行
                ToolbarItem(placement: .navigationBarTrailing){
                    Button(action: {
                        save()
                    }) {
                        Image(systemName: "icloud.and.arrow.up")
                    }
                }
            }
        }
        .alert(isPresented: $showAlert) {
            Alert(title: Text(self.message))
        }
    }
    
    // 日報を保存する処理
    func save() {
    }
}

Simulator Screen Shot - iPod touch (7th generation) - 2021-10-06 at 14.57.17.png

ReportView.swift

日報データを検索、結果を一覧表示する画面です。最初は日付だけを表示します。

struct ReportView: View {
    @State private var date = Date()            // 検索対象の日付
    @State private var ary: [NCMBObject]? = nil // 検索結果のNCMBObject(配列)
    
    var body: some View {
        NavigationView {
            VStack(spacing: 10) {
                if self.ary == nil {
                    VStack {
                        // 検索対象を指定(日報の日付)
                        DatePicker("日付を選択してください",
                            selection: $date,
                            displayedComponents: .date
                        )
                        // 検索実行
                        Button(action: {
                            search()
                        }, label: {
                            Text("日報を表示")
                        })
                    }
                } else {
                    // 検索結果をリスト表示
                    List {
                        ForEach(self.ary!, id: \.objectId) { report in
                            ReportRowView(report: report)
                        }
                    }
                }
            }
            .navigationBarTitle("日報検索", displayMode: .inline)
            .toolbar {
                // 日付データを消す(最初の状態に戻す)アイコン
                ToolbarItem(placement: .navigationBarTrailing){
                    Button(action: {
                        self.ary = nil
                    }) {
                        Image(systemName: "xmark.circle")
                    }
                    .disabled(self.ary == nil)
                }
            }

        }
    }
    
    // 指定された日付の日報データを検索する関数
    func search() {
    }
}

Simulator Screen Shot - iPod touch (7th generation) - 2021-10-06 at 14.59.31.png

ReportRowView.swift

検索結果の一覧表示用、1行データ用のViewです。表示されたタイミングで画像データをファイルストアからダウンロード、表示します。

struct ReportRowView: View {
    @State var report:NCMBObject // 表示する日報データ
    @State var imageData : Data = .init(capacity:0) // 日報に紐付いた画像データ
    
    var body: some View {
        // タップした際にの遷移
        NavigationLink(destination: DetailView(obj: report, imageData: $imageData)) {
            HStack(alignment: .top) {
                Spacer().frame(width: 10)
                VStack(alignment: .leading) {
                    HStack(alignment: .top) {
                        VStack {
                            // 画像データの有無を確認
                            if self.imageData.count == 0 {
                                // ないときにはダミー画像
                                Image(systemName: "photo")
                                    .resizable()
                                    .frame(width: 60, height: 60)
                                    .scaledToFit()
                            } else {
                                // 画像があれば表示
                                Image(uiImage: UIImage(data: self.imageData)!)
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .frame(width: 60, height: 60)
                            }
                        }
                        VStack(alignment: .leading) {
                            // 日報本文の一部を表示
                            Text((self.report["text"] ?? "") as! String)
                                .lineLimit(3)
                        }
                    }
                }
                Spacer()
            }
            .onAppear {
                // 画面が表示されたタイミングで画像を読み込む
                loadImage()
            }
        }
    }
    
    // 画像を読み込む関数
    func loadImage() {
    }
}

DetailView.swift

一覧でタップされた日報の詳細表示を行うViewです。一覧から渡されたデータストアオブジェクト、画像を表示します。

// 日報の詳細表示用View
struct DetailView: View {
    @State var obj: NCMBObject    // 日報用データストアのオブジェクト
    @Binding var imageData : Data // 日報に添付されていた画像データ
    
    var body: some View {
        VStack {
            // 画像データがあれば表示
            if self.imageData.count > 0 {
                Image(uiImage: UIImage(data: self.imageData)!)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 200, height: 200)
            }
            // 日報の本文
            Text((obj["text"] ?? "") as! String)
        }
        // タイトルに日付を表示
        .navigationBarTitle(dateTitle(), displayMode: .inline)
    }
    
    // タイトルに出す内容を作成する
    func dateTitle() -> String {
        // 日付フォーマットの作成
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "ja_JP")
        dateFormatter.dateFormat = "M月d日の日報"
        // 日報データの日付を使ってタイトルを作成
        return dateFormatter.string(from: (obj["date"] ?? Date()) as! Date)
    }
}

Simulator Screen Shot - iPod touch (7th generation) - 2021-10-06 at 14.59.37.png

Imagepicker

写真を撮影、またはフォトライブラリから写真を選択します。コードは【SwiftUI】カメラ機能の実装方法【撮影画像とライブラリー画像の利用】から拝借しています。

今回のプロジェクト

今回は言語がSwift、インタフェースがSwiftUI、ライフサイクルはSwiftUI Appとしています。

SDKのインストール

プロジェクトを開いて、Package Dependenciesの中にある + アイコンをクリックします。

ScreenShot__2021-10-04_18_35_29.png

パッケージ名が色々と出てくるので、左上のURL入力欄にて下記のURLを入力します。

ScreenShot__2021-10-04_18_35_37.png

https://github.com/NIFCLOUD-mbaas/ncmb_swift

そうすると ncmb_swift が出てくるので、右下にある Add Package ボタンを押します。

ScreenShot__2021-10-04_18_35_41.png

確認ダイアログはそのままで、Add Package ボタンを押します。

ScreenShot_ 2021-10-04 18.35.47.png

これでインストール完了です。

ScreenShot_ 2021-10-04 18.35.51.png

初期化

今回はSwiftUIを利用しています。ライフサイクルもSwiftUIです。

まずSDKをインポートします。

import SwiftUI
import NCMB

ContentViewをダミーのVStackでラップします。

VStack {
    ContentView()
}

そのVStackのonAppear内で、NCMBの初期化を行います。

var body: some Scene {
        WindowGroup {
            VStack {
                ContentView()
            }.onAppear() {
                // NCMBのアプリケーションキーとクライアントキーを設定
                let applicationKey = "YOUR_APPLICATION_KEY"
                let clientKey = "YOUR_CLIENT_KEY"
                // 初期化
                NCMB.initialize(applicationKey: applicationKey, clientKey: clientKey)
            }
        }
}

まとめ

今回は日報アプリの仕様と画面、NCMBの初期化までを解説しました。次は日報入力データの登録を解説します。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?