飴屋

開発日記/2020年の日記

2020/11/17

Wordpressのサイトでパーマリンクに細工をすることになって、get_permalink関数を呼んだときに値をフィルタ関数にかけようとした際にちょっと手間取りました。とりあえず記事タイトルをフィルタする感覚でadd_filterしてみます。

add_filter( 'the_permalink', 'filter_method');

意図した動作はしません。なんでもget_permalinkのときは別に post_link にフックをかけないとダメらしいです。

add_filter( 'post_link', 'filter_method');

しかし、これでもフィルタが反応しませんでした。情報を探すと post_type_link にもフックをかければよい、という断片的な情報がみつかりました。なんでいくつもフックが必要なのかわかりませんが、試してみます。

add_filter( 'post_type_link', 'filter_method');

それでも、ウンともスンとも動きません。なんだろう、これ。Wordpressのソースをあたった方がいいのかな、とも思いましたが「post_link」と「post_type_link」と二つを見比べて、不意に思いつきました。postは投稿記事を、post_typeはカスタム投稿タイプ記事を指すのだとしたら・・・pageが固定ページを意味して「page_link」にフックをかけられるのでは?

add_filter( 'page_link', 'filter_method');

ビンゴでした。動作確認に用意したのは固定ページだったので「page_link」にフィルタをフックさせたら、希望の動作をしました。Wordpressの歴史的な背景もあって、投稿と固定ページとカスタム投稿とでフックが分かれているのかなぁと思いつつ、三者共通のフックはないものかと考えなくもなかったり。

2020/11/13

Thunderbirdの自作アドオンの更新が完了しました。(ついさっき)軽快に動いている気がするので、アドオンを支える新しい仕組みが功を奏しているのかもしれません。(気のせいかもしれません。)

今回の改修にあたって、一番躓いたのは「MailExtensionという言葉に踊らされた」のが理由かもしれません。WebExtensionの仕組みをThunderbirdみたいなメーラー向けに仕上げたMailExtensionという仕組みが、さぞや便利にThunderbirdを操作できるようにしてくれているんだろうと思ったのですが、少なくとも現段階で実装されているでは自分の要求はかなわないようでした。ショートカットキーを追加するのに「commands」をmanifest.jsonに書きましたが、WebExtensionの仕様で使えたのはこの辺くらいだったかもしれません。

WebExtensionが実験的に提供している↓これを使って自分の欲望を満たすというのが正解だったようです。
WebExtension Experiments

  1. 書いてある通りに「experiment_apis」をmanifest.jsonに書き加える。
  2. 加えた実験的APIを定義するjsonファイル(schema.json)を用意する。
  3. APIを実装する。
    • getAPIメソッドの返り値がAPIの実装を返すように書く。
  4. 必要なタイミングで自作APIを叩く。

こういう流れを作ります。それで自作APIの中でChromeUtilsを使ってThunderbirdのウィンドウにアクセスできるようになっているというわけです。

var { ExtensionCommon } = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var w = Services.wm.getMostRecentWindow("mail:3pane");

自分が欲しかったものは「mail:3pane」だったのかぁ、と気付くまで時間がかかりましたが、これさえあれば自分の単純なアドオンなんてすぐにできあがりました。実験的なAPIだからまた今後いろいろ変更が入るのかなぁ。

2020/11/8

普段からアンテナを立ててない分野では突然「聞いてないよ~」って事態が発生します。Thunderbirdの更新で突然アドオンがいくつか死んだ、というのが今回のそれでした。ちゃんとアドオンを開発してた人は二年位前から事前に周知されて、対応も済んでいたっぽいですが、自作のアドオンは仕様が古いままだったので、ついにサポートが切られたということのようでした。もう一つよく使っていたアドオンがあったのですが、同時に死んだということは私と同じように古い仕様のままだったのでしょう。

今、あんまり時間をとって対応できないのですが、毎日使うメーラーの便利機能だったので、なきゃないでジワジワ困ってしまい、ちょっと新仕様について調べ始めました。WebExtensions APIをThunderbird向けに拡張した仕組みを使うらしく、とりあえずアイコンの画像とmanifest.jsonというアドオンの定義ファイルとバックグラウンドで動くjsファイルを用意してみました。中身はconsole.logでなにか出力するだけのものです。

それでアドオンのデバッグ機能というのがThunderbirdについているので、デバッグ環境で動作を確認するところまでいきました。ここから旧仕様アドオンが持っていた機能を実装し直すわけですが、あんまり参考にできそうな情報がみつけられなくて、自分で手探りでやっていくことになりそうです。

2020/8/25

ここしばらく新しく作ったAndroidアプリをチョコチョコ直していましたが、やっとひと段落つけそう・・・な気がしてきました。最初に作った習作アプリと違って、音楽再生アプリの場合、コンテンツ制作よりも端末の制御をおこなうプログラム設計に時間がかかったという印象です。

