麦芽を支える技術

麦芽(ばくが、英語:malt)とは、麦、特に大麦の種子を発芽させたもので、ビール、ウイスキー、水飴の原料となる。(Wikipediaより)

iOS Universal Linksの設定とFirebase Hostingでの簡単お試し方法

今更といえば今更なんですが、業務でiOSアプリのUniversal Links対応する際に、この辺りを自分なりに整理したので、その内容をメモっておきます。

iOSのDeep Link技術の整理

本題に入る前に、iOSにおけるDeep Link技術について整理しておきます。

ディープリンク(Deep Link, Deep Linking)とは

Mobile deep linking - Wikipedia日本語ページでは、なんかモバイルではなくWeb全般を捉えたページしか無い)

モバイルアプリ文脈では「URLを用いてアプリ内の特定の場所(画面)にリンクすること」をディープリンクと呼びます。

iOSのDeep Linkパターン

1. カスタムスキーマ起動

  • iOSアプリにおけるDeep Linkの方法の1つ
  • http/httpsスキーマの代わりにアプリ独自のスキーマを定義し、そのスキーマを検知してアプリを起動させる
    • ex.) URL: {custom_scheme}://~
  • AppDelegateの application(_:open:options:) でハンドリング
    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        // `url` にリンクされたURLが入ってくるのでハンドリング
        ...
        return true
    }

2. Universal Links

  • iOSアプリにおけるDeep Linkの方法の1つ(ただしiOS9.0以降のみ対応)
  • Webブラウジングにおいて一般的なhttpsスキーマを検知してアプリを起動させる
    • ex.) URL: https:/{your_host_name}/path/to~
  • あくまでトリガーが一般的なWebサイトのURL形式であり、対象アプリが未インストールの場合は通常通りWebブラウザで遷移する。
  • AppDelegateの application(_:continue:restorationHandler:) でハンドリング
    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        if userActivity.activityType == NSUserActivityTypeBrowsingWeb, let url = userActivity.webpageURL {
            // `url` にリンクされたURLが入ってくるのでハンドリング
            ...
        }
        return true
    }

(余談)Firebase Dynamic Links

  • Firebaseが提供するサービスの1つ
  • 名前で混同しがちであり、Webからアプリを開かせるときに使う点は似ているが、上記と並ぶDeep Link技術では無い
  • ユーザ環境(OS、アプリインストール有無など)に応じた適切なリンク先を選択し、提供してくれる
  • 提供されたリンク先を元に、アプリ側でどう振る舞うかは各OSのDeep Link実装に準ずる

Universal Links設定

大きく分けると以下の作業が必要となります。

  • apple-app-site-association ファイルをWeb上に配置
  • iOSアプリ側プロジェクト設定でAssociated Domainsの設定
  • アプリ起動時に入ってくるURLのハンドリング処理を実装

1. apple-app-site-association ファイルをWeb上に配置

apple-app-site-association とは、「このサイト(site)はxxxアプリ(apple-app)と紐づいている(association)よ」ということを示すファイルとなります。

具体的には以下のようなJSONファイルが実体となります。

{
  "applinks": {
       "apps": [],
        "details": [
           {
               "appID":"{APP_ID_PREFIX}.{APP_ID}",
               "paths":[ "*" ]
           }
         ]
    }
}
  • appID :Dev Centerに登録済みの内容を設定
  • paths :対象とするURLパス(ホスト部以降)

これをWebサイト側に設置する必要があるのですが、設置に際しては以下のような設置要件があります。

  • httpsでアクセス可能
  • そのドメインのルート or .well-known サブディレクトリに配置
  • Content-Typeが application/json で返却されること

ちょっとお試しで操作確認したい場合にこの環境用意するのはやや手間なので、簡単なセットアップ方法はこのエントリの後半にて。

2. iOSアプリ側プロジェクト設定でAssociated Domainsの設定

これはここのことですね。

f:id:asmz0:20190217205547p:plain:w600

applinks: の後に続けて 1. のファイルを設置したサーバURLの「ドメイン部」を記載します。サブディレクトリのような指定はできないので注意。

あと、Dev Center上で対象のAppIDのAssociated Domainsもちゃんと有効になっている必要があります。

3. アプリ起動時に入ってくるURLのハンドリング処理を実装

これは上の方でもサンプルコード軽く書きましたが、AppDelegateの application(_:continue:restorationHandler:) でURLを捕捉して、任意のハンドリングを行ってください。

スキーマ起動とUniversal Linksを共存させる場合は、URLからのパス切り出し処理は共通化しておくのが良いですね。

Firebase Hostingで簡単にapple-app-site-association ファイル配置

先ほど説明したapple-app-site-association ファイルの設置と軽い動作確認は、Firebase Hosting使うと便利です。

こんな感じ(firebase-toolsは入っている前提)

