記事一覧

ファイルにログ出力する機能を作成する | Xamarin.Forms


今回はファイルにログを出力する機能を作成するためのコードをご紹介いたします。

ただ単にログを出力する機能は.Net Framework で提供されていますが、それでは配布したアプリのログを取得することはできません。
System.Diagnostics.Debug.WriteLine
System.Diagnostics.Trace.WriteLine
System.Console.WriteLine

尚、ファイルにログを出力するには最低限以下の機能が必要になります。
(1)保存ディレクトリの取得機能
(2)ファイル書き込み機能
いずれもPCL単体では実現不可能ですので、DependencyServiceにて記述していきます。



前提条件
・Windows10
・Visual Studio 2015 Community Update3
・Xamarin 4.2.0.719 (NuGet Xamarin.Forms 2.3.2.127)
・macOS Sierra 10.12.1 / Xcode8.1 / Xamarin.iOS 10.2.0.4




1.PCLでの実装方法

文章を成形してファイルに出力する関数を作成します。
//LogUtility.cs
public static class LogUtility
{
    /// <summary>
    /// 保存パス
    /// </summary>
    private static string _savePath = null;

    /// <summary>
    /// ログを出力する
    /// </summary>
    /// <param name="err">エラー内容</param>
    public static void OutPutError(string err)
    {
        //保存パスを形成する
        //保存パス=ドキュメントパス&アプリ名_yyyyMMdd.log
        if (String.IsNullOrEmpty(_savePath))
        {
            _savePath = Common.GetDocumentPath();
            if (!_savePath.EndsWith("/"))
            {
                _savePath += "/";
            }
            _savePath += Common.DependSerivce.GetPackageName() + "_";
        }
        //ログ内容の成形
        string msg = "---------------------------------------------------------------------------------------------" + System.Environment.NewLine +
                     DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + " Error " + System.Environment.NewLine +
                     err;

        //Visual Studio 上でのログを出力する
        System.Diagnostics.Debug.WriteLine(msg);

        //ファイルログを出力する
        DependencyService.Get<IDependSerivce>().OutPutLog(_savePath + DateTime.Now.ToString("yyyyMMdd") + ".log", msg);
    }   
}

//Common.cs
public static class Common
{
    /// <summary>
    /// ドキュメントディレクトリを取得する
    /// </summary>
    /// <returns></returns>
    public static string GetDocumentPath()
    {
        string path = DependencyService.Get<IDependSerivce>().GetDocumentPath();
        if (String.IsNullOrEmpty(path))
        {
            path = DependencyService.Get<IDependSerivce>().GetDownloadPath();
        }
        return path;
    }
}

//IDependSerivce.cs
//DependencyServiceから利用する
public interface IDependSerivce
{
    string GetPackageName();
    string GetDocumentPath();
    string GetDownloadPath();
    void OutPutLog(string path, string err);
}



2.Androidの実装方法


//Android  DependSerivce.cs
using Android.Content;
using System;
using System.IO;
using Xamarin.Forms;
[assembly: Dependency(typeof(DependSerivce))]
public class DependSerivce : IDependSerivce
{
    public string GetPackageName()
    {
        Context context = Forms.Context;
        var name = context.PackageManager.GetPackageInfo(context.PackageName, 0).PackageName;
        return name;
    }
    public string GetDocumentPath()
    {
        try
        {
            var dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDocuments);
            return dir.AbsolutePath;
        }
        catch
        {
            return String.Empty;
        }
    }
    public string GetDownloadPath()
    {
        try
        {
            var dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
            return dir.AbsolutePath;
        }
        catch
        {
            return String.Empty;
        }
    }
    public void OutPutLog(string path, string err)
    {
//System.IOを利用する場合
        //System.IO.FileStream fs = new FileStream(path, FileMode.Append);
        //StreamWriter sw = new StreamWriter(fs);
        //sw.WriteLine(err);
        //sw.Close();
        //fs.Close();
        //sw = null;
        //fs = null;

//こちらの方がNativeです。Java.IO
Java.IO.FileWriter fw = new Java.IO.FileWriter(path, true);
Java.IO.BufferedWriter bw = new Java.IO.BufferedWriter(fw);
bw.Write(err);
bw.NewLine();
bw.Close();
fw.Close();
bw = null;
fw= null;
    }
}

※外部ストレージにアクセスするためにはパーミッションの設定が必要です。
次の記事「Android6以降のパーミッションの設定方法」をご参考ください。



3.iOSの実装方法


//iOS DependSerivce.cs
using System;
using System.IO;
using Foundation;
using Xamarin.Forms;
[assembly: Dependency(typeof(DependSerivce))]
public class DependSerivce : IDependSerivce
{
    public string GetPackageName()
    {
        string name = NSBundle.MainBundle.InfoDictionary["CFBundleDisplayName"].ToString();
        return name.ToString();
    }
    public string GetDocumentPath()
    {
        return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
    }
    public string GetDownloadPath()
    {
        return Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
    }
    public void OutPutLog(string path, string err)
    {
        System.IO.FileStream fs = new FileStream(path, FileMode.Append);
        StreamWriter sw = new StreamWriter(fs);
        sw.WriteLine(err);
        sw.Close();
        fs.Close();
        sw = null;
        fs = null;
    }
}



4.使用例

Exception等が発生した場合にログに出力すると良いでしょう。

catch (Exception ex)
{
    LogUtility.OutPutError(ex.Message + System.Environment.NewLine + ex.StackTrace);
}



5.実行例


log_1.png log_2.png


尚、今回ご紹介したソースはAndroid/iOSそれぞれ一つのファイルに集約して書かれていますが、パスを取得するクラスと文字列を書き出すクラスというように、実際は機能ごとに分けたほうが良いかもしれません。
ネームスペースなどは割愛しています。
あなたのアプリに合わせてカスタマイズしてみてください。




当ブログの内容をまとめた Xamarin逆引きメニュー は以下のURLからご覧になれます。
http://itblogdsi.blog.fc2.com/blog-entry-81.html


関連記事

コメント

コメントの投稿

広告

プロフィール

石河 純


著者名 :石河 純
自己紹介:素人上がりのIT技術者。趣味は卓球・車・ボウリング

IT関連の知識はざっくりとこんな感じです。
【OS関連】
WindowsServer: 2012/2008R2/2003/2000/NT4
Windows: 10/8/7/XP/2000/me/NT4/98
Linux: CentOS RedHatLinux9
Mac: macOS Sierra 10.12 / OSX Lion 10.7.5 / OSX Snow Leopard 10.6.8
【言語・データベース】
VB.net ASP.NET C#.net Java VBA
Xamarin.Forms
Oracle10g SQLServer2008R2 SQLAnywhere8/11/16
ActiveReport CrystalReport ReportNet(IBM)
【ネットワーク関連】
CCNP シスコ技術者認定
Cisco Catalyst シリーズ
Yamaha RTXシリーズ
FireWall関連
【WEB関連】
SEO SEM CSS IIS6/7 apache2

休みの日は卓球をやっています。
現在、卓球用品通販ショップは休業中です。