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

2016年08月28日

[Unity] AWS Lambda をUnityから実行してみた(iPhoneから実行も)

前回の [Web] AWS Lambda のHello Worldをやってみた の続きです。

前回は管理画面からAWS Lambdaを動かしました。
今回の目標はこの2つです。
・UnityからAWS Lambdaを動かしてみる
・Unityで作ったアプリをiPhoneで実行してAWS Lambdaを動かしてみる

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

上記の参考ページにもありますが、"AWS Mobile SDK for Unity"を使います。

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

SDKの対象にAWS Lambdaがありますね。
そして、Amazon Cognito も対象になっている点がポイントです(後述)。

はじめに、AWS Mobile SDK for Unityを上記のURLからダウンロードします。

lambda2_1.png


Unityで新規プロジェクトを作成します。
ここでは、LambdaTest という名前にして、2Dで作成します。

lambda2_3.png


Unityでプロジェクトが作成できたら、先ほど解凍した中から
AWSSDK.Lambda.3.1.4.7.unitypackage
をWクリックしてUnityにすべてインポートします。

lambda2_2.png

lambda2_4.png


UnityのBuildSettings(Ctrl+Shift+B)では、iOSにSwitchPlatformしておきます。

lambda2_5.png


ProjectウィンドウのAssets > Examples > LambdaExampleシーン をWクリックして
サンプルシーンを開きます。

lambda2_6.png


Gameウィンドウにプレビューが表示されるのですが、
カメラが配置されていないために警告(No cameras redering)が出ます。

lambda2_7.png


再生ボタンを押すと実行はされますが、気持ち悪いのでシーンにカメラを追加します。
Hierarchyウィンドウで右クリック > Camera でカメラを追加すると警告は消えます。

lambda2_8.png


カメラが追加された後のHierarcyウィンドウです。

lambda2_9.png


先ほど、再生ボタンを押せば実行されると書きましたが、実行はされますが
ボタンを押しても何も反応しません。
理由は、Lambdaオブジェクトに本来適用されているスクリプトが抜け落ちているからです!

lambda2_10.png


Assets > Examples > LambdaExample(C#ファイル) を先ほどのLambdaオブジェクトに
適用します。
すると、AWS Lambdaを使用するために必要なパラメーターが表示されます。

重要なのは、この3つです。
・Identity Pool Id
・Cognito Identity Region
・Lambda Region

lambda2_11.png


はじめに挙げた「AWS Mobile SDK for Unityを使ってサーバーレスなアプリを開発する」の
ページにもありますが、AWS Mobile SDK for Unity を使用するためには"Cognito"という
サービスを利用する必要があります。

Amazon Cognito:
https://aws.amazon.com/jp/cognito/

このユーザーのサインイン機能を使って、UnityからAWS Lambdaにアクセスするようです。
Unityの作業は一旦ここで止めて、Cognitoサービスを利用してみましょう。

AWSの管理画面のサービスから、Cognitoを選びます。
※管理画面の作業は、すべて"東京リージョン"での作業です!!

lambda2_12.png


"Manage Federated Identities"を選びます。
lambda2_13.png


"Identity pool name"が必須なので、ここではアプリの名前(AllZeroPuzzle)にしてみました。
ユーザー認証は使わないので、"Unauthenticated identities"の
"Enable access to unauthenticated identities"にチェックを入れておきます。
最後に"Create Pool"を押します。

lambda2_14.png


ユーザー認証あり/なし時のロールを作成する画面になります。
特に何もせず"許可"を押します。
lambda2_15.png


次に、Cognitoをどうやってプログラムから設定するかの説明ページが表示されるので、
Platform で Unity を選択します。
"Get AWS Credentials"のサンプルプログラムの中に記載されている

ap-northeast-1:xxxxxxxxxxxxxxxxxx

が Identity Pool ID です。
これを控えておきます。

控えておくものはこの2点です。
・Identity Pool ID
・リージョン名(Identity Pool IDの先頭"ap-northeast-1"のこと)

各リージョン名:
https://docs.aws.amazon.com/ja_jp/ElasticMapReduce/latest/DeveloperGuide/emr-plan-region.html

lambda2_16.png


それでは、Unityに戻って、以下の3つを埋めてみましょう。
・Identity Pool Id
・Cognito Identity Region
・Lambda Region

lambda2_17.png


再生ボタンを押してGameウィンドウの"List Functions"ボタンを押してみましょう。
すると、エラーが出ます。
これは、まだCognitoで作ったロールをLambdaに関連付けていないからです。

lambda2_18.png


再び、AWSの管理画面に戻ります。
サービス > AWS Lambda > Functions
を見ると、前回作った"helloWorld"があるので選択します。

lambda2_19.png


Configuration の"Existing role"が前回のまま(lambda_basic_execution)になっています。
この lambda_basic_execution を先ほどCognitoで作ったロールに置き換えたいのですが
選択肢にありません。
では、どうすればよいのでしょうか。

lambda2_20.png


管理画面のサービス > セキュリティ&アイデンティィ > IAM を選びます。

lambda2_21.png


左メニューの"ロール"を選ぶと、前回作ったロール(lambda_basic_execution)と
今回Cognitoで作ったロール(2つ)があります。
認証なし(Cognito_AllZeroPuzzleUnauth_Role)のロールを選びます。

lambda2_22.png


アクセス許可 > インラインポリシー > ロールポリシーの作成 を押します。

lambda2_23.png


"Policy Generator"の"選択"を押します。

lambda2_24.png


アクセス許可の編集画面になりますので、以下を設定します。
・AWSサービス = AWS Lambda
・アクション = InvokeFunction、ListFunctions ※Unityで使っている関数
・Amazonリソースネーム(ARN) = *(アスタリスク)

設定が終わったら"ステートメントを追加"を押します。

lambda2_25.png

lambda2_26.png


画面下にアクセス許可が表示されると"次のステップ"ボタンが有効になりますので、
押して次に進みます。

lambda2_27.png


ポリシーの確認画面です。
特に何もせずに"ポリシーの適用"を押します。

lambda2_28.png


画面が戻ると、インラインポリシーに先ほど作成したポリシーが追加されました。

lambda2_29.png


次に、前回作った lambda_basic_execution のロールを選びます。

lambda2_22.png


信頼関係を押すと、信頼されたエンティティとしてLambdaがあることが確認できます。
信頼関係の編集を押します。

lambda2_30.png


表示されるポリシードキュメントをコピーしておきます。

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}



