iOSエンジニアのつぶやき

毎朝8:30に iOS 関連の技術について1つぶやいています。まれに釣りについてつぶやく可能性があります。

【CSS】<button>要素の枠線と背景色を消す

CSS初心者なのでメモ🔰

結論

枠線はborderプロパティ、背景はbackgroundプロパティからそれぞれ消せます。

.button {
  border: none;
  background: transparent;
}

ちなみに、クリック時の枠線も消す場合は下記のようにoutlinenone にしておきます。

.button {
  border: none;
  outline: none;
  background: transparent;
}

てな感じで本日も以上となります🍺

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

Firebase A/B Testing をちょっと調べた

最近 Firebase A/B Testingを触る機会があったので、調べたことをちょっとメモしておきます🏃‍♂️

Firebase A/B Testingとは?

Firebase が提供する A/B テストの手法で、AまたはBのタイプでどちらの方がCVRがいいのかを分析し、プロダクトを最適化することができます。(現在提供されているのはベータ版のようです。) ちなみに、Firebase A/B Testingが利用できるのは、現時点では下記の三つになります。

  • Cloud Messaging
  • Remote Config(今日の話はこれ)
  • In-App Messaging

Firebase A/B Testingに必要な設定

Remote Configを使用して、Firebase A/B Testingを使用する際には下記を設定する必要があります。

  • *ターゲットユーザ
    • テスト対象のアプリ(iOS, Android, Webなど)
    • テスト対象のフィルター(アプリバージョン、地域、ユーザーオーディエンス)
  • アクティベーションイベント
    • テストが有効となるイベント
  • *コンバージョンイベント
    • テスト対象に行なってほしい、目標となる指標(e.g. 商品の購入など)
  • *バリアント
    • AとBでのRemoteConfigの設定値

アクティベーションイベントを使って、対象となるユーザが特定のアクションをした場合にテストを有効にすることができます。例えば、アプリのチュートリアルページを開いたイベントを設定すると、ターゲットユーザがアプリのチュートリアルイベントを開いた時点で、そのユーザはテストの対象となり、その後の行動がテストの結果に反映されます。また、コンバージョンイベントはメインのものと、その他のコンバージョンイベントを設定することができ、どちらもテストの結果では、それぞれのバリアントでのCVRを見れるようになっています。ちなみに、その他のコンバージョンイベントは、5個までしか設定できないっぽいです。

てな感じで本日は一旦以上になります🍺

参考

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

【SQL】unnestってなんだ

先日同様に、Firebase A/B Testing の結果をBigQueryで出力したところ、見慣れないunnestという演算子があったのでメモ🔰

結論

unnest演算子は、ARRAYREPEATEDなカラムをフラット化し、一行にしたテーブルを返します。

公式のサンプルを拝借すると下記のような感じで、ARRAYが展開されているのがわかります。

SELECT *
FROM UNNEST(['foo', 'bar', 'baz', 'qux', 'corge', 'garply', 'waldo', 'fred'])
  AS element
WITH OFFSET AS offset
ORDER BY offset;

+----------+--------+
| element  | offset |
+----------+--------+
| foo      | 0      |
| bar      | 1      |
| baz      | 2      |
| qux      | 3      |
| corge    | 4      |
| garply   | 5      |
| waldo    | 6      |
| fred     | 7      |
+----------+--------+

また、Google AnalyticsのデータをBigQueryで使う際に登場するuser_propertiesのようなREPEATEDなカラムも下記のようにして簡単にアクセスできるようになります。

...
        FROM
          `analytics_hoge.events_*`,
            UNNEST(user_properties) AS userProperty
        WHERE
          (_TABLE_SUFFIX between '20201105' AND '20201202')
          AND userProperty.key = "firebase_exp_34"
...

てな感じで本日も以上となります🍺

参考

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

【BigQuery】_TABLE_SUFFIXキーワードとは?

Firebase A/B Testing の結果をBig Queryで出力したところ、クエリに見慣れない_TABLE_SUFFIXキーワードがあったのでメモ🔰

結論

ワイルドカードテーブルを使用した場合に、_TABLE_SUFFIXでテーブル名のsuffix(接尾)を取得することができます。これは、特定の期間毎に作成されるテーブルなどで、期間毎にクエリをしたい場合などに便利です。

公式ドキュメントに載っているサンプルを拝借すると下記のようになります。AND ( _TABLE_SUFFIX = '0' OR _TABLE_SUFFIX = '4' ) とすることで、bigquery-public-data.noaa_gsod.gsod1940またはbigquery-public-data.noaa_gsod.gsod1944のテーブルをターゲットにクエリできるようになります。

