もう一人のY君

主にiPhoneのショートカットアプリのレシピやTipsなどを書いています. たまに数学の記事も書きます.

もう一人のY君 MENU  MENU

【iPhoneショートカット】設定やモードをカスタム切り替えする仕組みを作る

 

 よくあるソフトウェアでも、普段ユーザーが触らない設定が内部に組み込まれていることがあります、管理モードとかメンテナンスモードとか、そんな立場の設定やパラメータです.

 仮にユーザーが触るとしても、大抵はそのまま使い続けるケースもあるでしょう.

 そういった設定やパラメータは、当然「数字」アクションや「テキスト」アクションなんかに書いておく、あるいはメモやファイルアプリを使って読み書きする、Data Jarのようなショートカット補助アプリを使う…などなど色んな選択肢があります.

 しかしそれだと元に戻す際戻すべき値が分からなくなる恐れがあったり、そもそもアプリ(レシピ)ひとつでの管理から外れてしまいます.

 

 これらをどうするのか…はそういった使い方を要求される上で常につきまとう問題です.

 仮にそういった目的でなくとも、レシピを組む一助となるかも知れない手段として参考にしてください.

 

 

blog.thetheorier.com

 今回のアイデアを随所に採用したのがこのBattery Checkerになります.

 

 

ショートカット

ショートカット

  • Apple
  • 仕事効率化
  • 無料

※価格は記事執筆時のものです. 現在の価格はApp Storeから確認ください.

 レビュー時のiOSバージョン : iOS26.3

 

 

スポンサーリンク

 


 

 

基礎

 まずは基本形からです.

 今回のアイデアでは「辞書」アクションの利用が基本となります.

 今回は"flag"というキーを多用します、なお値は「ブール値」を使います.

 今後はこの値の真偽を切り替えるだけ…というのが目的です.

 「切り替え」や「設定」という目的を考えるとより自由にできるテキストや数の方が望ましいですが、それだと例外処理を配慮しなければならないデメリットがあります.

 なのでまず2タップで確実に2通りの選択肢を定めることのできるブール値を使います.

 

 キー"flag"の値を「辞書の値を取得」アクションで取り出しておきます.

 

 

 ここで厄介なことは、上の「辞書の値を取得」で得たものは、ブール値と思いたいのですが日本語設定だとテキストの「はい」「いいえ」を返してきます.

 なのでここからif文で場合分けしても本来の意味での真偽ではありません.

 ショートカットアプリの特徴のひとつは「変数型を比較的無視できること」ですが、if文の条件のように変数型に(本来の意味で)厳しい場合があります.

 正しく処理すれば画像①のようにif文の望む側の出力が帰ってきますが、if文の条件の属性を正しいものにしておく必要があります.

 

 

 if文の条件に入れた時点では画像のように「ファイルサイズ」になっている場合があるので、これをタップして「種類」を「ブール値」にすることで先の画像のようにブール値として場合分けができるようになります.

 

 今回は切り替えを行う組がひとつですが、当然同じ「辞書」アクションに2つ3つ…と一緒にまとめて活用すれば、レシピのカスタム設定として必要な際にまとめて弄ることが可能になります.

 

 

1:複合データの値を取り出す

 上記の基礎をもとに、色んなことを試行していきます.

 まずはシンプルに、それぞれで決めた同種のデータから値を取り出します.

 先ほどはブール値に応じたテキストアクションそのものを取り出しましたが、場合によっては扱うデータはひとつとは限りません.

 まずは基礎同様、「辞書」アクションを追加し、切り替えに使うキーと値(ブール値)を作っておき、その値も取得しておきます.

 

 

 今回はブール値に応じて単純なテキストを充てがうのでなく、データとしてjsonを入れてみます.

 jsonとは主にJavaScriptで使われるデータ変換フォーマットで、画像のようにテキストベースで簡単に記述できるメリットがあります.

 そしてショートカットでも扱うことができます.

 

 

 ちなみにこの画像上の「辞書」とその下2のアクションの組はほぼ同じ結果を出力するため概ね同じと解釈できます.
 jsonの構文ルールはここで詳しく説明するのは省きますが、最低限、:(コロン)で区切られた左側が「キー」、右側が「値」で組の関係になっています.
 キーと値は原則として"(ダブルクォーテーション)で挟む必要がありますが、値が数あるいはブール値などの場合はその限りではありません.

 その他配列や入れ子など複雑なデータにすることも可能ですが、今回はシンプルにキーと値だけのデータのみ考えます.

 

 改行とインデントを入れるのは見やすくするためなので必須ではありませんが、一行でズラッと書くとデータが多くなった際分かりづらくなります.

 

 

 話を先のレシピに戻します.

 if文の結果を「入力から辞書を取得」で辞書にします.

 これで対象のブール値が真の場合はif文の条件に合う方のjsonテキストが、偽の場合なら条件に合わない方のjsonテキストが採用されることになるので、今後は最初の辞書にあるflagの値を変えるだけでデータ全体を切り替えることが可能になります.

 最後に「辞書の値を取得」で好きなキーを指定して結果が正しいか確認します.

 

 

