頭ん中

しがないITエンジニアが、考えた事を書きます。

HARUMI FLAGを諦めた話

僕が "晴海" という場所を知ったのは、中学生の時だったと思う。

小沢健二「いちょう並木のセレナーデ」のフレーズに出てくる、晴海ふ頭という地名を聴いた時だ。

続きを読む

Uno PlatformのWebAssemblyでゲームを作る

Uno PlatformのWasmを試していて、タイピングみたいな簡単なゲームならできるかも?と思って完成したのがこれ。

https://typeratta.azurewebsites.net/

f:id:siamcats:20200601094526g:plain

ちなみにUWP版はこんな感じです。コードはSharedプロジェクト内にしか書いてないので、ほぼワンコードで同じ動作をするアプリのデスクトップ版・Web版ができました。 f:id:siamcats:20200601022550g:plain

コードはGitHubに。 github.com

以降、Wasmで動作させる時のポイントというか躓いたとこをいくつか。

続きを読む

API GatewayとLambdaでバイナリデータを扱う

画像などのバイナリデータをアップロードするREST APIを作ります。詳細はAmazon API Gateway 開発者ガイドのバイナリペイロードをサポートするという章を読むこと。バイナリの扱いにちょっと戸惑ったのでメモ。

前提

  • API GatewayとLambdaの基本的な設定内容は省略

API Gateway

バイナリメディアタイプ

API GatewayはデフォルトではテキストペイロードUTF-8エンコードされた JSON)として扱うため、バイナリペイロードで扱う場合は、API設定からバイナリメディアタイプを指定し、バイナリとして扱うContent-Typeを設定します。

今回はmp3をアップしたいのでaudio/mpegを指定

マッピングテンプレート

さっきの手順でバイナリペイロードとして扱うことにはなったんですが、そのままバックエンド(Lambda)までバイナリで渡せるのかなと思ったら、違ってた。

API Gatewayは、統合リクエスト本文マッピングテンプレートの設定で、バックエンドへの渡し方を決められます。ここでContent-Type:audio/mpegについてパススルーすれば、Lambdaにバイナリで渡るのかなと試したのですが、エラー。

{"message": "Could not parse request body into json: Unexpected character (\'\/\' (code 47)): maybe a (non-standard) comment? (not recognized as one since Feature \'ALLOW_COMMENTS\' not enabled for parser)\n at [Source: (byte[])\"\/9j\/4AAQSkZJRgABAQEASABIAAD\/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT\/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT\/wAARCAEqASwDASIAAhEBAxEB\/8QAHQABAAEFAQEBAAAAAAAAAAAAAAgBAgYHCQUEA\/\/EAEgQAAEDAwMDAgMFBQQHBQkAAAEAAgMEBREGByEIEjETQSJRYQkUMnGBFSNCkaEWUrHBFyYzYnKCkiRz0eHxJTRTY4OUo7Lw\/8QAHQEBAAEFAQEBAAAAAAAAAAAAAAECAwQFBgcICf\/EAC8RAQABAwMCAwYGAwAAAAAAAAABAgMEBREhMUEGBxITQlFhcYEUFZGhscEiM+H\/2gAMAwEAAhEDEQA\/\"[truncated 17128 bytes]; line: 1, column: 2]"}

結局どうやってもAPI GatewayからLambdaへはJSONオブジェクトで渡ることになるので、テキストとして処理しないと駄目みたいです。というこで、統合リクエストLambdaプロキシ統合の設定にチェックをしれて、ややこしいマッピングテンプレートの設定は省略します。

Lambda

API Gatewayからはbodyがbase64エンコードされたいつものJSONオブジェクトが来るので、それをデコードして処理します。簡単にS3に置くようなプログラムを実装すると以下。

bucket = 'xxxx'
s3 = boto3.resource('s3')

def lambda_handler(event, context):
    print(event)
    
    if event['isBase64Encoded']:
        date = datetime.datetime.now().strftime('%Y%m%d-%H%M%S')
        key = date + '.mp3'
        print(key)
        
        decode = base64.b64decode(event['body'])
        
        obj = s3.Object(bucket,key)
        res = obj.put(
            Body=decode,
            ContentType='audio/mpeg'
            )
        
        print(res)
        
        return {
            'statusCode': 200,
            'body': json.dumps(
                {
                    'message': 'uploaded.',
                    'file': key
                }
            ),
            'isBase64Encoded': False
        }
    else:
        return {
            'statusCode': 400,
            'body': json.dumps(
                {
                    'message': 'not binary file'
                }
            ),
            'isBase64Encoded': False
        }

参考にしたサイト

UWPでローカルDBのマイグレーションをする(EntityFramework Core / SQLite)

まえがき

ちょっと昔のAndroidアプリやWindowsアプリで、分岐とDDL文を散りばめたギリギリの運用を目にすることが結構ありました。

ローカルDBとテーブルをCodeFirstに生成し、とりあえずデータをCRUDする方法が紹介された記事は一杯ありますが、アプリをアップデートする際のマイグレーションまで解説されたドキュメントは、あまりないんですよね。

ということで、たぶん現在もっとも標準的と思われるWindowsアプリの構成(UWP / EntityFramework Core / SQLite)で、ローカルDBのマイグレーションを試していきたいと思います。

続きを読む

Uno Platformを試す

XAMLひとつでWindows/iOS/Android/WebAssemblyに対応という夢のような話です。 f:id:siamcats:20200206025122p:plain

Create a Single Page App with Uno

既にチュートリアルのやってみた系記事はあるので、いくつか躓いたところと、良くあるXAMLのデザインテンプレートが実際どんな感じになるか紹介したいと思います。

続きを読む

UWPクライアントから社内プロキシ認証を超えてREST APIを叩くのに嵌った

(ほんといちいちいちいち厄介な社内プロキシ)

f:id:siamcats:20200130192353p:plain

マニュフェストに忘れずチェックいれて

// using Windows.Web.Http;
var httpClient = new HttpClient();
var uri = new Uri("https://contoso.com/GetApi");
var response = await httpClient.GetAsync(uri);

こんな感じで叩けば

f:id:siamcats:20200130185243p:plain

おなじみの認証ダイアログが勝手に出てきてくれるじゃないですか。

でもなんかよくわかんない例外になる時があるんです。

"Exception from HRESULT: 0x80072EF3"
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()

よくよく調べてるとアプリ起動後に最初に叩くリクエストがPOSTの時だけ起きてるみたいなんですよね。

var httpClient = new HttpClient();
var uri = new Uri("https://contoso.com/PostApi");
var content = "hogehogebody";
var response = await httpClient.PostAsync(uri,content);

なので適当にGETメソッドのリクエストを投げ認証させておいて、それからPOSTのAPIを叩けば普通にいけました。うーん…。