#standardSQL
SELECT
  max,
  ROUND((max-32)*5/9,1) celsius,
  mo,
  da,
  year
FROM
  `bigquery-public-data.noaa_gsod.gsod194*`
WHERE
  max != 9999.9 # code for missing data
  AND ( _TABLE_SUFFIX = '0'
    OR _TABLE_SUFFIX = '4' )
ORDER BY
  max DESC

てな感じで本日も以上となります🍺

参考

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

Duplicate identifier 'LibraryManagedAttributes' エラーの対処法

@types/react導入済みのプロジェクトで、後から@types/react-responsiveを追加した時に下記のようなエラーが100件近く発生したので、その原因と対処法をメモしておきます👀

Duplicate identifier 'LibraryManagedAttributes'.

結論

どうやら,yarnreactの複数のバージョンの定義を解決しようとしたために、LibraryManagedAttributesの定義が重複していたことが問題のようでした。 ということで、yarnresolutionsを使ってこれの重複を解決していきましょう。resolutionsは複数のバージョンがあるパッケージを一つのバージョンで解決してくれます.

classic.yarnpkg.com

package.json内にresolutionsセクションを下記のように追加して、yarnコマンドでインストールを再度実行するとエラーなくプロジェクトをビルドできるようになりました!

  "resolutions": {
    "@types/react": "^16.9.11"
  },

という感じで本日も以上となります🍺

参考

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

【CSS】background-imageで指定した画像が表示されん

結論

url-loaderlimitでの制限を超える、ファイルサイズの場合表示されていなかったぽくて、limitの数値を多めに設定したら表示されるようになりました👀

    config.module.rules.push({
      test: /\.(png|jpg|gif|svg)$/,
      use: {
        loader: 'url-loader',
        options: {
          limit: 8192
        }
      }
    })

v4.webpack.js.org

ちなみに、この制限を超えるとfile-loaderが使用されるらしい。

てな感じで本日も以上となります🍺

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog

【Firebase】Firebase Dynamic LinksのURL手動構築

以前の記事をアップデート版を書く機会があったので再投稿🏃‍♂️

yamatooo.blog

Firebase Dynamic Links

Firebase Dynamic Linksは、Firebaseが提供するDynamic Links機能で、ユーザがリンクを開いた時の挙動をネイティブアプリのインストール状況などに応じて遷移先を変えることができる技術です。

f:id:yum_fishing:20210702194526p:plain

Firebase Dynamic Linksの種類

どのような生成方法があるのかを見ていく前に、Firebase Dynamic Linksの種類を見ていきます。現在FirebaseにはLong Dynamic LinksShort Dynamic Linksの二つのDynamic Linksがあります。

  • Long Dynamic Links
  • Short Dynamic Links

Short Dynamic Linksの方がURLの長さが短いのは、名前から察することができると思いますが、両者には大きな違いが一つあり、それは自動でトラッキングされるデータです。

ちなみに、僕が調べた限りではそれぞれ自動でトラッキングされるデータは下記のようになります。

Dynamic Links Type Firebase Dynamic Links Analytics Google Analytics
Short Dynamic Links アプリの初回起動、アプリの再開、クリック数、リダイレクト、アプリインストール アプリの初回起動、アプリの再開、アプリのアップデート
Long Dynamic Links なし アプリの初回起動、アプリの再開、アプリのアップデート

Firebase Dynamic Links Analyticsは、Firebaseコンソール(Dynamic Linksセクション)またはREST API経由でトラッキングデータを取得することができ、Google AnalyticsについてはFirebaseコンソール(Analyticsセクション)または、Google AnalyticsデータをBigQueryにエクスポートすることで、BigQueryからデータを見ることができます。

🎣

Firebase Dynamic Linksの生成方法

ということで、次はFirebase Dynamic Linksの生成方法について見ていきましょう。

まず、公式ドキュメントに載っている概要説明の「仕組み」セクションの最初の文には下記のように書いてあります。

ダイナミック リンクを作成するには、Firebase コンソール、REST APIiOS または Android Builder API を使用します。

参照: https://firebase.google.com/docs/dynamic-links?hl=ja#how-does-it-work

