2023年1月8日日曜日

Firestoreでのデータの保存について2

 昨日に引き続き、今回は、Firestoreにデータの保存(書き込み)ができるか、確認を行います。

Firestoreへの保存確認

アプリ名.swiftファイルを以下のように編集する。

import SwiftUI

import FirebaseCore

import Firebase

import FirebaseFirestore


class AppDelegate: UIResponder, UIApplicationDelegate {

    

    func application(_ application: UIApplication,

                     didFinishLaunchingWithOptions launchOptions:                   [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        FirebaseApp.configure()

        Firestore.firestore().collection("users").document("Message").setData([

            "UserMessage": "message",

            "Date": "messageDate",

            "UserId": "messageId",

        ], merge: false) { err in

            if let err = err {

                print("Error writing document: \(err)")

            } else {

                print("Document succesfully writen!")

            }

        }

        return true

    }

}


アプリをビルドした際にデータが保存されているか、Cloud Firestoreで確認する。

usersというコレクションの中に、
Messageというドキュメント、さらにその中に、
以下のデータが格納されていることが確認できます。
  • Date"messageDate"、
  • UserId "messageId"、
  • UserMessage "message"
これで親、子、孫のように階層状にデータが保存できることがわかりました!

 


2個目の個人開発アプリ、リリースしました!

この年末年始で個人開発アプリ、2個目を無事にリリースしました!

開発環境

  • Xcode 14.2
  • SwiftUI
  • MacBook Air M1 メモリ8G

開発期間

 約6日間、合計40時間程度
 (リジェクト対応含む)

アプリコンセプト

 アプリ起動後簡単に、一定時間毎に通知するタイマーを設定できる

アプリ開発背

 つい最近、こたつを朝からつけっぱなしで外出して夕方に気がつき、妻に叱られたので「スマホのアラーム機能をわざわざ設定するのも面倒だよなぁ・・・」と思い、「じゃあアプリ起動するだけで通知できるようなアプリを作ればいいじゃん!」ってことで開発しました!
他の学習で行き詰まっており、息抜きも兼ねてです笑

想定するユーザー

 こたつやストーブを消し忘れやすい人たち(私)

実装した機能

  • UserNotificationを用いた通知機能(アプリ起動中でもバックグラウンドでも通知)
  • UserDefaulsを用いた内部データ保存機能
  • Timer.scheduledTimerを用いたカウントダウン機能
  • NavigationStackを用いた画面遷移(かなり特殊に感じました・・・)
  • 通知が許可されていない場合に表示する、アラート機能(設定画面への遷移含む)
  • GoogleAdmobを用いたインタースティシャル(全画面)広告表示機能

アプリ画像





アプリURL

 もしよかったら、ダウンロードしてみてください!

このアプリの今後について

 特にありませんが、機能改修希望や不具合ありましたら、ご連絡いただければ対応考てます!

2022年10月25日火曜日

Firestoreでのデータの保存について1

前回制作したアプリでは、Realmを用いてデータの保存処理を行なっていました。

しかし、端末内に保存されるため、アプリを削除すると、データも共に消えてしまいます。

そのため、今回はFirebaseのCloud Firestoreというものを使って、データの保存処理について実装します。そこで学習したことを簡単にまとめていきます。

概要

  • モバイル開発、ウェブ、サーバー開発に対応したデータベース
  • 階層データ構造に対応
  • リアルタイムアップデート
  • オフラインサポート(オフラインでもキャッシュから読み書き可能)

開発環境:Xcode (Ver.13.4.1)、SwiftUI

実装について(Firestore自体の設定は省略。基本的に手順通りに進める)