2:複合データの値を取り出して計算する

 実際に活用する際は、単純に取り出して表示させることもあるでしょうが更に計算させたり共有させる場合もあります.

 とりあえず切り替え用のjsonを辞書化するまでは先程のレシピを同じように組みます.

 

 

 「辞書の値を取得」で好きなキーを指定し、その値を使って「計算」や「計算機」アクションで適当に計算して確かめます.

 今回用意したjsonの各キーの値はダブルクォーテーションの付いていない数字なので属性も数ですが、「計算」や「計算式」アクションで使う場合はダブルクォーテーションをつけた値であっても問題ありません.

 

 

活用例:一方の場合だけ計算

 先程は、ブール値がどちらであろうと各々のjsonから値を取り出して計算しましたが、目的によっては一方の場合だけ別の処理をさせたい場合もありえます.

 その場合は例えば画像のように場合分けの中で一方はそのままの結果を、他方では計算などの処理をさせればいいです.

 今回の画像の場合は最初の「入力を要求」で摂氏温度を入力することを想定し、ブール値が真ならばそのまま摂氏を、偽ならば華氏の値を計算させています.

 

 

 頻繁に切り替える(選択する)場合にこういった方法は向かないですが、たまに変える程度であったり仮に配布する相手によって他方が望ましい場合にこの方法は重宝するわけです.

 

3:「メニューから選択」の項目に使う

 基本的に、この手法はマジック変数として使える場所であればどこでも使えます.

 なので次は「メニュー」アクションの項目の欄で利用してみます.
 同じくブール値でjsonデータを場合分けするのですが、今回はメニューの項目用のキーと値の組を追加しておきます.

 それぞれitem1、item2の名をキーとし、値は真の場合は日本語、偽の場合は英語にでもします.

 

 

 取得した辞書から項目のために用意したキーitem1とitem2の値を「辞書の値を取得」アクションで取得し、「メニューから選択」アクションの項目の部分に配置します.

 今回はメニュー表示の見た目だけ確認するのでこれ以上追加しません.

 ただこのままだと項目がどちらも「辞書の値」になってしまうので、区別したい場合は各々のマジック変数をタップし、名前を変更してわかりやすくしましょう.

 

 

 これで、最初の辞書にあるflagの真偽に応じてメニューの項目が変わるようになります.

 2通りとはいえ言語設定に使えることになります.

 

 

4:「リストから選択」に使う

 「メニューから選択」に似たものとして、「リスト」と「リストから選択」を組み合わせる方法があるのでその場合も考えてみます.

 まずは相変わらず切り替え用のjsonデータを辞書化するまで作ります.

 

 

 更に同じく項目用の値を取り出すのですが、今回はこれを「メニューから選択」アクションの項目でなく「リスト」アクションに直起きします.

 項目が多い場合は「項目を繰り返す」などを使うことになるかもしれません.

 こうして得たリストに対して「リストから選択」でひとつ選ばせます.

 

 こうして得た項目に対して処理させればいいのですが、「メニューから選択」アクションと違って「リストから選択」アクションそのものに分岐フォーマットがないため、if文を使って個別に処理させる必要があります.

 加えて最初のflagの値次第では項目の文字列が違います、なので単純にif文で場合分けして処理するわけにはいきません.

 最近のiOSバージョンではif文の条件を複数にできるようになりましたからそれを使っても良いのですが、ここではその前のバージョンを使っている場合も想定して他の手段を使います.

 

 

 まずは「リストから選択」で得た項目を指定します.

 「一致するテキスト」アクションを使い、正規表現を使って例えば

 

(項目1|item1)

 

と書きます.

 正規表現で括弧はグループ化、そして|はorに相当します、なのでこの場合「項目1」と「item1」のどちらかが一致した場合にマッチする…と言えます.

 これに対してif文を適用します、マッチさせた結果が存在する(=任意の値)なら然るべき処理をさせます.

 今回は適当なテキストを出力させることにします、「メニューから選択」とは異なりif文は入れ子にせず独立させるとその場で出力して終わるため、共通な出力としたい場合は同じ名前の変数に置いておく必要があります.

 

 

 同じ処理をすべての項目に対して行います.

 最後に確認のために「コンテンツを表示」を追加します.

 

 

 これでリストの場合でも「メニューから選択」と同じようなことができることが分かりました.

 