そう。この文を見て僕はAPIを介してのみFirebase Dynamic Linksを生成できないものだと勘違いしていました。厳密には、Short Dynamic Linksの場合はAPIを介してリンクを生成する必要があり、Long Dynamic Linksの場合は手動でURL構築をすることも可能ということです。ということで、Firebase Dynamic Linksの生成方法は下記の通りになります。

  • Firebaseコンソール
  • Dynamic Links Builder API
  • REST API
  • *URLの手動構築(今回の話)

Dynamic Links Builder APIは、iOSAndroidといったそれぞれのプラットフォームで用意されているFirebase SDKに内包されていて、リンクをアプリ内で動的に生成する場合なんかに使われていて、REST APIDynamic Links Builder APIが使用できない環境下でリンクを動的に生成したい場合なんかに使用されます。

(というかこのBuilder API使ったことある人なら、Long Dynamic Links生成する分にはネットワークを介する必要ないから、URL手動構築できんじゃん!って気付いてそう。)

guard let link = URL(string: "https://www.example.com/my-page") else { return }
let dynamicLinksDomainURIPrefix = "https://example.com/link"
let linkBuilder = DynamicLinkComponents(link: link, domainURIPrefix: dynamicLinksDomainURIPRefix)
linkBuilder.iOSParameters = DynamicLinkIOSParameters(bundleID: "com.example.ios")
linkBuilder.androidParameters = DynamicLinkAndroidParameters(packageName: "com.example.android")

guard let longDynamicLink = linkBuilder.url else { return }
print("The long URL is: \(longDynamicLink)")

URLの手動構築

結論から言うとURLの手動構築は、下記のような形式で行うことができます。

https://[your_domain].page.link/?link=https://komer.co/skus/sDUqpxQg864DJPLriMTG&ibi=com.cookpad.ios.komerco-customer

[your_domain].page.linkドメインを指定して、あとはパラメータを追加してリンクタップ時の挙動を変えていく感じですね。

それぞれのパラメータについては、公式ドキュメントに詳しく書かれているので省略しますが、後述す解析パラメータ以外の大事な部分(今回はiOSに関連する部分)だけ抜粋して一旦説明します。

link

まずは、linkパラメータ。これがアプリ内の特定のコンテンツを開くための重要なリンクで、アプリ側ではこのリンクを処理して、特定のコンテンツを表示できるようにしておく必要があります。また、このリンクはHTTP、HTTPSのいずれかを使用して設定する必要があり、アプリがインストールされていない場合のデフォルト遷移先にもなります。

ibi

Dynamic Linksで開きたいiOSアプリのBundleIDを指定するパラメータで、アプリを開くには必須のパラメータです。ちなみにAndroidアプリでも開きたい場合にも同様に、apnにパッケージ名を追加する必要があります。

ifl

アプリがインストールされていない場合に開くリンクを指定することができます。デフォルトでは、linkで指定したURLに遷移します。ちなみにAndroidの場合は、aflで指定する。

st

ソーシャル投稿などで、リンク共有時に使用されるタイトルを設定します。

sd

同じくソーシャル投稿などで、リンク共有時に使用されるリンクの説明を設定します。

si

同じくソーシャル投稿などで、リンク共有時に使用される画像へURLを設定します。 ちなみに画像は、

300x200 ピクセル以上、300 KB 未満である必要があります。

だそうです。

解析パラメータ

そして、Dynamic Linksでのイベンなどをトラッキングするために重要な解析パラメータも、URL手動構築(厳密にはLong Dynamic Links生成)の際に付与することができます。

ちなみに、下記が追加可能な解析パラメータになります。

パラメータ 送信先
utm_source, utm_medium, utm_campaign, utm_term, utm_content, gclid Google Analytics
at, ct, mt, pt App Store(App Store Connectで確認できる)

そうです!App Storeにも解析パラメータを送信することができるので、Long Dynamic Linksでも、どのリンク経由でアプリがインストールされたのかもわかります。具体的にはct(Campaign Token)で、どのキャンペーンでアプリがインストールされたのかなどを調べることができます。

結局なにが嬉しいのか?

Dynamic Linksの動的生成が楽!

例えば、ECサービスの商品詳細画面でリンクをタップした時にネイティブアプリの特定のコンテンツに遷移させたいとなった場合、linkパラメータを現在のパスに応じて変更するだけでURLを構築することができるので、商品毎にDynami Linksを発行する手間が省けるといった感じです🎉(つまりFirebaseはいいぞ)

てな感じで今回は以上となります🏃‍♂️

その他の記事

yamatooo.blog

yamatooo.blog

yamatooo.blog