【サクメモ】進捗状況Ver0.01:コンセプト決め

どうも、ねこきち(@nekokichi1_yos2)です。

 

iOSエンジニアになるべく、2度目の転職活動中です。

 

個人開発で作ったアプリをリリースする予定ですが、アピールポイントを増やそうと、リリースノートの投稿も始めます。

 

リリースノートの内容は、個人開発に関して考えたことや実行したこと、です。

 

期間は、転職活動を終えるまで、を考えています。

(アプリに愛着が湧けば、続くかも)

 

本日は、個人開発の構想、についてです。

 

Scrapboxで書き出したものをコピペしただけなので、内容や可読性については、ご了承ください。

 

アプリ名

サクメモ
 

コンセプト

サクッとメモを作れて、サクッとメモを見れる
 

メイン機能

メモをウィジェットで管理
 

差別化ポイント

  • 綺麗なUIデザイン
  • 文章のカスタマイズ
    • 見出し
    • フォント
    • 文字色
    • 引用
  • デザインテンプレート
    • 古書風
    • 近未来風
    • 文庫風
    • 書道風
  • ウィジェットの表示デザイン
    • そのまま
    • リスト
    • チェックリスト
  • フォーカスモード
    • 書くことに集中
  • 自然消滅
    • 設定した期間が過ぎると、自動的にメモを削除
 

誰が使う

  • アプリを開かずにメモを確認したい人
  • 直近で達成したい目標を常に確認したい人
  • 今取り組んでいることだけに集中したい
 

制作の動機

  • メモを開く過程を減らしたい
    • メモを読むために、アプリを開いて、目的のメモを選択するのは手間
    • 何度も読むメモなら、ウィジェットで表示しておけばいい文字装飾できず、読みづらい
  • 文字の装飾ができない
    • 太文字、背景色の変更、しかできない
  • 目立つように配置したい
  • メモが溜まっていくのが気になってしまう
    • 使えば使うほど、メモが溜まり、タイトルを見ると読みたくなる
    • 常に新しいことを得て、何かに取り組む以上、古いメモは要らない
    • 過去を気にせず、目の前のことに集中したい
  • 継続したい習慣を何度も見て、達成率を上げたい
    • 習慣を毎日目にすれば、習慣の存在を忘れない
    • 習慣を促すのではなく、習慣を無意識に定着したい
  • 美麗なUIにした類似アプリを作ってみたい
    • 類似アプリをAppStoreで探すと、簡素なデザインばかり
    • 趣味ではなく、本格的なメモアプリとしての存在感を出したい

【XCTest】No target application path~のエラーについて

 どうも、ねこきち(@nekokichi1_yos2)です。

 

今回は、No target application path specified via test configuration、のエラーでつまずいたので、備忘録を残します。

 

発生タイミング

 

XCTestで特定のテストを実行したら発生した。

 

⌘Uだと正常に実行したけど(ただし、テスト結果がprint()などが機能しない)、XCTFail()だけの関数でも発生してしまう。

 

XCUITestでは問題なかった。

 

解決方法 

Podfileでテスト用TARGETの記述を追加

Podfileにて、下記を記述して、Pod installやPod Updateを繰り返したら、解決した

f:id:nekokichi_yos2:20210131214112p:plain


"inherit! :search_paths"を調べると

  • inherit : 継承
  • search_paths : 親の検索パス

の意味になるみたい。

 

つまり、

  • 親が持つCocoaPodの検索パスがなかった
  • 親と同じ検索パス、CocoaPodsの設定がなかった

からエラーが起こったと解釈。

 

確かに、エラー文では、BundleやPathがnullだ的なことが書かれていたし、親のモジュール(アプリ)を実行するから親の環境と同じでないといけない気はする。

 

GitHubDesktopで差分を確認すると、テスト用TARGETのinfo.plistにCFBundle~の設定値が追加されていた。

f:id:nekokichi_yos2:20210131222209p:plain

 

とにかく、XCTest + CocoaPod、を利用するなら、Podfileの記述はいじらない方がいい。

 

新規のXCTestファイル、TARGETを追加

 

当たり前だけど、既存のファイルとTARGETを削除し、新規のそれらを追加したら、上手く行った。

 

参考

qiita.com

stackoverflow.com

guides.cocoapods.org

【Swift】ローカル通知が受信されたかを知る方法

どうも、ねこきち(@nekokichi1_yos2)です。

 

今回は、ローカル通知の受信を検知する方法を載せます。

 

ローカル通知のデリゲートメソッドについて

 

ローカル通知には、

  • willPresent()
  • didReceive()

のデリゲートメソッドしかありません。

 

しかも、上記の2つはそれぞれ、

  • フォアグラウンドで通知を受け取った時
  • 通知をタップした時

でしか実行されません。

 

もし、ユーザーがアプリをタップした場合、デリゲートメソッドに引っかからず、アプリを起動した時、通知が受信された時に実行したい処理がスルーされてしまいます。

(プッシュ通知なら、受信時の処理を実行できるだろうが、今回は却下。)

 

そこで登場するのが、getDeliverdNotification()、です

 

getDeliverdNotification()を使う

 

