Google Workspace で no-reply アカウントを作る
Google Workspaceで no-reply@domain.jp など送信専用の設定をする。
https://admin.google.com/ から管理コンソールに入り、ドロワメニューから 「アプリ」 -> 「Google Workspace」-> 「Gmail」を選択。
「ルーティング」をクリックしルーティング画面に移動したら、その中の項目の「ルーティング」にある「設定」または「別のルール追加」を選択。
ルーティング設定の名前を入力(例: 送信専用アドレス)
影響を受けるメールでは「受信」を選択
「上記の種類のメッセージに対し、次の処理を行う」で「メールを拒否」を選択
拒否用通知にメールが送信できないことを伝えるメッセージなどを入力(例: このメールアドレスは送信専用です。)
オプションを表示する
「影響を受けるアカウントの種類」で「ユーザー」を選択
送信専用にしたいメールアドレスを入力
保存
react-native-soundでダッキングしたい(iOS)
オーディオセッションを共有して同時に音を出した状態にするとき、ダッキングと言って片方の音を小さくして片方を目立たせることができる。
iOSネイティブ開発では AVAudioSessionCategoryOptionDuckOthers を指定すればこれが実現できるが、react-native-sound では対応していなかったのでパッチを当てた。
RNSound.m
withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionAllowBluetooth
ここを
withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers
こうする。
ちなみに変更前の AVAudioSessionCategoryOptionAllowBluetooth はダッキングしなくても消さないとエラーコード 560557684 の cannotInterruptOthers エラーが出たので消す必要あるかも。
Objective-cメモ
@react-native-firebase/auth: "16.0.0"のobjcのコードを読まなきゃいけない機会があったのでそれを元にobjcの文法をメモる。
変数の前につく * ってなに
NSDictionary *authCredentialDict = nil;
ポインタであることを表す。
NSDictionaryはobjcのオブジェクト型であり(C由来のプリミティブ型ではない)、オブジェクトはポインタとして扱う必要があるので変数名の前に * をつけている。
メソッド定義
- (NSDictionary *)firebaseUserToDict:(FIRUser *)user { ... }
これは NSDictionary型の の戻り値があり、FIRUser型の引数 user をとる firebaseUserToDict というメソッドを定義している。
2つ目の引数から定義の方法がちょっと違う
- (void)promiseWithUser:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject user:(FIRUser *)user {
第二引数以降は「ラベル」をつける(任意だけど基本つける)。
ラベル:(型):引数名
となる。
呼び出し元からはラベルを指定して引数を渡すことができる。
メソッドの呼び出し
[self promiseWithUser:resolve rejecter:reject user:userAfterUpdate];
[クラス or インスタンス名 メソッド名:第一引数 (ラベル):引数];
return @{} の@ってなに
// firebaseUserToDict return @{ ... };
objcのオブジェクトを表す。
objcにはC言語由来のプリミティブ型とobjcで使用できるオブジェクト型が存在する。オブジェクト型を使用するには値の先頭に @ をつけないといけない。
@{}内のデータで、@がついているフィールドとついてないフィールドがあるが、なに
// firebaseUserToDict return @{ ... keyEmail : user.email ? (id)user.email : [NSNull null], @"emailVerified" : @(user.emailVerified), ... }
キーは既にNSStringで定義されているもの。値はオブジェクトにしなければいけないため。
キーで keyEmail と @"emailVerified" がある。keyEmailは既に static NSString *const keyEmail = @"email"; と定数化されているものを使用している。
値に関してはまず user.email はNSString であり、それをそのまま使用している。
user.emailVerifiedは BOOL なのだが、NSDictionary はプリミティブを値に持てない。なのでこれをオブジェクトにする必要がある。この場合はNSNumberに解釈される。(BOOLはYESなら1, NOなら0を返す)
(id)user.email の (id) は型キャスト。
JS Bundleの中身を見たい
ReactNativeアプリを実行する時、JSコードは Metoro によって JS Bundle という1つのファイルにバンドルされる。
そのバンドルの中身はローカルでMetoroが起動している状態の時に
http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false
で確認することができる。
ファイルはデバイスのメモリに置かれているので、プロジェクトファイルに作成されることはない。
JS あるキーが重複したオブジェクトを取り除く
const a = [ { name: 'Risa', age: 22, }, { name: 'Ryu', age: 20, }, { name: 'Risa', age: 22, }, ];
このような配列がある。要素のオブジェクトの name の値が重複しているオブジェクトを1つ取り除きたい。
const mapped = new Map(a.map((_a) => [_a.name, _a]));
Mapインスタンスを作成。a.map((_a) => [_a.name, _a])
で name をキー、_aそのものを値として作成。
この時点で重複が取り除かれる。
// 作成されたMapインスタンス {'Risa' => {…}, 'Ryu' => {…}}
次にこのインスタンスからイテレーターオブジェクトを作成する。要素が列挙される。
Map.prototype.values() - JavaScript | MDN
const iterator = mapped.values();
Array.fromでイテラブルなオブジェクトを配列に変更する。
Array.from() - JavaScript | MDN
const newArray = Array.from(iterator) // [{name: 'Risa', age: 22}, {name: 'Ryu', age: 20}]