ページ「Xamarin.Mac/NSApplicationのサブクラスを使う」と「Xamarin.MacでNLogを使う」の間の差分

提供: MonoBook
< Xamarin.Mac(ページ間の差分)
ナビゲーションに移動 検索に移動
(153.174.184.145 (トーク) による版 6178 を取り消し)
 
imported>Administrator
(Administrator がページ「Xamarin.Mac/NLogを使う」を「Xamarin.MacでNLogを使う」に移動しました)
 
1行目: 1行目:
[[MonoMac]]および[[Xamarin.Mac]][[AppKit]]のNSApplicationのサブクラスを利用したい場面もあることだろう。多くの場合はNSApplicationDelegateで事足りるだろうが、稀にすべてのイベントをトラップしたい場面などではNSApplicationのサブクラスを作る必要がある。
+
[[Xamarin.Mac]]でも[[NLog]]を使えると捗る。
  
 
==実装1==
 
==実装1==
===NSApplicationのサブクラスを作る===
+
[[Xamarin.Mac]]でも[[NLog]]はなんら問題なく使用できる。[[NuGet]]から一発[[インストール]]である。試してはいないが[[MonoMac]]でも同じだと思う。
Register属性で指定した名前は後ほどInfo.plistで利用される。凄く重要。クラス名と同じにしておくと紛らわしくないと思われる。
 
  
NSApplicationがデフォルトコンストラクタを持たない関係でサブクラスにもコンストラクタがないと[[コンパイル]]が通らないが、[[デバッガ]]で追ってみた限りでは呼ばれている気配はない。そのためAwakeFromNibメソッドをオーバーライドして初期化している。これでいいのかは知らん。
+
ただし[[ファイル]]に出力する場合に注意が必要で、[[Mac OS X]]ではあらゆる[[ファイル]]は[[アプリ]]の外部に保存する必要があるため、NLog.configファイルの設定例でよく見かける「basedir変数」以下に書き込む設定は使えない。
<source lang="csharp">
 
    using System;
 
  
    using Foundation;
+
===ファイルに出力するNLog.configの設定例===
    using AppKit;
+
そこで以下の例では[[Mac OS X]]では定番の「~/Library/Logs/」以下に出力してみた。
  
    [Register("App")]
+
<source lang="xml">
    public class App : NSApplication
+
<?xml version="1.0" encoding="utf-8" ?>
    {
+
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
        public App(IntPtr handle) : base(handle) {}
+
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 +
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
 +
      autoReload="true"
 +
      throwExceptions="false"
 +
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log" >
  
        public App(NSCoder coder) : base(coder) {}
+
  <variable name="appname" value="monobook"/>
  
        /// <summary>
+
  <targets>
        /// 初期化はAwakeFromNibのタイミングでいいのか?
+
    <target xsi:type="File" name="logfile"
        /// 調査中
+
    fileName="${specialfolder:folder=MyDocuments}/Library/Logs/${appname}/${shortdate}.log"
        /// </summary>
+
        layout="${longdate} ${uppercase:${level}} ${message}" />
        public override void AwakeFromNib()
 
        {
 
            base.AwakeFromNib();
 
            this.Delegate = new AppDelegate();
 
        }
 
  
        /// <summary>
+
    <target xsi:type="Console" name="console" />
        /// こいつをオーバーライドすればほぼ全てのイベントが取れる
 
        /// </summary>
 
        /// <param name="theEvent">The event.</param>
 
        public override void SendEvent(NSEvent theEvent)
 
        {
 
            base.SendEvent(theEvent);
 
        }
 
    }
 
</source>
 
 
 
===Info.plistに「Principal class」を設定する===
 
Info.plistを開き、Xamarin Studio下部の「ソース」タブを選択する。Info.plistがない場合はファイルを追加する(新規追加ダイアログでは「Application Manifest」という名称になっているはず)。
 
 
 
プロパティの一覧が列挙されるので、プロパティ「Principal class」に「String」型で前述のRegister属性で付けた名前を入力する(この例であれば「App」)。プロパティ「Principal class」がない場合はリスト下部の「Add new entry」を選べば新しい行が追加される。
 
  
===エントリポイントを書き換える===
+
  </targets>
Xamarin Studioで「空のプロジェクト」を作ると初期値でこんな感じになっている。
 
