この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
2019年10月31日に「AndroidとiOS向けのGoogle Analytics」のサポートが終了します。
というわけで、移行する前準備として、XamarinでFirebase Analyticsを試してみました。
- Q:なぜXamarin?
- A:趣味です!
Firebase Analyticsのイベントについては、下記をどうぞ!
目次
環境
- Windows
- Windows 10 Pro
- Visual Studio Community 2019 (Ver16.1.5)
- macOS
- macOS Mojave 10.14.5
- Visutal Studio Community 2019 for Mac (Ver8.1.3)
- Xcode 10.2.1
- Android
- Pixel 3a (Android 9)
- iOS Simulator
- iPhone Xs 12.2
- Xamarin
- Xamarin Ver16.1.0.545
- Xamarin.Android SDK Ver9.3.0.23
- Xamarin.iOS and Xamarin.Mac SDK Ver12.10.0.157
- Library
- Xamarin.Forms Ver4.0.0.425677
- Xamarin.Firebase.Analytics Ver60.1142.1
- Xamarin.Firebase.iOS.Analytics Ver5.5.0
アプリの新規作成
Visual Studioを起動し、「モバイルアプリ(Xamarin.Forms)」を選択します。
プロジェクト名を適当に入力します。
場所はできるだけ浅い階層にしましょう!(Windowsの場合)
「ソリューションとプロジェクトを同じディレクトリに配置する」にもチェックを入れておきます。
※Windwosでフォルダ/ファイル階層が深いと、Androidのビルドに失敗するためです。
テンプレートは何でも良いですが、シンプルな「空白」を選択しておきます。
Firebaseプロジェクトの作成
Firebase Consoleにアクセスし、「プロジェクトの作成」を選択します。
プロジェクト名を適当に入力し、アナリティクスの地域を日本にします。
Androidアプリ
FirebaseプロジェクトにAndroidアプリを追加
Firebaseプロジェクトで、Androidマークを選択します。
Androidアプリのパッケージ名をコピペ入力し、「アプリを登録」を選択します。
google-services.json
をダウンロードし、「次へ」を選択します。
Firebase SDKの追加は無視して進み、インストールを確認する画面を表示しておきます。
AndroidアプリのFirebase対応
NuGetパッケージのXamarin.Firebase.Analytics
をAndroidプロジェクトにインストールします。
Visual StudioのAndroidプロジェクト直下に、ダウンロードしたgoogle-services.json
を配置します。
続いて、google-services.json
のビルドアクションをGoogleServicesJson
にします。
この項目が存在しない場合は、Visual Studioを再起動したり、ソリューションのリビルドをすれば現れます。
MainActivity.cs
に初期化とイベント送信をお試し実装します。
ハイライト部分が追加したコードです。
MainActivity.cs
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Firebase.Analytics;
namespace FASample.Droid
{
[Activity(Label = "FASample", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
var analytics = FirebaseAnalytics.GetInstance(this);
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
var bundle = new Bundle();
bundle.PutString(FirebaseAnalytics.Param.ItemCategory, "Monday");
bundle.PutString(FirebaseAnalytics.Param.ItemName, "21:54");
analytics.LogEvent(FirebaseAnalytics.Event.SelectContent, bundle);
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
動作確認(Android)
それでは、アプリを実行しましょう!!
うまくいけば、10~60秒後ぐらいに「正常に追加されました」と表示されます!
Dashboardでも1ユーザと認識されています。
DebugViewの設定(Android)
こちらを参考に実施します。
数分待つと、DebugViewにいろいろと表示されます!!
出ない場合は、アプリを再起動させればOKでした。
iOSアプリ
FirebaseプロジェクトにAndroidアプリを追加
Firebaseプロジェクトで、「アプリを追加」からiOSマークを選択します。
iOSアプリのバンドルIDをコピペ入力し、「アプリを登録」を選択します。 (実機で動作確認する場合は、実機インストール可能なバンドルIDを使用してください)
GoogleService-Info.plist
をダウンロードし、「次へ」を選択します。
Firebase SDKの追加は無視して進み、インストールを確認する画面を表示しておきます。
iOSアプリのFirebase対応
NuGetパッケージのXamarin.Firebase.iOS.Analytics
をiOSプロジェクトにインストールします。
Visual StudioのiOSプロジェクト直下に、ダウンロードしたGoogleService-Info.plist
を配置します。
続いて、GoogleService-Info.plist
のビルドアクションをBundleResource
にします。
GoogleService-Info.plist
のIS_ANALYTICS_ENABLED
をTrue
に変更します。
GoogleService-Info.plist
<key>IS_ANALYTICS_ENABLED</key>
<true></true>
AppDelegate.cs
に初期化とイベント送信をお試し実装します。
ハイライト部分が追加したコードです。
AppDelegate.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Foundation;
using UIKit;
using Firebase.Analytics;
namespace FASample.iOS
{
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
// https://github.com/xamarin/GoogleApisForiOSComponents/issues/158#issuecomment-483194061
var foo = Firebase.Core.Configuration.SharedInstance;
Firebase.Core.App.Configure();
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
var events = new Dictionary<string, string>
{
{
ParameterNamesConstants.ItemCategory,
"Friday"
},
{
ParameterNamesConstants.ItemName,
"17:08"
},
};
var sendParams = NSDictionary<NSString, NSObject>.FromObjectsAndKeys(
events.Values.ToArray(),
events.Keys.ToArray()
);
Analytics.LogEvent(EventNamesConstants.SelectContent, sendParams);
return base.FinishedLaunching(app, options);
}
}
}
なお、ビルドした際に下記エラーが発生したため、var foo = Firebase.Core.Configuration.SharedInstance;
を追加してます。
error MT5210: Native linking failed, undefined symbol: ...
error MT5211: Native linking failed, undefined Objective-C class: ...
error MT5201: Native linking failed. Please review the build log and the user flags provided to gcc: -ObjC -ObjC -lc++ -lsqlite3 -lz -ObjC -lc++ -lsqlite3 -lz
error MT5202: Native linking failed. Please review the build log.
動作確認(iOS)
それでは、アプリを実行しましょう!!
うまくいけば、10~60秒後ぐらいに「正常に追加されました」と表示されます!
Dashboardでも1ユーザと認識されています。
DebugViewの設定(iOS)
こちらとこちらを参考に--argument=-FIRDebugEnabled
を追加します。
数分待つと、DebugViewにいろいろと表示されます!!
出ない場合は、アプリを再起動させればOKでした。
共通プロジェクトからイベント送信してみる(Xamarin.Forms)
せっかくなので、Xamarin.FormsのDependencyServiceを利用し、共通プロジェクトから呼び出しましょう。
参考にどうぞ!(どちらかというと、これが本命だったりします)
インターフェースを定義
共通プロジェクト(FASample)にIAnalytics.cs
を作成します。
IAnalytics.cs
using System.Collections.Generic;
namespace FASample
{
public interface IAnalytics
{
void LogEvent(string eventName, Dictionary<string, object> eventParams);
void Screen(string screenName);
}
}
Androidの実装
Androidプロジェクト(FASample.Android)にAnalyticsSingleton.cs
とAnalytics_Android.cs
を作成します。
AnalyticsSingleton.cs
using Android.App;
using Firebase.Analytics;
namespace FASample.Droid
{
public class AnalyticsSingleton
{
public static AnalyticsSingleton GetInstance { get; } = new AnalyticsSingleton();
public FirebaseAnalytics Analytics { get; set; }
public Activity Activity { get; set; }
private AnalyticsSingleton()
{
}
}
}
Analytics_Android.cs
using System.Collections.Generic;
using Android.OS;
using Xamarin.Forms;
using FASample.Droid;
[assembly: Dependency(typeof(Analytics_Android))]
namespace FASample.Droid
{
public class Analytics_Android : IAnalytics
{
public void LogEvent(string eventName, Dictionary<string, object> eventParams)
{
if (eventName == null || eventParams == null) return;
var analytics = AnalyticsSingleton.GetInstance.Analytics;
var bundle = new Bundle();
foreach (var eventParam in eventParams)
{
if (eventParam.Value.GetType() == typeof(string))
{
bundle.PutString(eventParam.Key, (string)eventParam.Value);
}
if (eventParam.Value.GetType() == typeof(int))
{
bundle.PutInt(eventParam.Key, (int)eventParam.Value);
}
}
analytics.LogEvent(eventName, bundle);
}
public void Screen(string screenName)
{
if (screenName == null) return;
var analytics = AnalyticsSingleton.GetInstance.Analytics;
var activity = AnalyticsSingleton.GetInstance.Activity;
analytics.SetCurrentScreen(activity, screenName, null);
}
}
}
続いて、MainActivity.cs
のOnCreate()
を次のようにし、FirebaseAnalyticsのインスタンスを保存します。
MainActivity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
AnalyticsSingleton.GetInstance.Analytics = FirebaseAnalytics.GetInstance(this);
AnalyticsSingleton.GetInstance.Activity = this;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
iOSの実装
iOSプロジェクト(FASample.iOS)にAnalytics_iOS.cs
を作成します。
Analytics_iOS.cs
using System.Collections.Generic;
using System.Linq;
using Foundation;
using Firebase.Analytics;
using Xamarin.Forms;
using FASample.iOS;
[assembly: Dependency(typeof(Analytics_iOS))]
namespace FASample.iOS
{
public class Analytics_iOS : IAnalytics
{
public void LogEvent(string eventName, Dictionary<string, object> eventParams)
{
if (eventName == null || eventParams == null) return;
var sendParams = NSDictionary<NSString, NSObject>.FromObjectsAndKeys(
eventParams.Values.ToArray(),
eventParams.Keys.ToArray()
);
Analytics.LogEvent(eventName, sendParams);
}
public void Screen(string screenName)
{
Analytics.SetScreenNameAndClass(screenName, null);
}
}
}
呼び出し側の実装
画面表示時に画面情報を送信し、ボタンを押したときにイベントを送信してみます。
MainPage.xaml
とMainPage.xaml.cs
を編集します。
title="MainPage.xaml"]
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="FASample.MainPage">
<StackLayout VerticalOptions="Center">
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="Center"/>
<Button Text="send event"
HorizontalOptions="Center"
VerticalOptions="Center"
Clicked="Button_OnClicked" />
</StackLayout>
</ContentPage>
MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;
namespace FASample
{
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
DependencyService.Get<IAnalytics>().Screen("This is MainPage!!!");
base.OnAppearing();
}
private void Button_OnClicked(object sender, EventArgs e)
{
var events = new Dictionary<string, object>
{
{
"item_category",
"August"
},
{
"item_name",
"18th"
},
{
"item_id",
18
}
};
DependencyService.Get<IAnalytics>().LogEvent("select_content", events);
}
}
}
いざ、実行します!!
動作確認(Android)
screen_view
が飛んできました。
詳細を見ると、This is MainPage!!!
が表示されています!!
続いて、アプリ画面のボタンを押すと、select_content
が飛んできました。
詳細を確認すると、バッチリ送信できています!!
動作確認(iOS)
iOSも同様です!!
さいごに
結果的には、意外と簡単にできました。(ハマりまくりましたけど……)
やり方は分かったので、あとは本番アプリに適用するだけです。(これが大変だけど……)
参考
- Firebase Analyticsの仕様的な
- Firebase AnalyticsのAndroid的な
- Firebase AnalyticsのiOS的な
- Xamarin