5:Vcardメニューで使う

 次はリストを使ったメニュー寄りで、レシピを紹介・配布する上級制作者の間では標準装備と言えるハックでり、それゆえ難易度がちょと高めのVcardメニューです.

 

 

 うまく使うことで画像のような区切りのよいアイコン付きのメニューを作ることができます.

 

blog.thetheorier.com

 

blog.thetheorier.com

 一度作っておけば楽ですが、この2記事を参考にしてください.

 

 

 まずは先ほどと同じように辞書化し、辞書の値を取り出すまでを組みます.

 せっかくなので項目に使う文字列は先程より少し長めに、複雑にしておくことで正規表現の工夫も想定しておきます.

 

 

 次にVcardのコード本体を「テキスト」アクションに書いていきます.
 先程紹介したShortcut Menu Builderを使って作成し、その結果を貼り付ければ十分なのでVcardそのものの説明はここでは行いません.

 画像のようにNと書かれている項のオブジェクトにメニューとなる項目をマジック変数として充てがうので、Shortcut Menu Builderでは適当な文字列を入れ、「テキスト」アクションに貼ってから置き換えましょう.

 このVcardテキストを「名前を設定」で適当にa.vcfとでもしておき、これに対して「入力から連絡先を取得」で連絡先に変換、これに対して「リストから選択」でひとつ選ばせます.

 

 

 「リストから選択」で得たので、先程同様if文と正規表現で場合分けします.

 ただ、今回の場合if文の条件に「リストから選択」の結果を代入すると、普段通り「選択した項目」となるでしょう.

 このままだとVcardである連絡先から「リストから選択」で得た結果はメニューに使うべきオブジェクトNの部分と異なる箇所を参照してしまいます.

 なのでこの「選択した項目」をタップし、「種類」を「連絡先」に変更し、その下の欄にある「名前」にチェックを入れます.

 更に今回は前回と異なり項目の文章を多少複雑にしました、場合によってはもっと長かったり絵文字が入ったりしてややこしいでしょう.

 なので各項目全体をorでマッチさせるのではなく、被らない範囲で一部だけチェックさせます.

 今回の場合「設定」と「settings」だけで十分区別できるため、「一致するテキスト」アクションを使うのは前回と同様ですが、代わりに

 

.*(設定|settings).*

 

でマッチさせます.

 .(ドット)は任意の一文字にマッチ、*(アスタリスク)は直前の文字(またはグループ)の0回以上の繰り返しです、なので例えば.*a.*なら「aをどこかに含む文字列」と解釈できます.

 if文の中身は今回は適当です.

 

 

 他の項目が選択された場合も同じように組んでいき、最後に確認しておきます.

 

 中長期で使うレシピなら、折角なので採用してみるといいです.

 

6:リッチテキストに反映する

 これまでは切り替えた値を計算やメニューの項目に活用しましたが、今度は結果の出力に使ってみます.

 単に「コンテンツを表示」に使ってもいいですが、折角なのでリッチテキストで採用します.

 まずは切り替え用のフラグを含んだ「辞書」アクションを用意し、その値も取得しておきます.

 

 

 切り替え用のブール値に応じて要素を変更する項目を含むjsonを作り、if文の結果を「辞書」に変換するまでは前回と同じですが、扱いやすいよう今回はそれをcontentsと名付けた変数に置いておきます.

 

 「テキスト」アクションを追加し、今回はhtmlでリッチテキストを作成します.

 今回は実験的に作成しているためhtmlの中身は必要最低限です(流石にデフォルトだとフォントサイズが小さいのでそれだけは指定しています).

 本文に、2つのキーと各々の値を書き並べるだけのシンプルな内容です.

 ここで注意したいのは、例えばitem1の左にわざと"_"と付けている点です.

 単純に該当する場所に項目や値を配置するだけなら直接マジック変数や変数を使えばいいですが、今回のように条件によって結果が異なる場合はそうはいきません.

 加えて、項目数が少なければあらかじめ確定させておいて配置すればいいですが、そうでない場合はアクション数がどんどん増えていきます.

 そのためあとでまとめて置換する方法を取るのですが、そのままだと置換する必要のない場所まで変わってしまう恐れがあります、なので該当箇所の先頭または末尾に(適当に決めた)特殊文字をわざと付けておき、それを含む箇所だけ置換できるようにします.

 

 まずはその置換がうまく行っているかを確かめるため、置換を行ってない状態でリッチテキストにして確認してみます.

 「HTMLからリッチテキストを作成」アクションでリッチテキストにし、「Web表示を表示」アクションでそれを表示させます.

 この後変換を踏まえた処理を続けますが、実際に使用する場合は上の最後にある「HTMLからリッチテキストを作成」と「Web表示を表示」は確認用なので取り除きましょう.

 

 

 レシピの作成を続けます.

 先程の辞書Contentsに対して「辞書の値を取得」アクションですべてのキーを取得し、それに対して「各項目を繰り返す」アクションを使います.

 「各項目を繰り返す」の中でcontentsにあるキー(繰り返し項目)の値を取り出し、「テキストを置き換え」で先程のhtmlにある"_"から始まる文字列と置き換えます.

 その結果を変数htmlで上書きすればOKです、これで変換項目が増えてもアクション数の負担はこの5アクション(実際の処理数はともかく)で済みます.

 

 こうして置換を終えたhtmlを「HTMLからリッチテキストを作成」でリッチテキストにし、「Web表示を表示」で表示します.

 

 

 まず置換前の結果です.

 "_"が付いたままですね.

 

 

 次へ進むとちゃんと置換されました.

 最初のflagを切り替えて再実行すれば他方のjsonに従って置換されることになります.

 

 

