2016年11月15日

[Unity] AWS Mobile SDK for Unity で、iPhoneで実行時エラー(NullReferenceException)が出る

AWSの一部のサービスをUnityから動かせるSDKが出ています。

AWS Mobile SDK for Unity:
https://docs.aws.amazon.com/mobile/sdkforunity/developerguide/

サンプルプログラムが添付されているので
これは便利だということで利用し始めました。

しかし、AWS S3 のサンプルを動かそうとしたときに
Unityエディタから動きませんでした。

Unityエディタで動かすには、

AWSConfigs.HttpClient = AWSConfigs.HttpClientOption.UnityWebRequest;

の一行が必要でした。

[参考] AWS Mobile SDK for Unityを使ってサーバーレスなアプリを開発する:
http://nil-one.com/blog/article/2016/04/14/AWS_Mobile_SDK_for_Unity/

これで安心、と思いきや、実機で実行したところ
NullReferenceException
が出てしまいました↓


NullReferenceException: A null value was found where an object instance was required.
at Amazon.Runtime.Internal.DownloadHandlerBufferWrapper..cctor () [0x00000] in :0
at Amazon.Runtime.Internal.UnityMainThreadDispatcher+d__7.MoveNext () [0x00000] in :0
at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00000] in :0
at Amazon.Runtime.Internal.UnityMainThreadDispatcher.ProcessRequests () [0x00000] in :0
at Amazon.Runtime.Internal.UnityMainThreadDispatcher.Update () [0x00000] in :0
Rethrow as TypeInitializationException: The type initializer for 'Amazon.Runtime.Internal.DownloadHandlerBufferWrapper' threw an exception.
at Amazon.Runtime.Internal.UnityMainThreadDispatcher+d__7.MoveNext () [0x00000] in :0
at UnityEngine.SetupCoroutine.InvokeMoveNext (IEnumerator enumerator, IntPtr returnValueAddress) [0x00000] in :0
at Amazon.Runtime.Internal.UnityMainThreadDispatcher.ProcessRequests () [0x00000] in :0
at Amazon.Runtime.Internal.UnityMainThreadDispatcher.Update () [0x00000] in :0
Amazon.Runtime.Internal.UnityMainThreadDispatcher:ProcessRequests()
Amazon.Runtime.Internal.UnityMainThreadDispatcher:Update()


原因は、実機で動かす時に必要な「link.xml(UnityプロジェクトのResourcesディレクトリに入れる)」
の記載が Unity5.4 から変更があったようでした。

[公式]AWS Mobile SDK for Unity セットアップの仕方:
https://docs.aws.amazon.com/mobile/sdkforunity/developerguide/setup-unity.html

公式ドキュメントにはlink.xmlは

<assembly fullname="UnityEngine">
<type fullname="UnityEngine.Experimental.Networking.UnityWebRequest" preserve="all" />
……

と記載されていますが、Unity5.4以降は「Experimental」を削除した

<assembly fullname="UnityEngine">
<type fullname="UnityEngine.Networking.UnityWebRequest" preserve="all" />
……

が正しいようです。

[参考]iOS: NullReferenceException: A null value was found where an object instance was required. #435:
https://github.com/aws/aws-sdk-net/issues/435

この修正をしたところ、実機でも無事AWS S3にファイルをアップロード/ダウンロードできるように
なりました。

公式ドキュメントを信じていたので、痛い目にあいました。
この解決方法を見つけた人って凄いなー。
posted by be-style at 08:00| Comment(0) | Unity

2016年09月01日

[iOS] ITMS-90617 が出て、iTunes Connect にアップロードできない

・macOS Sierra (10.12 Beta) (16A313a)
・Xcode7.3.1

でビルドして、アーカイブまでは成功。
でも、アップロードしようとすると ITMS-90617 のエラーが出てしまいました。

スクリーンショット 2016-09-01 22.25.08.png

理由は、macOS Sierra だからのようです。

参考:
http://stackoverflow.com/questions/37838487/error-itms-90167-no-app-bundles-found-in-the-package

困ったなー。

追記:
Xcode 8 Betaでビルドしたらうまくいきました。
Beta版だけど、審査大丈夫かなー。

追記:
審査以前に、iTunes Connectにアップした後に審査ボタンを押したら
Beta版ではダメというメッセージが出て申請できませんでした。
もっと早い段階で言って!

スクリーンショット 2016-09-02 1.05.56.png

追記:
OrganizerでExportして、Application Loaderでアップロードを試みましたが、
ダメでした。


アーカイブファイルの中身開いてinfo.plistを書き替える方法で上手くいったという情報があるけど、
怖くて真似できない。。。
https://forums.developer.apple.com/thread/49004


開発者用の「macOS Sierra Developer Beta」じゃなくて
一般公開されている「macOS Sierra Public Beta」を試してみよう。

macOS Sierra Public Beta:
https://beta.apple.com/sp/ja/betaprogram/welcome?locale=ja

ダメだったので、macのOSをsierra以前のもの(EI Capitan)に戻すことにしました。
https://www.macxdvd.com/blog/smart-how-to-downgrade-macos-10-12-sierra.htm

そして、やっとITCにアップロードできました!

スクリーンショット 2016-09-03 23.07.42.png

長かった。。。
EI Capitan に戻す前に、タイムマシーンで保存した後に作業した分を
きっちりバックアップとっておいて、EI Capitan に戻した後にプログラム等を
更新することをお忘れなく。