<source lang="csharp">
 
    static class MainClass
 
    {
 
        static void Main(string[] args)
 
        {
 
            NSApplication.Init();
 
  
            var application = NSApplication.SharedApplication;
+
  <rules>
            application.Delegate = new AppDelegate();
+
    <logger name="*" minlevel="Trace" writeTo="logfile" />
            application.Run();
+
    <logger name="*" minlevel="Info"  writeTo="console" />
        }
+
  </rules>
    }
+
</nlog>
 
</source>
 
</source>
 +
NLogに設定するパスは[[絶対パス]]なので、ホームディレクトリのパスの取得は「[[MonoMac/特殊ディレクトリのパスを取得する]]」を用いてMyDocumentsを指定することで取得した。
  
 +
また、NLog.config中でアプリ名を動的に取得する方法がわからなかったので、この例では自前でappname変数を用意している。
  
これを以下のように書き換える。なお「空のプロジェクト」ではなく「Cocoa」を選ぶと最初からこうなっている。
+
===備考===
<source lang="csharp">
+
NLog.configは初期状態でビルド時にコピーされない設定になっていると思うので修正するのを忘れないこと。NLog.configファイルのプロパティの「出力ディレクトリにコピー」の値を「新しい場合のみコピー」または「常にコピー」に設定する。
    using System;
 
    using AppKit;
 
  
    static class MainClass
+
===不具合===
    {
+
これは2015年8月3日の情報です。
        static void Main(string[] args)
+
[[Xamarin.Mac]]において「Debugビルド」を行うとアプリ内(***.app内)のMonoBundleディレクトリにNLog.configファイルが生成(コピー)されるが、「Releaseビルド」では生成されないようだ。たぶん[[不具合]]だと思う。
        {
 
            NSApplication.Init();
 
            NSApplication.Main(args);
 
        }
 
    }
 
</source>
 
  
 
==関連項目==
 
==関連項目==
 +
*[[MonoMac/特殊ディレクトリのパスを取得する]]
  
 
==参考文献==
 
==参考文献==
84行目: 54行目:
 
{{stub}}
 
{{stub}}
  
[[category:Xamain.Mac]]
+
[[category:Xamarin.Mac]]
 
[[category:MonoMac]]
 
[[category:MonoMac]]

2019年5月22日 (水) 05:13時点における最新版

Xamarin.MacでもNLogを使えると捗る。

実装1[編集 | ソースを編集]

Xamarin.MacでもNLogはなんら問題なく使用できる。NuGetから一発インストールである。試してはいないがMonoMacでも同じだと思う。

ただしファイルに出力する場合に注意が必要で、Mac OS Xではあらゆるファイルアプリの外部に保存する必要があるため、NLog.configファイルの設定例でよく見かける「basedir変数」以下に書き込む設定は使えない。

ファイルに出力するNLog.configの設定例[編集 | ソースを編集]

そこで以下の例ではMac OS Xでは定番の「~/Library/Logs/」以下に出力してみた。

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log" >

  <variable name="appname" value="monobook"/>

  <targets>
    <target xsi:type="File" name="logfile" 
    	fileName="${specialfolder:folder=MyDocuments}/Library/Logs/${appname}/${shortdate}.log"
        layout="${longdate} ${uppercase:${level}} ${message}" />

    <target xsi:type="Console" name="console" />

  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="logfile" />
    <logger name="*" minlevel="Info"  writeTo="console" />
  </rules>
</nlog>

NLogに設定するパスは絶対パスなので、ホームディレクトリのパスの取得は「MonoMac/特殊ディレクトリのパスを取得する」を用いてMyDocumentsを指定することで取得した。

また、NLog.config中でアプリ名を動的に取得する方法がわからなかったので、この例では自前でappname変数を用意している。

備考[編集 | ソースを編集]

NLog.configは初期状態でビルド時にコピーされない設定になっていると思うので修正するのを忘れないこと。NLog.configファイルのプロパティの「出力ディレクトリにコピー」の値を「新しい場合のみコピー」または「常にコピー」に設定する。

不具合[編集 | ソースを編集]

これは2015年8月3日の情報です。 Xamarin.Macにおいて「Debugビルド」を行うとアプリ内(***.app内)のMonoBundleディレクトリにNLog.configファイルが生成(コピー)されるが、「Releaseビルド」では生成されないようだ。たぶん不具合だと思う。

関連項目[編集 | ソースを編集]

参考文献[編集 | ソースを編集]