7:切り替え数を増やす場合

 これまでは切り替えにブール値を用いたため、2通りまでしか切り替えられませんでした.

 可能なら3通り4通り…とできるとより有益であり、不可能ではないですがデメリットも出てきます.

 最後にここではそんな例を紹介します.

 

 

 「辞書」アクションを追加するのはこれまでと同じですが、今回はこのアクションひとつで切り替えのオプションひとつ分…として扱います.

 目的に応じてキーと値を追加していき、適当にdatabaseとでも名付けます.

 

 

 辞書databaseのすべてのキーを「辞書の値を取得」アクションで取り出し、「リストから項目を取得」で最初の項目を取り出します.

 これで、くだんの辞書にある各データを動かして一番上にしたものがその切り替え値として機能します.

 このキーの値も「辞書の値を取得」で取り出しておきます.

 

 

 あとは目的に応じて他の処理をしたり、単に表示したりさせます.

 

 これで切り替えの選択肢が3つ以上であっても通用します.

 

 

デメリットと改善案

 これには当然デメリットが存在します.

 

 

他との共存ができない

 この方法では「辞書」アクションそのものをひとつの切り替えに使っているため、他の切り替え項目がある場合とは別に作ることは避けられません.

 

 

「すべてのキー」の順番

 「辞書の値を取得」ですべてのキーを取得する際、その順番が記述通りになる保障はありません.

 多くの実装では順序を保持することは多いですが、jsonそのものに順序の概念がないからです.

 今のところ「テキスト」アクションに書いたjsonや外部から読み込んだjsonは、順序が乱れることを確認しています.

 現状「辞書」アクションの場合は順序を保持していますが、今後のiOSアップデートでそれが崩れる可能性はゼロではありません.

 

 なのでキーの文字列の先頭に敢えて番号をつけ、すべてのキーを取り出してから「ファイルにフィルタを適用」アクションを使って昇順に並べ替え、その上で「リストから項目を取得」で最初の項目を取り出せば確実に「辞書」アクションの先頭の項目を取り出せます.

 アクション数が増えて面倒になるのがネックですね.

 ただ使っていくうちに順番が滅茶苦茶になることを考えると、番号付けしておくことはメリットでもあります.

 この話はいずれきちんと記事にする予定です.

 

 

他とのメリット・デメリット

 そもそもやりようによってはブール値以外にも数字やテキストを使う選択肢もあります.

 しかしこれらにもメリットとデメリットがあります.

 

 

ブール値を使うメリット・デメリット

 メリット

  • UIが2択固定のため入力ミスがほぼなく、例外処理も不要
  • オンオフしかないため可読性が高い
  • 条件分岐と相性がよく(if文ひとつでOK)、設計が単純となり保守に強い

 デメリット

  • 3択以上の内容に使えない

 

数値を使うメリット・デメリット

 メリット

  • ブール値より選択肢が多い(0,1,2,…)
  • テキストより誤入力のリスクが低い
  • 切り替え項目そのもので演算が可能

 デメリット

  • 数値自体に意味はない(1が何か、2が何か…がわからない)
  • その説明や対応表が必要
  • 仕様変更の際再設計が必要になる恐れ

 

テキストを使うメリット・デメリット

 メリット

  • 意味が明確で、他と比べて可読性が圧倒的に高い
  • 拡張や追加が容易
  • デバッグ時に理解しやすい
  • jsonや外部連携と親和性が高い
  • enumとして使える

 デメリット

  • 誤入力リスクが圧倒的に高い
  • 大文字小文字の揺れ、スペルミス、例外処理対策が必要

 

 

 一度慣れておけば、他のアプリを介さずある程度パラメータをレシピ自身に組み込める便利なアイデアです.