Show original
Enjoyed this article?
Support i_factory

AI translation
It's quite a hassle to prepare it until it's ready to use because of iOS restrictions, , , , ,
Enjoyed this article?
Support i_factory
I wanted to eliminate "time spent searching for apps," so I built an iOS launcher—and ran into two walls with iOS.
I want to eliminate the action of "searching for apps" from my daily routine. That's the only reason I built this.
I think there's more value in writing about what I couldn't overcome than what I managed to do, so I'll focus on that.
There's time spent flipping through multiple home screen pages looking for the app I need.
Each search takes only a few seconds, but I do it many times a day.
Most people try to solve this through "organization"—creating folders, rearranging, moving unused apps to other pages.
But apps keep increasing, so organization never ends. You end up organizing forever.
So I thought: what if the order itself could move?
Based on the current time, day of the week, location, and whether I'm moving, show the "app I'm likely to open next" at the top.
That way, I wouldn't need to search or organize as much.
I built an iOS launcher. It displays the same order both in the app itself and in a widget on the home screen.
To predict ahead of time, I need to remember when and what the person opened. This was the first wall.
iOS has no way to know when other apps are launched.
⇒ I can only record what was opened through this app.
In other words, I can never see how many times someone opened LINE directly from the home screen.
I can only remember when they tapped an icon within the app or opened it from the widget.
This isn't something with a workaround—it's just how it is.
So I decided to write about it plainly, whether in the app or in pre-launch guidance. If I hide it, people will think "this app doesn't learn," and that's the end of it.
I only remember when you tap an icon in this app or open it from the widget. I don't record direct opens from the home screen (because iOS won't tell me when other apps are launched).
Wall #2 grows directly out of wall #1.
iOS has no API to list the apps installed on the device. All I can do is check "is there an app that can open this URL scheme?"—and even then, Info.plist in the LSApplicationQueriesSchemes only lets me query up to 50 entries that I've written in advance.
I have 50 entries, with 0 slots left. ⇒ To add one, I have to remove something else.
So I keep 53 of the popular ones and check whether they exist,
but for apps not on that list, I have to ask users to register them themselves.
I want to predict ahead, but first I have to ask for registration work. This is the part I feel most sorry about.
The slowness of registration wasn't a UI design problem.
The only way to confirm "whether that app can actually be opened" is to actually open it. And the moment it opens, my app goes to the background. ⇒ I can't move to the next one.
Plus, open only returns "it opened." It doesn't return what opened. Even if I meant to open twitter:// but a different app launched, I can't tell the difference.
⇒ Only the user's eyes can verify it. I had to ask the person who came back: "Was the app that just opened correct?"
I tried several ways to automate this, and they all hit this same wall.
"Open → go to background → verify with eyes → return" is the minimum unit for one entry, and it can't be shortened.
I didn't give up entirely. There was one workaround.
Apps that can be opened via universal links have their provider'shttps://<ドメイン>/.well-known/apple-app-site-association publicly declare it in appID.
If the bundleId written there matches the one in the App Store, I can confirm that's the correct way to open it. Not a guess. And this verification requires no screen switching at all.
⇒ Only at this stage can I pass dozens of names at once and run it.
I measured it in practice. Of the 67 apps on my device, 21 (31%) were confirmed without switching screens even once.
The remaining 69% have to be inferred from bundleId, so I still end up asking users to verify them one by one with their eyes.
I could only reduce it by 3 percent. But finding a place where I could reduce it at all was a win.
Accuracy measured on my own data:
1st place is correct: 73.7%
Within top 3: 91.7%
Upper limit if prediction were perfect: 90.5%
The upper limit is 90.5% not because of prediction quality.
It's because people open different apps at the same time and place. ⇒ "Always 1st place" is theoretically impossible.
So I decided not to write "always" or "guaranteed" in ads or on screen.
On the other hand, in places where only certain apps are used (gyms, salons, store membership apps, etc.),
my measurements show them consistently appearing in 1st place. It clearly works in some places and not others.
I haven't given up on reducing registration effort.
As more apps become openable via universal links, the percentage I can confirm without opening should increase.
I'll measure how far that 31% can grow.
If anyone else got stuck in the same place, or if you know a workaround, please tell me.
「アプリを探す時間」を消したくて iPhone のランチャーを作ったら、iOS の壁が2枚あった
日常から「アプリを探す」という動作をなくしたい。それだけのために作りました。
できたことより、どうにもならなかったことのほうが書く価値があると思うので、そちらを厚めに書きます。
ホーム画面を何ページもめくって、目的のアプリを探している時間があります。
1回は数秒でも、1日に何度もやっています。
多くの人はそれを「整理」で解決しようとします。フォルダを作って、並べ替えて、使わないものを別ページへ追いやる。
でもアプリは増え続けるので、整理は終わりません。ずっと整理し続けることになります。
だったら、並びのほうが動けばいいと考えました。
いまの時刻・曜日・いる場所・移動しているかどうかから、「次に開きそうなアプリ」を上に出す。
そうすれば探す必要も、整理する必要も減るはずです。
作ったのは iOS のランチャーです。本体の画面と、ホーム画面に置くウィジェットの両方に、同じ並びを出します。
先回りするには、その人がいつ何を開いたかを覚える必要があります。ここが最初の壁でした。
iOS には、他のアプリの起動を知る方法がありません。
⇒ このアプリを経由して開いたぶんしか記録できません。
つまり、ホーム画面から直接 LINE を開いた回数は、こちらからは永久に見えません。
覚えられるのは、アプリの中のアイコンを押したときと、ウィジェットから開いたときだけです。
これは回避策のある話ではなく、そういうものだという話です。
なので、アプリの中でも起動前の案内でも、そのまま書くことにしました。隠すと「学習しないアプリ」だと思われて終わるからです。
覚えるのは、この中のアイコンを押したときと、ウィジェットから開いたときだけです。
ホーム画面から直接開いたぶんは記録されません(iOS が、他のアプリの起動を教えてくれないためです)。
1枚目の壁から、そのまま2枚目が生えてきます。
iOS には、端末に入っているアプリを列挙する API もありません。分かるのは「この URL スキームを開けるアプリが在るか」だけで、しかも Info.plist のLSApplicationQueriesSchemes に先に書いておいた 50 件までしか問い合わせられません。
いま 50 件、空き 0 です。⇒ 1つ足すには、どれかを外すしかありません。
そこで有名どころ 53 件を持っておいて在否を確かめる形にしましたが、
そこに無いアプリは利用者に自分で登録してもらうしかありません。
先回りしたいのに、まず登録作業をお願いすることになる。ここがいちばん申し訳ない部分です。
登録が遅いのは、UI の作りが悪いからではありませんでした。
「そのアプリが本当に開けるか」を確かめるには、実際に開いてみるしかありません。そして開いた瞬間、こちらのアプリは背面に回ります。⇒ 次の1件へ進めません。
しかも open は「開いた」としか返しません。何が開いたかは返しません。twitter:// を開いたつもりで別のアプリが立ち上がっていても、こちらには区別がつきません。
⇒ 確かめられるのは利用者の目だけです。戻ってきた人に「いま開いたのは合っていましたか?」と聞く形にしました。
自動化を何通りか試して、全部ここに突き当たりました。
「開く → 背面に回る → 目で確認 → 戻る」が1件の最小単位で、これは縮められません。
全部あきらめたわけではありません。1か所だけ抜け道がありました。
ユニバーサルリンクで開けるアプリは、提供元がhttps://<ドメイン>/.well-known/apple-app-site-association に正式な宣言を公開しています。
ここに書かれた appID が App Store の bundleId と一致すれば、それが正しい開き方だと確定できます。推測ではありません。そしてこの確認は、何も開かずに済みます。
⇒ この段だけは、名前を何十件まとめて渡しても走らせられます。
実測してみました。手元の端末に入っていた 67 件のうち 21 件(31%)が、1回も画面を切り替えずに確定しました。
残りの 69% は bundleId からの推測になるので、結局1件ずつ目で確かめてもらうことになります。
3割しか減らせませんでした。ただ、減らせるところが確かに在ったのは収穫でした。
手元のデータで測った的中率です。
1位が当たる73.7%3位以内に入る91.7%完璧に読めた場合の上限90.5%
上限が 90.5% なのは、予測の出来の問題ではありません。
同じ時刻・同じ場所でも、人は違うアプリを開くからです。⇒ 「必ず1位」は原理的に届きません。
なので、宣伝でも画面でも「必ず」「絶対」は書かないことにしました。
一方で、その場所でしか使わないアプリがある場所(ジムや美容院、お店の会員証など)は、
手元の計測では1位に出続けています。効くところと効かないところが、はっきり分かれるようです。
登録の手間は、まだ諦めていません。
ユニバーサルリンクで開けるアプリは今後も増えるので、開かずに確定できる割合は上がっていくはずです。
31% がどこまで伸びるか、しばらく測ってみます。
同じところで詰まった方がいたら、抜け道を知っていたらぜひ教えてください。