これからは RSS の時代かと思って iOS / macOS で動く RSS リーダーを作った

タイトルは嘘で、これからは RSS の時代とはとくに思っていないのですが RSS リーダーは作りました。まだリリースしたばかりで不具合がありそうですが、まったく使えないということもないはずなのでよかったら使ってみてください。

ソースコードはパブリックにしています。

github.com

なぜ作ったか

気に入っているブログやニュースレターをもれなく読みたいと思って FeedlyRSS リーダーとして使っていたのですが、 Pull to Refresh の触り心地がネイティブっぽくないとか、アイコンの色がちょっときつすぎるとかめちゃくちゃどうでもいいことが気になって徐々にアプリを使わなくなってしまいました。当然ですがこれは Feedly がだめだということではなくて(むしろ細かいところまでよくできていると感じる)、人それぞれ好みがあるし、毎日使うようなアプリでは好みでない点が気になってくることもあるという話です。

Feedly 以外にも RSS リーダーを探してみたのですがいまいちしっくりくるものがなくて、自分で作れば自動的にお気に入りアプリになるので作ってみようと思いました。

どういうアプリか

かなりふつうの RSS リーダーになりました。 iOS アプリの UI はできるだけ Apple 標準のものに寄せたのですが、 macOS アプリについては勘所がなくて雰囲気で自分が使いやすいように作りました。 一部だけでも Feedly や Reeder よりも優れた点を作りたくて、 Background task を使って裏でフィードを取得して新しいエントリを push 通知で知らせたり、 Widget サポートを充実させたりしています。

iCloud 同期

RSS リーダーは複数端末で既読状況を同期しつつ使える必要がありますが、のちのち面倒になるので絶対に個人開発のアプリでサーバーを管理したくないという思いがあります。 iOS / macOS では Core Data の iCloud 同期機能を使えば無料で複数端末同期を使えて最高なので、 iCloud 同期を使うことにしました。

しかし、サーバを介して同期するのと比べると iCloud 同期特有の使い勝手の悪さもありました。

まずは、アプリから同期を実行するという API がないのでデータの流れをコントロールしづらくて、表示されるデータが古くなってしまうことがあるという点です。例えば Core Data / SwiftData の iCloud 同期を実行して完了してからなにかする - maiyama4's blog のような工夫もしているのですが、いまいちうまく動かないこともあります。そのいまいち動かないときも、なぜうまく動かないかよくわからないことが多くて、ログ出力を多めにして Unified Logging の出力をアプリから見られるようにする - maiyama4's blog の仕組みで追ったりしていました。この辺は、知見を溜めて改善していきたいです。

また、購読しているフィードが多い場合に、フィードの更新を知るためにすべてのフィードを取得しないといけないという問題もあります。サーバがあれば、サーバ側でよしなにデータを更新しておいてアプリからは API を1個たたけば更新がまとめてどかっと降ってくるようにできるのですが、サーバがないとアプリから大量のリクエストを送るのでパフォーマンスが悪くなりやすいです。今は、パフォーマンスが悪いことは諦めて、データのリフレッシュ時にどのくらいフィードのリフレッシュが進んでいるのかをわかりやすく表示することで対処(?)しています。ふつうのリフレッシュインジケータだけだと一生くるくるしているだけで不安になるので...。

macOS アプリと SwiftUI

いつも iOS アプリを作っているので macOS アプリのことはよくわかっていないのですが、パソコン大好き人間としては RSS リーダーはさすがにパソコンからも使いたいので macOS 版も作ってみることにしました。

最初は、 iOS アプリも macOS アプリも SwiftUI で作れるわけだから UI のコードはほとんど共通化できるのではと思っていたのですが、その点はあまりうまくいかなかったです。iOS アプリと macOS アプリではナビゲーションの構造も違えば、どの要素をどこに配置したいかも違うので、多くの画面ではそれぞれの OS 専用の画面を作ることになりました。共通化できたのは、 UI の部品や末端のそれほど UI にこだわらなくていい画面のみでした。とはいえ、一部だけでも共通化できることに利点は感じることはできました。

個人的には SwiftUI のマルチプラットフォーム開発は write once, run anywhere よりは learn once, write anywhere なのかなという所感を得ましたが、これは単に自分の SwiftUI の練度が低いだけで、本当はもっとうまく UI の共通化ができるのかもしれません。いずれにしても、令和時代に AppKit をまともに勉強するのはかなり難しいと思うので SwiftUI で macOS アプリを書けるのはかなりよさそうで、 iOS よりも macOS を使っている時間の方が長いのに iOS アプリしか作らないのももったいないので、どんどん作っていきたい。