  1. Firebaseにアクセスし、プロジェクトを作成。
  2. iOSアプリを選択し、アプリの登録を行う。
  3. バンドルIDはXcodeにて確認できます。
    (アプリプロジェクトファイル選択 >TARGETSのプロジェクト選択
     >General >Bundle Identifier)
  4. 設定ファイルをダウンロードし、Xcodeにドラックアンドドロップで追加する。
    (Copy items if neededにチェックを入れること)
  5. Firebase SDKの追加
    CocoaPodsやSPM(Swift Package Manager)にてインストールします。
    私は、SPMにて導入しました。導入方法は以下の通りです。
     XcodeのFile>Add Packagesを選択し、右上の検索窓に、
     「https://github.com/firebase/firebase-ios-sdk.git」を入力し、必要なライブラリを導入する。
    ただしここが一番の躓きポイントでした・・・
    様々なサイトや書籍を参考にしたものの、どれを導入すべきか、明記しているものがなく、記載通りではエラーが出るなどして、かなり導入に時間を要しました。
    肝心のところを・・・覚えてません。思い出し次第追記します。
  6. 初期化コードの追加
    SwiftUIの場合の導入については、公式ドキュメントに記載がないので、他の方の記事を参考に記述しました。というか、Firebase公式ドキュメント、何事もざっくりしか書かれておらず、これだけでは初学者には実装困難です。
    AppDelegate.swiftファイルはないため、プロジェクト名.swiftに以下を追記します。
    ・import Firebase
    ・class AppDelegate内のfunc application(~)内に FirebaseApp.configure()
  7. 次にまたウェブに戻り、Cloud Firestore(Firestore Database)を選択し、ルールの設定などを行う。
     allow read, write: if true;  tureにすることで、アクセス可能になります。
  8. ここからは、データの書き込みが行われているかの確認手順ですが、続きは後日・・・?

参考書籍:つくって学ぼiOSアプリ開発

2022年10月4日火曜日

2個目のアプリ作成開始!SwiftUIにトライ!!

2個目のアプリ作成開始!今回はSwiftUIを学びながら進めていこうと思います!
10月2日:アプリ設計
10月3日:ワイヤーフレーム作成、SwiftUI学習、Home画面作成
10月4日:Home画面大まかにVIewとして完成

因みに、私はiOSアカデミア(プログラミングスクール)入校以前(半年くらい前)は、書籍でSwiftUIは軽ーく学んでました!ので、余裕余裕と思いきや・・・久しぶりに扱うと、案外難しい!
そこで、ここが違った!というところを本日はまとめていきます!

主な相違点

  1. 視覚的にViewにコンポーネントを配置する操作(StoryBoard)がない!
  2. 上記に伴いオートレイアウトの制約もない!
  3. コードを記述したら、常にプレビューに反映され、見ながらレイアウトできる!
  4. コンポーネント実装にあたり、コードが違う!
数日の学習だけで上記のような点が挙げられます!
これらに対して、StoryBoardでの実装方法を学ぶ前(スクール入校前)は、
  1. StoryBoardって難しそう・・・
  2. え、設定むっず!!
  3. SwiftUIの方が、最新だし、すぐプレビュー見れるし最高!
  4. 割と記述簡単だー
っていう認識でした!しかしStoryBoardを学んだ後にSwiftUIを復習する中で、以下のように感じました!
  1. ついついコンポーネントを直接配置したくなる!もやもや
  2. オートレイアウトないから、レイアウト難しい・・・
  3. プレビューがあるけど・・・処理が重い・・・(M1 MacBook Air 8G)
  4. 記述方法が難しい・・・
慣れによるものとは思いますが、慣れてしまえば案外StoryBoardの方がやりやすく感じるかもしれません!
因みに、スクール的には、まだ現場ではStoryBoardでの実装が多いとのことで、そちらのカリキュラムでした!

本日は時間ないので、以上!

2022年10月1日土曜日

比較して学ぶRxSwift入門 学習

 今日から書籍「比較して学ぶRxSwift入門」を元に、学習開始!学んだことを記録していきます!気になった方はぜひ書籍を手に取ってみてくださいね!

リアクティブプログラミングとは?

時間と共に変化する値と振る舞いの関係を宣言的に記述するプログラミング手法。
・・・と言われてもわかりませんよね?
こちら書籍でExcelを用いた例があり、それを見れば理解しやすいかと思います!
簡潔にいうと、A+B=Cという式があった際に、AもしくはBの値が変化した場合に、Cも変化するよ!的なプログラミングってことですね。

RxSwiftの導入について

CocoaPodsを用いる場合、以下の通りです。
  1. ターミナルにて、導入したいプロジェクトのディレクトリへ移動
  2. コマンド「pod init」を実行 > Podfileが生成される
  3. 「Podfile」を開き、「pod 'RxSwift'」「pod 'RxCocoa'」を追記し保存(バージョンは指定しない)
  4. コマンド「pod install」を実行

Observable(監視可能な?)とは?

イベントを検知するためのクラス。ストリームとも言われる。
Obsarvable:イベント発生元(.tapなど)
Obsarver:イベント処理(onNextなどの中身)

通知するイベントの種類

  • onNext:デフォルトのイベントを返す。値を格納でき、何度でも呼び出し可能
  • onError:エラーイベント。1度だけ。購読(?)破棄
  • onCompleted:完了イベント。1度だけ。購読(?)破棄

Disposeについて

購読(?)を破棄し、メモリリークを回避するためのもの。

SubjectとRelayとは?

Observableのイベント検知 + イベントの発生ができる

以下の4種類が存在
  • PublishSbject
  • BehaviorSubject
  • PublishRelay
  • BehaviorRelay
Relayに流せるイベントは、onNext のみ。(逆を言えばエラーがないことの保証となる)

Publishはバッファを持たず、Behaviorはバッファを持つ。
(subscribe時に一つ過去のイベントを受け取流ことができ、
 最初にsubscribeするときには宣言時に設定した初期値を受け取る)