これは偏にモバイル端末が少ないバッテリーをやりくりしなければならないという制約ありきで設計されてるからだと思うのですよね。常に電源が供給されているPCやサーバー端末のプログラムは、電源富豪プログラムだったでした。

今回、chromecastを使った処理があったのですが、chromecastの端末とは常に(5秒に一回くらい)通信しなくてはならないのですが、Activityで実装してもこの子すぐに転生して、別のライフサイクルに入ってしまうのですね。本やWEBサイトで見聞きしてましたが、あんまり自分とは関係なさそうって思っていてすいませんでした。Serviceを用意して、Activityと一緒に転生しないように頑張ったり、WakeLockを使って電源と計算資源を画面オフの時も融通してもらったり、なんかいろいろ大変なんですね。

2020/8/3

最近、暇を見て作っていたAndroidの公開申請がやっと通りました。リジェクトされる度に「ご対応のお願い」というタイトルのメールが届くのですが、読んでも具体的に悪い部分が書いてないので、推測交じりで修正しては再申請するのを繰り返していました。

Google Play にアプリを公開するための手順は以下のとおりです。
1.デベロッパー ポリシー センターのポリシーの範囲ページを確認
2.アプリを修正し、上記の問題に対処したことを確認(該当する場合は、アプリのストアの掲載情報が準拠しているかどうかも確認)
3.アプリが他のすべてのデベロッパー プログラム ポリシーに準拠していることを再度確認
4.Play Console にログインし、アプリのアップデートを送信

メールはこんな感じで「ポリシーの範囲」ページがポイントになっているみたいなのですが、内容が五段落に分けられていて、今回どの部分が問題を指摘している部分なのか悩んでしまいました。

結果的に最後に行った修正はアプリに対してのものではなく、アプリストアの表現に問題があったのではないかと思われます。「ポリシーの範囲」にはストアでの表記も含まれるよ、って書いてあるので、それをくみ取れればもっと早くリリースできたかな。

ちなみに、Chromecastで音楽を再生するようなアプリで、説明文とイラストに「自分はGoogle Home miniに音楽を送っている」という感じを出したのがダメだったのかなと考えています。Google Home miniみたいな商品名の商標に関するポリシーにひっかかるのかな。勘違いを生まないようにという配慮だと思うので「Cast device」みたいに名称を書き換えたら申請が通りました。

スマホの音声入力で音楽の再生をコントロールするアプリです。興味があれば、ぜひ!

2020/8/2

先日のandroidアプリのdebug版にapplicationIdSuffix をくっつけていた問題を深堀することになりました。AndroidManifest.xmlにproviderが登録されている場合、リリース版とデバッグ版を同一端末に入れられない現象が起こったのですが、providerのandroid:authoritiesが両者で競合を起こすのが問題となっているみたいです。

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="net.candychip.soft.provider" />

こんな内容を

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="@string/authorities" />

こんな感じで文字列リソースに変更して、デバッグ版とリリース版はリソース側で管理しようと思ったのですが、これがどうもうまくいかないようで、文字列リソースが展開されていないと推測しました。

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider" />

こんな風に書くとアプリIDを${applicationId}と書き換えてくれるみたいです。gradleでapplicationIdSuffix をデバッグ版につけてくれるので、重複もしないで済みそうです。

FileProviderはコード上でもauthoritiesを記述するのでそっちも対応しました。

2020/7/30

アプリをアップデートしたんだけど、インストールが途中で止まるという事象が発生しました。他の利用者さんはちゃんと更新できているみたいなので、自分の環境依存かなと思いつつ、Google Playの提示する方法でもう一度インストールを試すもダメでした。とりあえずフィードバックを送信して、ダウンロードデータのキャッシュを消して再トライしてもダメなので、

  1. アプリ側の欠陥
  2. インストーラーの欠陥
  3. 自分の端末の欠陥

を疑ってみることに。

そもそも自分の端末はプライベートにも開発機としても使っているので、やっぱりそこに問題があるかなと考えて、最近変更したことを思い返しているとgradleのファイルに

buildTypes {
debug {
applicationIdSuffix ".debug"
}
}

こんな記述を追加してました。デバッグ版のアプリのIDの語末に「.debug」をつけるとリリース版とデバッグ版が同一端末内で共存できるので、便利です。この共存が状態がダメなのかと思ってデバッグ版をアンインストールしてみたところ、あっさりリリース版のアップデートは成功しました。

インストーラーの中身はどうなっているかわかりませんが、デバッグ版とリリース版とでアプリのIDだけちょこっと変えても、アプリのpackage名は同じままなので、その辺がインストーラーにチェックされて弾かれているのではないかと勝手に予想しています。大変な問題にはならなそうでよかった。