$ # firebase hostingの初期設定する
$ firebase init
 
$ # こんな構成でファイルを置く
$ tree
.
├── firebase.json
└── public
    ├── 404.html
    ├── apple-app-site-association
    └── index.html
 
$ # firebase.jsonでContent-Typeを application/jsonにしておく
$ cat firebase.json
{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [
      {
        "source": "/apple-app-site-association",
        "headers": [{"key": "Content-Type", "value": "application/json"}]
      }
    ]
  }
}
 
$ # デプロイ
$ firebase deploy

まず、Firebase Hostingは自動でhttpsになります。 また、上記デプロイするとhttps://xxxxx.firebaseapp.com の直下に apple-app-site-association が配置され、アクセスするとContent-Typeが application/json のレスポンスが返却されます。

よって先に記載した設置要件を全て満たしたことになります!

おわりに

以上がiOS Universal Linksの基本的な設定方法と、簡単なお試し手順の紹介となります。

遷移時に確認ダイアログが表示されるスキーマ起動と違い、Universal LinksはWebからアプリへの遷移がシームレスなので、Webとアプリをうまく融合させたサービスの作りにしたい場合などに有効ですね。

PHPカンファレンス仙台にLT登壇&ブース出展してきました #phpconsen

「ブログを書くまでがカンファレンス」と言われておりますので、熱が冷めないうちに書いておきます。

2019/1/26(土)に開催された「PHPカンファレンス仙台」にて、LT登壇とブースの出展してきました。

phpcon-sendai.net

最初に言ってしまうととても楽しかったわけですが、今回は一般参加者ではなく初めて登壇&ブース出展という役割で参加したので、その辺の観点も含めてまとめてみます。

続きを読む

2019年の目標設定

あけましておめでとうございます。まぁこれを書き始めたのはまだ2018年の蒲田のドトールなので、まだ年明けてないんですが。

どうせすぐには書ききれないので、追記する頃には無事年明けのエントリになるはずです。(この後発熱し寝込んで、年末年始に全く筆が進まなかったので、無事年明けて1/6に大半の内容を追記)

去年は割とちゃんと目標設定&評価したので、2019年もちゃんと目標設定してコツコツ消化していきましょう、ということで所信表明をしておきます。

続きを読む

2018年の振り返りと評価と総括

今年も残すところあとわずかということで、2018年の振り返りをしとこうと思います。

実は毎年なんとなく目標は立てていて、年末になんとなく自分の中で評価してはいたんですが、まぁ当然ながら明文化しとかないとだいたい曖昧な感じになるので今年はちゃんと書いてみます。

今年の活動方針おさらい

そもそも今年はどんな感じでやって行こうか、という点については、今年一発目でTweetしていました。

奥さんの実家でみんな寝静まった後に一人ワイン飲みながら呟いてる関係で、まぁなんとなく日本語が怪しいんですが、活動範囲をより会社外に拡げ、対外的なアウトプットを増やし、個人ブランディングを推進して行こう、みたいなことを言いたかったはずです。

続きを読む

「EVENTech」というIT勉強会・イベント検索アプリをリリースしました

このエントリはQiita「個人開発 Advent Calendar 2018」の5日目のエントリとなります。


はじめに

ホントはアプリのリリースと同時にこういうエントリを書いて、それでアプリの告知とかすれば良かったわけですが、何かこうApple審査通ったらなんだかんだですぐリリースしたくなるもので、かつリリースを済ますとそこである程度満足感を得てしまうものですね。。

なので本エントリは、あえてAdvent Calendarに登録して強制力を持たせてブログを書く、という自分の尻を叩くプレイです。

というわけで、「EVENTech」というiOSアプリを個人で開発してリリースしました。

eventech.asmz.beer

EVENTech

EVENTech

  • Akira Shimizu
  • Business
  • Free

続きを読む

Confluence APIを使ってConfluence上に新規ページを作成する

はじめに

Confluenceとは

ja.atlassian.com

Atlassian社製のチームコラボレーション・ナレッジマネージメントサービス。平たく言うと社内Wiki的なやつですね。

Qiita:Team、esa.ioKibela、Crowi、Notionあたりと競合する領域ですかね。

以下、コンフルと呼びます。

続きを読む

仙台からiOSDC Japan 2018へ参加してきました

事前ブログで宣言した通り、2018/8/31(金)と9/1(土)の2日間「iOSDC Japan 2018」に参加してきました。

asmz.hatenablog.jp

仙台の自宅からiOSDC会場までざっくり3時間。

やっぱ遠いなーとか思ったんですが、よくよく考えたら、数年前まで首都圏に住んでた時は満員の通勤電車で都内まで2時間くらいかかってたし、快適な新幹線使って3時間なら大したことないですね。そうですね。

続きを読む