WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

MacでC#を書いてみよう(実践編)

今回のエンジニアブログ担当の岩原です。
今回は、前回の続きである「MacでC#を書いてみよう(実践編)」です。

前回、

インストールは結構簡単に出来ました。 しかし、実行やデバッグは少し手間がかかります。 次回はその辺りを書きたいと思います。

と書きましたが、バージョンアップによって簡単になったため、実践編に入ります。

まずはNuGetのインストールから行います。
VisualStudioを使っている方にはお馴染みのパッケージマネージャです。
Xamarinでも使えるので入れておきます。
これでライブラリ管理を楽にしましょう。

初めに、Xamarinを起動し、「Xamarin Studio」→「アドイン マネージャ」を選択します。
次にギャラリータブを選択し、リポジトリのコンボボックスをクリックします。
01_NuGetOpen

コンボボックスの中から「Manage Repositories」を選択します。
02_NuGetManage

リポジトリ管理画面の追加ボタンをクリックします。
03_NugetBefore

NuGetのリポジトリのURLを入力します。
URLは「http://mrward.github.com/monodevelop-nuget-addin-repository/4.0/main.mrep」です。
04_NugetUrl

リポジトリが追加されたことを確認し、リポジトリの管理画面を閉じます。
05_NugetAfter

それではNuGetをインストールしましょう。
「IDE extensions」をクリックし、内容を表示します。
06_NugetInstall

「NuGet Package Management」を選択し、インストールボタンをクリックします。
07_NugetLetsInstall

確認ダイアログでインストールボタンをクリックします。
07-01_NugetInstallConfirm

インストールのプログレスバーが表示されるので、終わるまで待ちます。
07-02_NugetInstalling

インストールが完了すると、ダイアログが自動的に閉じられ、アドインマネージャの画面でインストールされたことが分かるマークが付きます。
07-03_NugetInstalled

アドインマネージャ画面を閉じ、ソリューションの「New」をクリックします。
08_Restert

新しいソリューション画面にて、今回作成するアプリの種類を選択していきます。
今回作成するアプリは、ありきたりなHello Worldではなく、少し手間をかけたいと思うので、
Amazon AWS S3のバケットからファイル一覧を取得するコードを書きたいと思います。

コードを書く前に以下の値が必要になるため、事前に準備が必要です。
確認の方法はAmazon AWSのサイトを確認して下さい。

・Access Key ID
・Secret Access Key
・対象のバケット名

セキュリティを考慮すると、S3のみへのアクセス権限を持つIAMユーザーを作成し、そのIAMユーザーのAccess Key IDとSecret Access Keyを使う方が望ましいかと思います。
IAMユーザーは、AWSマネジメントコンソールのIAMから作成できます。

では、コードを書いていきましょう。
まずは、S3からファイル一覧を取得するクラスを作成します。
今後の拡張を考え、クラス名は「S3Accesser」としましょう。

S3が返すファイルの一覧は、ページングされているため、
次頁取得処理などが必要になります(ソース上のB)。

ListObjectsResponseクラスのNextMarkerプロパティは、
次頁の開始点を返します。
このプロパティが空の場合、次頁がないと判断できます(ソース上のA)。

using System;  
using Amazon;  
using Amazon.S3;  
using Amazon.S3.Model;  
using System.Collections.Generic;  
using Amazon.S3.Transfer;  
using System.IO;  
  
namespace BlogNeta  
{  
    public class S3Accesser  
    {  
        private IAmazonS3 s3;  
  
        private string bucketName = "";  
  
        public S3Accesser (string key, string secret, string bucketName)  
        {  
            s3 = AWSClientFactory.CreateAmazonS3Client (key, secret, RegionEndpoint.APNortheast1);  
            this.bucketName = bucketName;  
        }  
  
        public List<string> GetFileNames()  
        {  
            List<string> list = new List<string> ();  
  
  
            var listObjectRequest = new ListObjectsRequest();  
            listObjectRequest.BucketName = this.bucketName;  
  
            ListObjectsResponse response = null;  
  
            while(true){  
  
                response = s3.ListObjects(listObjectRequest);  
                foreach (var item in response.S3Objects)  
                {  
                    list.Add (item.Key);  
                }  
                //A:次頁がなければ終わり  
                if (string.IsNullOrEmpty(response.NextMarker)) {  
                    break;  
                }  
                //B:次頁開始点を設定  
                listObjectRequest.Marker = response.NextMarker;  
  
            }  
  
            return list;  
        }  
    }  
}

今度はメイン関数です。
.NET感を出すために、Parallelクラスを使ってます。特に意味はありません。
変数key、secret、bucketNameには、それぞれAccess Key ID、Secret Access Key、バケット名を設定してください。

また、C#では、文字列の前に@(アットマーク)をつけると、文字列をエスケープしなくても大丈夫なようになります。
(ダブルクォーテーションなど)

using System;  
using Amazon;  
using Amazon.S3;  
using Amazon.S3.Model;  
using System.Collections.Generic;  
using System.Threading.Tasks;  
  
namespace BlogNeta  
{  
    class MainClass  
    {  
        public static void Main (string[] args)  
        {  
            Console.WriteLine ("Hello World!");  
            string key = @"Access Key IDを設定してください";  
            string secret = @"Secret Access Keyを設定してください";  
            string bucketName = @"バケット名を設定してください";  
            S3Accesser accesser = new S3Accesser (key, secret, bucketName);  
  
            List<string> list = accesser.GetFileNames ();  
            //Parallelsを使用してみる  
            Parallel.ForEach (list, item => {  
                Console.WriteLine(item);  
            });  
        }  
    }  
}  

上記コードをすべて書いたら、デバッグ実行しましょう。
16_Debug

ビルドエラーが発生した場合は、どこか間違っています。
実行時に以下の様な例外が発生した場合は設定したAccess Key ID、Secret Access Key、バケット名が間違っているか、そのバケットを閲覧する権限がありません。
15_Exception

問題なく実行できた場合は、対象バケットのファイルの一覧がコンソールに出力されます。
なお、コード中にパスワード的な文字列(今回で言えばSecret Access Key)を直接書いてしまうのはセキュリティ的にオススメできません。
設定ファイルを持つなり、実行時引数に指定するなりしたほうが良いかと思います。