 subscribeとは:購読する、約束するという意味。

使い分け

  • Subject:通信処理やDB処理など、エラー発生時に処理を分けたいとき。
  • Relay:UIに値をBindする。(onErrorやonCompletedが発生すると、購読が止まる(その先のタップや入力イベントを拾えなくなる)ため。

bindとは?

RxSwiftでは、単方向のデータバインディング。
subscribeする場合は処理を記述するが、bindすることでよりコードが簡潔になる。

Operatorとは?

Observableに対し、イベントの変換(mapなど)・絞り込み(filterなど)などの加工を施して、新たにObservableを生成する仕組み。


2022年9月29日木曜日

作成済(レイアウト済み)アプリへのScrollView追加実装について

 アプリ配信後、現在の職場の方数名にアプリをダウンロードして、使ってもらったところ、とあるおじ様のiPhone8にて、レイアウト崩れを確認。

前回のアプデにて、レイアウト改善できた。・・・はずだった。

アプデしてもらうと・・・あら不思議!画面下部の登録ボタンだけ見切れて、肝心のデータ保存ができない!!

Labelなどのフォントサイズは指定して、同機種シミュレータで見切れないことも確認したのだが・・・・なぜだ!?というわけで、ScrollView実装に踏み切りました!実装自体は簡単ですが、レイアウト完成済ということもあり、めっちゃくちゃ苦労しました!


実装における問題点

  • ScrollViewを追加配置すると、作成していたViewより前に来るので配置換えが必須。
  • 上記解消のため、コンポーネントの配置換えをすると、オートレイアウトの制約が全て解除される!(ここが一番の問題点)
以上の問題が発生。特にオートレイアウトの制約解除はキッツイ・・・今までの苦労が水の泡に・・・。ってなるので、必死に試す、調べる、試す・・・を繰り返すこと数時間?やっと損害の少ない方法にたどり着いた!(多少は手直し必要です。ですが全部より断然マシです)


解決方法!(ここに至るまでが大変だった!)

  1. ScrollView及びその上にViewを配置、各種設定。(この手順はこちらのサイト参照)
  2. レイアウトを崩さずに、ScrollViewに乗せたい(スクロールしたい)コンポーネントを全選択する。
  3. Xcodeのメニューにある、Editor>Embed in>View を選択すると、選択したコンポーネントが一つのViewコンポーネントに格納される。
  4. このViewコンポーネントを、手順1で配置したScrollView上のViewに格納
  5. そうすると、一部エラーが出て、制約の手直しが必要になるものの、大まかなレイアウトは崩れずにScrollView上に配置できる。制約の手直しも、ほぼオートで大丈夫。(自分の場合)

以上!


2022年9月27日火曜日

iOSアプリ設計パターン入門(書籍) 学習2

MVPとは?

画面の描画処理とプレゼンテーションロジックとを分離するアーキテクチャ

  • Model:純粋なドメインロジックやそのデータを持つ(MVCと同じ)
  • View:ーザー操作の受け付けと、画面表示を担当する
  • Presenter:View と Model の仲介役であり、プレゼンテーションロジックを担う

目的

保守のしやすさ向上

MVVMとは?

画面の描画処理とプレゼンテーションロジックとを分離するアーキテクチャ

ViewとViewModelを関連づける(データバインディング)ことで、ViewModelの状態変更に同期してViewの状態も更新される。

  • Model:純粋なドメインロジックやそのデータを持つ(MVCと同じ)
  • View:ーザー操作の受け付けと、画面表示を担当する
  • ViewModel:View-Model 間の画面表示のための仲介役
と、これだけ見るとほぼMVPと同じ・・・??と感じます。
データバインディングするかしないか、くらいの違いでしょうか・・・?

実装手段として、以下の手段がある
  • Nontification Center:手間もコード量も多い、非現実的、実装コスト高い
  • RxSwift(外部ライブラリ):学習コストかかる、ライブラリのアプデに追従する必要、記述が容易
以上!
詳しいことは、以下の書籍を購入して確認してくださいね!
図や、実装に関するコードとかも記述あります!
私には難しいことまではまだまだ理解できないので、かけません笑

flutterについて、学んだことなど

Swiftについて学んできたため、つい比較してしまいがちです。 SwiftUIと比較して、書いてみました。 似ているようで似ていない flutterには、SwiftUIにおける「View」という概念が、「Widget」と呼ばれるものになる SwiftUIのようにWidgetの中に...