Qiitaの人気記事を見られるiOS用Widgetアプリリリースしました🤖

## はじめに
この度、「WidgetQiita」というQiitaの記事をWidgetで見れるアプリをリリースしました :tada: 
Widgetに表示された記事をタップするとSafariなどのデフォルトのブラウザでタップした記事を見ることができます。
また、Widgetからタップした記事は閲覧履歴として後から確認することも可能です。


| Widget | 閲覧履歴 | よく見るユーザーとタグ　|
| -- | -- | -- |
|![IMG_0BF4F84AFAF3-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/5754eaba-abc4-178d-e909-2338c2593e76.jpeg)  | ![IMG_0027.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/f25d4f7b-ab7d-64ec-b82d-43e3cecc1585.png) | ![IMG_0028.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/8d6f8261-36c4-a108-60c6-f63fff69ca1f.png)|

iOSのWidgetのサイズは`systemSmall`, `systemMedium`, `systemLarge`の3種類です。

| systemSmall | systemMedium | systemLarge　|
| -- | -- | -- |
| ![IMG_0029.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/37d1d57a-5358-648a-e742-27d5db74f773.png) | ![IMG_0030.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/dcca1f52-401a-f3f6-48c3-4766862d5ab2.png) | ![IMG_0031.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/f2007c84-19f0-6df0-baa5-af06ffa2b33b.png) |