ドキュメントでは、NotificationCenterに登録された通知の一覧を返すメソッド、だそうです。

 

書き方は、以下の通り。

UNUserNotificationCenter.current().getDeliveredNotifications { (notification) in
}

 

クロージャの引数をprint()で出力すると、受信された通知の詳細が出ます。

f:id:nekokichi_yos2:20201231213249p:plain

 

また、取得する値は、UNNotification型の配列です。

f:id:nekokichi_yos2:20201231213438p:plain

 

例えば、配列のプロパティであるisEmptyを利用すれば、

  • true:受信されてない
  • false:受信された

により、通知が受信された時の処理を実装できます。

UNUserNotificationCenter.current().getDeliveredNotifications { (notification) in
    if notification.isEmpty {
        // 受信してない
    } else {
        // 受信した
    }
}

 

結果、ローカル通知のデリゲートメソッドでは拾えなかった、

のユーザーアクションにも対応できます。

 

getDeliverdNotification()でできること

 

まとめると、

  • ローカル通知の詳細を取得できる
  • ローカル通知が受信されたかがわかる
  • sceneDidBecomeActive()と併用すれば、アプリの直接起動でも、受信状態の分岐ができる

 

ソースコード

  

import UIKit

class UNUserNotificationTest: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let content = UNMutableNotificationContent()
        content.title = "通知"
        content.body = "受信しました"
        content.sound = .default
        // 5秒後に通知
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
        let request = UNNotificationRequest(identifier: "notification", content: content, trigger: trigger)
        let center = UNUserNotificationCenter.current()
        center.add(request) { (error) in
            if let error = error {
                print(error)
            }
        }
    }

}


import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        //ローカル通知
        UNUserNotificationCenter.current().requestAuthorization(
            options: [.alert, .sound, .badge]){
            (granted, _) in
            if granted{
                UNUserNotificationCenter.current().delegate = self
            }
        }
        return true
    }

}



import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else { return }
    }

    // バックグラウンド -> フォアグラウンド、で実行
    func sceneDidBecomeActive(_ scene: UIScene) {
        UNUserNotificationCenter.current().getDeliveredNotifications { (notification) in
            if notification.isEmpty {
                // 受信してない
            } else {
                // 受信した
                print("受信しました")
            }
        }
    }

}

【Swift】RealmStudioでRealm内のデータを閲覧する方法

どうも、ねこきち(@nekokichi1_yos2)です。

 

Realmには、RealmDatabaseを覗けるツール、RealmStudioが用意されています。

 

普通はDatabaseを実装する場合、データが正常に保存されてるかを確認する必要があり、ビルドしてデータを取得/出力などをします。

 

ですが、確認のためにビルドするのは面倒です。

 

また、printでデータを出力しても、コンソールではデータの中身は表示できても、どのような階層で保存されてるかがわかりません。

 

そこで今回は、Realmに保存したデータをRealmStudioで閲覧/操作する方法を載せます。

 

解説

 

 RealmStudioをインストール

 

まず、下記サイトよりRealmStudioをダウンロードします。

 

realm.io

 

.dmgの拡張子でダウンロードされますので、ダブルクリックで開きます。

 

f:id:nekokichi_yos2:20200920212519p:plain

 

Applicationsフォルダに移動させます。

 

f:id:nekokichi_yos2:20200920212609p:plain

 

RealmStudioを開いたら、下記の画面になります。

(初回起動時、メールアドレスの入力を求められます。)

 

f:id:nekokichi_yos2:20200920212433p:plain

 

 ここまで出来たら、一旦、RealmStudioは置いておきます。

(RealmCloudにログインする必要はありません。)

 

バイス内データのディレクトリを取得

 

RealmStudioでRealm内のデータを参照するには、データの保存ディレクトリを取得しなくてはなりません。

 

方法は、下記のコードを実行するだけです。

print(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true))

 

すると、コンソールにデータの保存ディレクトリ(今回はドキュメントのディレクトリです)が出力されます。

["/Users/パソコンのユーザー名/Library/Developer/CoreSimulator/Devices/A5B96368-B46F-452F-B02F-CCF8A8E333F0/data/Containers/Data/Application/0212ABB6-47ED-461D-803F-B5524D54E20D/Documents"]

 

Finderでディレクトリ先を開く

 

Finderのツールバーから、"フォルダへ移動する"、を選択します。

f:id:nekokichi_yos2:20200920214405p:plain

 

入力欄にXcodeで取得したディレクトリをコピペします。

f:id:nekokichi_yos2:20200920214453p:plain

 

コピペしたディレクトリに移動したら、default.realm、を開きます。

f:id:nekokichi_yos2:20200920214544p:plain

 

これで、Realm内のデータが閲覧できます。

f:id:nekokichi_yos2:20200920215010p:plain

 

 

 

後は、

  • RealmStudioでデータを変更(追加、編集、削除)する
  • アプリ側でRealmとデータのやりとりができてるかを確認

するなどして、Realmが正常に動作してるかを確認できます。

 

ソースコード

 

print(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true))
  • NSSearchPathForDirectoriesInDomains:指定されたディレクトリパスを返す
  • .documentDirectory:ドキュメントのディレクトリを指定

 

参考

 

qiita.com