無事、アップルの審査にも提出できました。

今後、β版にするときは、申請の予定がないときにしよう。。。
今回で懲りました。
タグ:Xcode SIERRA MacOS
posted by be-style at 22:31| Comment(0) | iOS

2016年08月30日

[Web] AWS Lambda から DynamoDB にアクセスしてアイテムを更新してみた

前回の[Unity] AWS Lambda をUnityから実行してみた(iPhoneから実行も)で、iPhoneからAWS Lambdaにアクセスすることができました。

今回は、この3点をやってみます。
・管理画面からDynamoDBにアイテムを追加する
・LambdaからDynamoDBにアクセスする(node.js)
・DynamoDBのアイテムを更新する


Lambdaでnode.jsを使って色々できるとなったら、Lambdaが動いているサーバー上に
記録を残したいときがあります。
memocached や ファイル書き出し等はできないようです。

そこで、永続的にデータを保存できるAWSサービスのRDBとDynamoDBを考えました。
今回は、後々データが増えたときに扱いやすそうなDynamoDBを触ってみます。

DynamoDB の基礎知識とまとめ:
http://qiita.com/hshimo/items/e5ad98b21786d796f1da


AWSの管理画面から、サービス > データベース > DynamoDB を選択します。

dynamo_1.png


はじめてDynamoDBを触ったときの画面になります。
Create table
を選びます。

dynamo_2.png


テーブルの設定画面になります。

・テーブル名 : Test
・プライマリキー : key1(文字列)
・デフォルト設定の使用 : オフ
・セカンダリインデックス : なし
・プロビジョニングされたキャパシティ 読み込み/書き込み容量ユニット : 1

にして"作成"を押します。

dynamo_3.png


テーブルができました!

dynamo_4.png


それでは項目(アイテム)を追加してみましょう。
画面右の"項目"メニュー > 項目の作成 を選びます。

dynamo_5.png


項目の作成画面に移るので、プライマリキーに"aaa"を入力します。

dynamo_6.png


要素を追加するので、"+"ボタン > Append > String を選びます。

dynamo_7.png


key2 として、値に vvv を入力します。
その後、画面右下の"保存"を押します。

dynamo_8.png


テーブルに項目が追加されました。

dynamo_9.png


AWS LambdaからDynamoDBにアクセスするために、ロールの設定の変更が必要になります。
ここで、作成したテーブルの"Amazonリソースネーム(ARN)"をコピーして覚えておきます。

dynamo_10.png


サービス > IAM の画面に移り、ロールの画面を開きます。
前回のhelloWorldで使ったロール(Cognito_AllZeroPuzzleUnauth_Role)を開きます。

dynamo_10_1.png


インラインポリシー > ロールポリシーの作成 を選びます。

dynamo_11.png


"選択"を押します。

dynamo_12.png


アクセス許可の編集画面になりますので、
・AWSサービス : Amazon DynamoDB
・アクション : Scan, UpdateItem
・ARN : 先ほどコピーしたARN

を設定して、"ステートメントを追加"を押します。

dynamo_13.png

dynamo_14.png


ステートメントの内容を確認(Scan, UpdateItemがある)して、"次のステップ"を押します。

dynamo_15.png


ポリシーの確認画面では特になにもせず"ポリシーの適用"を選びます。

dynamo_16.png


ポリシー一覧の画面に戻ると、先ほど作ったポリシーが追加されています。

dynamo_17.png


サービス > AWS Lambda の画面に移り、以前作成した helloWorld を選びます。

dynamo_18.png


以前のプログラムを、DynamoDB用に書き換えます。

node.jsによるLambda操作のサンプル
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/gettingstartedguide/GettingStarted.NodeJs.03.html

var AWS = require("aws-sdk");
var dynamo = new AWS.DynamoDB.DocumentClient();

exports.handler = function(event, context) {
var param = {
TableName : "Test",
FilterExpression : "key1 = :val",
ExpressionAttributeValues : {":val" : "aaa"}
};
dynamo.scan(param, function(err, data) {
if (err) {
console.log("エラー = " + err);
context.fail(err); // エラー時
} else {
console.log("成功 = " + data);
context.succeed(data); // 正常時
}
});
};

dynamo_19.png


管理画面で実行してみると、DynamoDBの項目の中身を取得できました。

dynamo_20.png


では、key2 の "vvv" を "moji" に置き換えてみましょう。
Lambdaのプログラムを変更します。

var AWS = require("aws-sdk");
var dynamo = new AWS.DynamoDB.DocumentClient();

exports.handler = function(event, context) {
var params = {
TableName: 'Test',
Key: {
"key1": "aaa" // Hashキー
},
AttributeUpdates: {
"key2": {
'Action': 'PUT', // 置き換え
'Value': "moji" // 文字列
}
}
};
dynamo.update(params, function (err, data) {
if (err) {
console.log("失敗" + err);
} else {
console.log("成功");
}
});
};


dynamo_21.png


実行すると、"成功"と出たので、置き換えがうまくいったようです。

dynamo_22.png


サービス > DynamoDB の画面に移り、先ほど作成した Testテーブルの中身を確認すると、
ちゃんと更新されていました。

dynamo_23.png


これで、これからアプリに追加する機能に必要なことは揃いました。
よかったよかった。
posted by be-style at 21:37| Comment(0) | Web