iPadOS15.0以降なら上記に追加で`extraLarge`にも対応しています。
（今年発売の[iPad mini](https://www.apple.com/jp/ipad-mini/)可愛すぎませんか？）
![IMG_0369.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/ca67a322-7f84-ea60-222d-861847e027d1.png)


気になった方、勉強になると思った方はこちらからインストールしてみてください🙏🏻

<a href="https://apps.apple.com/us/app/widgetqiita/id1585253685?itsct=apps_box_badge&amp;itscg=30200" style="display: inline-block; overflow: hidden; border-radius: 13px; width: 250px; height: 83px;"><img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=250x83&amp;releaseDate=1631923200&h=fca5a63570aea49606cdea0ce4323f5c" alt="Download on the App Store" style="border-radius: 13px; width: 250px; height: 83px;"></a>
<img src="https://tools-qr-production.s3.amazonaws.com/output/apple-toolbox/c1e21820df97cbe67394d870c6152b7d/81d7677ca2bed3644801847c9a8cf59a.png"  width="128px">

### 本題
実はWidgetQiitaがリリースするまでに2年以上の歳月がかかっております。
WidgetはiOS14からの機能でして2年前には存在していない機能です。
どうしてWidgetをメインにしたアプリになったのかappleのレビュワーとの二年間に及ぶ戦いの日々を書き連ねていきたいと思います。

### なぜ作ろうと思ったのか
iOSエンジニア歴が半年もない状態で新卒として配属されたチームでの開発体制は"テスト駆動開発"で"ペアプログラミング"を実施しており、アーキテクチャは"Clearn Architecture" + "AppCoordinator"パターンという当時の自分は触ったことも聞いたこともないといった状況でした。

学生の頃、Unityでクソゲーを量産してきた経験？から、自分は何事も手を動かさないと身につけることができないということを理解していたのでとりあえず愚直に
「TDDでCleanArchitectureで個人アプリを作ろう！」
となりました。
そこでどんなアプリにしようかと悩んでたところ、Qiita APIができる機能が多くドキュメントが日本語のためハードルが低く、かつ実際にAPIを使って記事を書いている人が多いためQiitaのクライアントアプリを作ろうと決めました！

https://qiita.com/api/v2/docs

以下のように機能をホワイトボードに書き出して毎日仕事から帰ってきたら

### １回目のリジェクト :tada:
そんなわけで、毎日仕事終わりにコツコツ作り3ヶ月ぐらいで以下の全ての要件を実装し終わり、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">自分で考えた要件は、全部実装した！<br>とりあえずファーストリリースはこれで、継続的インテグレーションを忘れずに、、<a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://twitter.com/hashtag/Qiitable?src=hash&amp;ref_src=twsrc%5Etfw">#Qiitable</a> <a href="https://twitter.com/hashtag/%E5%80%8B%E4%BA%BA%E9%96%8B%E7%99%BA?src=hash&amp;ref_src=twsrc%5Etfw">#個人開発</a> <a href="https://t.co/ItWupqQ7Nq">pic.twitter.com/ItWupqQ7Nq</a></p>&mdash; tsuzuki (@tsuzuki817) <a href="https://twitter.com/tsuzuki817/status/1173585354068152320?ref_src=twsrc%5Etfw">September 16, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

2019/9/22 に１回目の申請をしました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">QiitaクライアントアプリAppleさんに申請した(n=1) <a href="https://t.co/MLnszobA5B">pic.twitter.com/MLnszobA5B</a></p>&mdash; tsuzuki (@tsuzuki817) <a href="https://twitter.com/tsuzuki817/status/1175719280576385024?ref_src=twsrc%5Etfw">September 22, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ここで１回目のリジェクトをくらいました。

理由は、appleストアに同じようなアプリが既にあるためダメです的なものでした...orz
しかも、何回も同じようなアプリを提出してきたらスパムとみなします、的な文言まで添えられていてかなりビビりました :sweat_drops: 
そこで既にストアにあるアプリとの差別化を図るためにメモ機能の追加や細かい機能の追加を行いました。

### 2回目のリジェクト :tada: 
なんとか実装を加えてリリースしました。
しかし、またしても同じ理由でリジェクトされてしまいました。
UIKitよりSwiftUIの開発にハマっていた自分は、このアプリをリリースすることを諦めてしまいました :sweat_smile: 

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Appleさんにリジェクトされてたアプリをいろいろ改良して再提出した！<br>レビュワーの方といいアプリ作ってるみたいで燃えました🔥</p>&mdash; tsuzuki (@tsuzuki817) <a href="https://twitter.com/tsuzuki817/status/1200761607023759360?ref_src=twsrc%5Etfw">November 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 3回目のリジェクト :tada: 
2020年の12月ごろ、たまたま自分が作っていたQiitaアプリの話をしたことをきっかけにもう一回申請頑張ってみようかなと考えまして、記事の閲覧数によって自分のステータスがアップするミニゲーム要素をくわえることにしました。

これなら似たようなアプリはあるまいと意気込み申請しました。

そしてリジェクトです。

2020年6月末からログイン機能を提供しているすべてのiOSアプリで`Apple Sign In`が必須になりました。
`Apple Sign In`というのは、AppleIDでアプリやサイトに登録できるようなるというユーザーにとってはとても親切な機能です。

しかしQiitaには`Apple Sign In`機能がないため、華麗にリジェクトを食らいました。

https://qiita.com/shiz/items/5e094910f742c2ad72a4

Qiita APIはログインしていないと、APIの叩ける回数やLGTMやストック、コメント、フォローなどできなくなるので絶望的です。
なんとかレビュワーの方に、頼みましたが儚く終わりました... orz


### 4回目のリジェクト :tada: 

3回目のリジェクトのあたりから、副業をするようになり個人アプリ開発の優先順位が下がってきておりました。

https://www.nicody.jp/

しかし、iOS14から登場するWidget機能が個人的にはとてもお気に入りの機能でして、簡単なWidgetアプリをリリースして、とても満足していましたが、
心の奥底にはQiitaアプリがこちらをちらちらと見ており、Widget機能をつけてQiitaアプリをリリースしたい！
という強い思いが込み上げてきました！
(2021/06ぐらい)

https://apps.apple.com/jp/app/1of366/id1538336225

そこで前回してきされたApple Sign InはQiitaのログイン機能としては提供されていないため、あきらめログインに関係しそうな機能を全て削除しました；；

そして、削除したあとに今回リリースしたアプリの元となるWidgetを作って申請しました！

そしてもちろんリジェクトです。

今回の理由はちゃんとメールが残っていました。
`Guideline 5.1.1 - Legal - Privacy - Data Collection and Storage`で簡単にいうと、このアプリはCOVID-19関連のアプリだから政府関係じゃないとだめだよ

的なことでした。

最初は意味がわからず混乱したのですが、レビュワーの方は親切にもアプリの検索機能を使い`COVID-19`と検索し出てきた記事をスクリーンショットに貼ってくださっていました。

COVID-19の話題が上がっていると全く相手にしてもらえない様子でした。

https://gigazine.net/news/20200306-apple-coronavirus-apps-for-ios/

### 5回目のリジェクト :tada: 
COVID-19と検索されるとリジェクト対象の記事が出てきてしまうので、検索機能を消してしまえば問題ないだろうということで検索機能を消して再度申請しました。

しかしリジェクト。

レビュワー云く「検索機能を消してもこのアプリはCOVID-19関連のアプリって認識したからだめだよ」

的なことでした... orz

しかし、Widget機能だけでもちゃんとリリースしたいと強く思っていたのでどうにかしてアプリをリリースする方法を考えました。

「アプリにCOVID-19関連の情報が表示されてはいけない」

この用件を満たす解決策が現在のアプリです。

基本的には、Widgetで記事名を表示するだけなのでCOVID-19関連の情報が表示されることはありません。

また記事を閲覧するのはアプリではなく、Safariで開くようにしました。

これでいけると思い、WidgetQiitaの作成に取り掛かります！

### WidgetからSafariに遷移させる方法

この記事を書いている段階では、少なくとも自分の知る範囲でWidgetから直接Safariを起動する方法がわかりませんでした。
そこで、一度本体アプリを経由してからSafariに遷移するといった方法をとっています。

仕組み的には

1. Widgetで記事をタップ
2. URLスキームをつけて本体アプリを開く
3. URLスキームに付けられたパラメータをもとに記事のリンクを作成してSafariを開く

といった流れになっています。

基本的にはタップした時に、Linkをつかってアプリ本体のURLスキームを叩いて遷移させています。

```.swift
struct Link<Label> where Label : View
```

https://developer.apple.com/documentation/swiftui/link

ただし、smallサイズのWidgetにはLinkが効かないので、`widgetURL`メソッドを使って開くURLを指定します。


```.swift
func widgetURL(_ url: URL?) -> some View
```

https://developer.apple.com/documentation/swiftui/view/widgeturl(_:)

次に、アプリ側でURLスキームを開けるように設定をしておきます。
大元のViewで`onOpenURL`をセットしておきます。
このようにすることで、WidgetがURLスキームを開いた時のURLをonOpenURL内でキャッチすることができます。

```.swift
func onOpenURL(perform action: @escaping (URL) -> ()) -> some View
```


https://developer.apple.com/documentation/swiftui/view/onopenurl(perform:)

なお、一度Widget側で一度URLに変更するときには、URLComponentsを使って一度URLに変更しています。

こんな感じで今のようなアプリ申請しました！

### 6回目のリジェクト :tada: 

今回のアプリには実は課金することによって広告を非表示にすることができるという機能を入れたのですが、それ関連でリジェクトされてしました... orz

`Guideline 3.1.2 - Business - Payments - Subscriptions`で、アプリの課金するページにもちゃんと利用規約とプライバシーポリシーのリンクをちゃんと置いておいてくださいてきなことだったのですぐに対応しました！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171702/144e767f-bdd6-9b78-caa6-5f2e5aed1e93.png"  width="256px">

### ついにリリース :tada: :tada: :tada: 
こうして2年以上に及ぶ奮闘の末アプリをリリースすることができました！
大きく6回のリジェクトに分けて紹介しましたが、本当はスクリーンショットやminimum functionなど細かい理由で倍以上リジェクトは食らっていますが、あまり書くこともないので割愛しました :smile: 

appleは常に時代にあった変化をし続けていくので、開発者も常に一緒に進化し続けないと行けないということがよくわかりました。

このアプリを使って、みなさんが面白い記事に出会えることを祈っています :pray_tone1: 

また追加機能のご要望、バグの報告、アドバイス、感想もろもろありましたらこちらの[Twitterアカウント](
https://twitter.com/WidgetQiita)によろしくお願いいたします :bow: 

<a href="https://apps.apple.com/us/app/widgetqiita/id1585253685?itsct=apps_box_badge&amp;itscg=30200" style="display: inline-block; overflow: hidden; border-radius: 13px; width: 250px; height: 83px;"><img src="https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=250x83&amp;releaseDate=1631923200&h=fca5a63570aea49606cdea0ce4323f5c" alt="Download on the App Store" style="border-radius: 13px; width: 250px; height: 83px;"></a>
<img src="https://tools-qr-production.s3.amazonaws.com/output/apple-toolbox/c1e21820df97cbe67394d870c6152b7d/81d7677ca2bed3644801847c9a8cf59a.png"  width="128px">