2020/7/25

最近、久しぶりに新しくAndroid向けのアプリを作っていて、久しぶりにローンチ準備中です。何年か前に行ったときと微妙にやることが細かく変わっていましたね。コロナ禍の影響でアプリの審査に時間がかかるようになっているのも気がかりです。

今回、AsyncTaskだったりRecyclerViewだったりを多用したので結構新しい知識が増えたのですが、deprecatedなコードがジワジワ増えているのにも同時に気づかされ、専業でアプリを作って知識をアップデートさせていかないと、ドンドン陳腐化していきそうに感じました。

あと、自分はJavaでアプリを組んでいるのですが、ググって出てくる情報がKotlinばっかりというケースが増えてました。やることは基本変わらないので、どっちでもいいのですが、一回腰を据えてKotlinで何か書いてみた方が楽しいかもですね。

でも、ローンチが済んだら一回別のことに力を入れるつもりです。次はC++かな?

2020/5/22

Windowsで開発していると、PuttyでSSH接続したりWinSCPでSFTP接続することが多いのですが、今回三つ踏み台を経ないと接続できないサーバーが現れて悩まされました。

Puttyは複数のサーバー設定をplinkでつなぐだけで多段sshをつなぐのは難しくないのですが(接続 - プロキシ)、WinSCPは接続設定でトンネルの設定を行う箇所が一つしかないので、踏み台をいくつも超えて接続することができません。そんなときは、ポートフォワーディングを使ってトンネルの数を稼いでいたのですが、踏み台が三つになったらうまく設定ができなくなってしまいました。できそうだけど、つながらなくて、原因を特定するのがまた難しくて・・・。

しばらく悩んだ結果、発想を転換しました。Puttyで既に繋げられるようにはなっているので、Puttyの接続をWinSCPにリンクできないかなと思った次第です。結果として、Puttyの設定をWinSCPにインポートできることを知り、あっさりと問題は解決されました。WinSCPは知らないだけで、いろいろできる子でした。ポートフォワーディングも必要ないなら、他の接続設定も書き換えてひと手間減らせそう!

そして、この感動をすぐ忘れそうだから、ここに書き留めておくのでした。

2020/3/17

Chrome 80 から別ドメインのリソースへのCookieの挙動が変わる件でお問い合わせをいただいて、対応しました。この動作変更について入院中にも検討してたのですが、大丈夫そうかと思ってたら、見当はずれな検討でダメでした。

HTTP Cookie は緩い運用で使われていたけど、危ないからChromeがそこに先鞭をつけたのですよね。サードパーティーにCookieは渡さないので、Webが少し安全になるようです。

今はCookieにSecure;SameSite=None をくっつけてこれまで通りの動作も期待できますが、将来的にどうなるんですかね?広告屋さん的にはユーザーを特定して広告を選びたい需要があるけど、プライバシー権の方が強いのか、今後も要チェックですね。

2020/3/6

管理しているサイトでGoogle Mapsを使ったコンテンツを覗いたところ、地図に暗いレイヤーがかけられて、「開発用」的な文言と表示に問題がある旨、メッセージが表示されました?あれ、何だっけ個れってなった話。

そういえばクレジットカードの有効期限が切れたんだよな~、と新しいカード情報を入力したけど、表示は変わりませんでした。反映されるまで時間がかかるやつか?と一日寝かしてみたけどダメでした。とりあえずブラウザのconsoleを読んでみると支払いに問題がある的な内容があって、英語の説明ページへのリンクが張られていました。読んでみたけど、可能性のある問題の原因が列挙されているだけで要領を得ませんでした。

支払いに問題があるってことだけど、更新したカード情報は問題なさそうだし、もしかしたらアカウントがダメなのか?といくつか管理しているgoogleアカウントをチェックしてみたけど、google maps apiの利用登録をしているアカウントは支払い情報がちゃんと設定されてます。しかしふと気が付くと画面の上の方に「google cloud platformのお試し期間が終わりました」的なアラートが出ていました?なんかよくわかんないけど、google maps はgoogle cloud platform の傘下に入っていて、記憶にはないけどそのプラットフォームをお試し期間として利用してたことになっていたようです。昨年の入院中に何かがあったのか、それともgoogle maps api キーを取得したときにそれらの事情が明示されていたのか、わかんないけどお試し利用を本利用に切り替えたら地図は無事表示されるようになりました。各プロジェクトの一日に使える無料枠についてはこれまで通り変わらないようなので、特に支障はないです。

お試し期間に申し込んだ記憶と、お試し期間が切れる旨通知が来た記憶がないことだけが心配です。

開発日記

Last-Modified