3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Xamarin で manifestPlaceHolders もどきの環境変数展開

Last updated at Posted at 2018-03-17

こんにちは、豚野郎です。 Xamarin 素敵ですね。XAMLでレイアウト組めるので、MVVMでのアプリ開発が捗ります。

さて、 アプリ開発をしていると、Twitterログインや広告を追加したくなります。
これらにはAPIキーをコードに埋め込む必要がありますが、当然リポジトリの管理化には置きたくありません。
Android では、 manifestPlaceHolders を使用してビルド時に挿入する事が可能ですが、どうググっても VisualStudio にはそのような素敵機能が見当たりません…。
とはいえ、APIキーを管理するクラスを .gitignore に埋め込むのは、クローン直後にビルドエラーになるためなんだかいやです。
できるならば manifestPlaceHolders のようにビルド時に挿入したいです。
標準機能で提供されていないので、ビルドイベントでファイル内の文字列を置換する事で実現してみようと思います。

対象ファイルに置換用文字列を埋め込む

Environment.cs
public class Environment
{
    /// <summary>
    /// Twitter API の API KEY を取得します
    /// </summary>
    public string TwitterConsumerKey { get; } = "${TWITTER_CONSUMER_KEY}";

    /// <summary>
    /// Twitter API の API SECRET KEY を取得します
    /// </summary>
    public string TwitterConsumerSecretKey { get; } = "${TWITTER_CONSUMER_SECRET_KEY}";
}

${TWITTER_CONSUMER_KEY}${TWITTER_CONSUMER_SECRET_KEY} が置換用の文字列です。
ビルド時に上記の文字列を環境変数に定義された文字列に置換します。

Windows 環境用置換スクリプトを作成する

replace.bat
@echo off

set outpath=%1
set inpath=%outpath%.work
set before=%2
set after=%3

copy /Y %outpath% %inpath%
type nul > %outpath%
setlocal enabledelayedexpansion
for /f "tokens=1* delims=: eol=" %%a in ('findstr /n "^" %inpath%') do (
  set line=%%b
  if not "!line!" == "" (
    set line=!line:%before%=%after%!
  )
  echo.!line!>> %outpath%
)
endlocal

del /Y %inpath%
exit /B 0

Windows には sed コマンドが存在しない為、 bat ファイルで代替します。
第一引数のファイル内に、第二引数で指定された文字列が存在する場合、第三引数で指定された文字列に置換します。
スクリプトは こちら を参考にさせて頂きました。

プロジェクトに PreBuildEvent と PostBuildEvent を埋め込む。

Example.csproj
<Project>
  ... 中略 ...
  <PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
    <PreBuildEvent>
      copy /Y $(ProjectDir)Environment.cs $(ProjectDir)Environment.cs.bak
      call $(ProjectDir)replace.bat $(ProjectDir)Environment.cs ${TWITTER_CONSUMER_KEY} $(TWITTER_CONSUMER_KEY)
      call $(ProjectDir)replace.bat $(ProjectDir)Environment.cs ${TWITTER_CONSUMER_SECRET_KEY} $(TWITTER_CONSUMER_SECRET_KEY)
    </PreBuildEvent>
    <PostBuildEvent>move /Y $(ProjectDir)Environment.cs.bak $(ProjectDir)Environment.cs</PostBuildEvent>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(OS)' != 'Windows_NT' ">
    <PreBuildEvent>
      source ~/.bash_profile
      cp $(ProjectDir)Environment.cs $(ProjectDir)Environment.cs.bak
      sed -i '' 's/${TWITTER_CONSUMER_KEY}/'$TWITTER_CONSUMER_KEY'/g' $(ProjectDir)Environment.cs
      sed -i '' 's/${TWITTER_CONSUMER_SECRET_KEY}/'$TWITTER_CONSUMER_SECRET_KEY'/g' $(ProjectDir)Environment.cs
    </PreBuildEvent>
    <PostBuildEvent>mv $(ProjectDir)Environment.cs.bak $(ProjectDir)Environment.cs</PostBuildEvent>
  </PropertyGroup>
</Project>

PreBuildEvent にて、環境変数をコード中に存在する特定文字列を置換する事で、ビルド時の環境変数展開を実現しています。
また、誤って環境変数が展開されたソースコードを git にコミットしない為に、 PreBuildEvent にて作成したバックアップファイルを PostBuildEvent で元ファイルに上書きしています。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?