ロール画面に戻り、認証しない方(Cognito_AllZeroPuzzleUnauth_Role)を選びます。
信頼関係の画面を見ると、信頼されたエンティティには

cognito-identity.amazonaws.com

だけが記載されています。
ここに、先ほどの"lambda_basic_executionと同じ信頼されたエンティティ"を追加します。
つまり、

ID プロバイダー lambda.amazonaws.com

を追加します。
ここでも、信頼関係の編集を押します。

先ほどの信頼関係の"Statement"の内容を、",(カンマ)"で区切ってから追記します。

lambda2_31.png


すると、信頼されたエンティティに"ID プロバイダー lambda.amazonaws.com"が追加されました。

lambda2_32.png


Lambdaの画面に戻ります。
ExistingRoleに、先ほど選択肢にはなかった"Cognito_AllZeroPuzzleUnauth_Role"が追加されているので
選択します。

lambda2_33.png


画面上の"Save and test"を押してみましょう。
特に問題なく実行されるはずです。

次に、Unityに移り、再生を押してから"List Functions"を押すと、
Lambdaで作った関数 helloWorld が表示されます。

lambda2_34.png


続いて、"Invoke"を押すと、"Function Name:"の入力欄に記載されている関数を呼びます。
記入欄には"helloWorld"とあるので、Lambda上のhelloWorldが呼ばれます。

lambda2_35.png


これで、PCのUnityからAWS Lambdaに接続し、関数を実行することができました。


最後に、iPhoneで動作するようにします。

サンプルに添付してあった
Assets > Examples > readme.md
を開くと、IL2CPP で実行するには
Resources ディレクトリを作り、その中に link.xml を追加する必要があるようです。

lambda2_36.png


link.xmlに記述する内容は
https://github.com/aws/aws-sdk-net/blob/master/Unity.README.md#unity-sdk-fundamentals
に記載されていますが、こちらにも転機しておきます。
※上記には、コメントアウトしていない部分があったため
<linker>
<assembly fullname="UnityEngine">
<type fullname="UnityEngine.Experimental.Networking.UnityWebRequest" preserve="all" />
<type fullname="UnityEngine.Experimental.Networking.UploadHandlerRaw" preserve="all" />
<type fullname="UnityEngine.Experimental.Networking.UploadHandler" preserve="all" />
<type fullname="UnityEngine.Experimental.Networking.DownloadHandler" preserve="all" />
<type fullname="UnityEngine.Experimental.Networking.DownloadHandlerBuffer" preserve="all" />
</assembly>

<assembly fullname="mscorlib">
<namespace fullname="System.Security.Cryptography" preserve="all"/>
</assembly>

<assembly fullname="System">
<namespace fullname="System.Security.Cryptography" preserve="all"/>
</assembly>

<assembly fullname="AWSSDK.Core" preserve="all">
<namespace fullname="Amazon.Util.Internal.PlatformServices" preserve="all"/>
</assembly>
<assembly fullname="AWSSDK.CognitoIdentity" preserve="all"/>
<assembly fullname="AWSSDK.SecurityToken" preserve="all"/>
</linker>

readmeでは
<assembly fullname="AWSSDK.Lambda" preserve="all"/>

を追加するように記載がありましたが、追記しなくても動作しました。

Unityでビルドするときは、
"Setting for iOS"で"Bundle Identifier"を自分用に変更しておきましょう。

ここでは、be-styleのアプリということで

com.jpn.bestyle.lambdatest

としておきました。

lambda2_37.png


ビルドする前は、Examples/LambdaExample のシーンが登録されていることを確認しましょう。

lambda2_38.png


UnityでビルドしてできたXcodeのプロジェクトファイルを開きます。
特に何もせずに実行します。

アプリが起動して、"List Functions"と"Invoke"が動作すれば成功です!

iPhoneでの実行時にハマった点がありました。
Credentials is expired、つまりCredentialsが有効期限切れになっているというのです。

事象としては、iPhoneの時計が日本時間なのに、サーバーの時間がアメリカ時間になっていて
その時差によって有効期限切れでAWS Lambdaが使えないというものでした。

解決方法は、iPhoneの時間を"自動設定"にすることでした。
このときにiPhoneの"位置情報"を有効にすることにポイントがありました。
そうしたら、接続先のサーバー(東京リージョン)と端末の時計が合い、Lambdaにアクセスできました。


今回が初めてなので、途中で不要な処理が入っているかもしれません。
それはこれから経験を積んで精査していきたいと思います。


次は、AWS Lambda から DynamoDB にアクセスしてみます。
[Web] AWS Lambda から DynamoDB にアクセスしてアイテムを更新してみた
posted by be-style at 23:09| Comment(0) | Unity