adbのCLIでAndroidのエミュレータを起動したりアプリの起動、テストの実行をしたりする
この記事はAndroid Advent Calender その2の15日目の記事です。
今回は
https://developer.android.com/studio/command-line/adb.html https://developer.android.com/studio/run/emulator-commandline.html https://developer.android.com/studio/test/command-line.html
を見て色々素振りしてみようと思います。
シミュレータの起動
/Users/woshidan/Library/Android/sdk/tools/emulator -avd Nexus_5X_API_22
で起動することが可能です。テストを実行させたり、アプリをインストールして起動したりしてみましょう。
アプリのインストール
$ adb install app/build/outputs/apk/app-debug.apk app/build/outputs/apk/app-debug.apk: 1 file pushed. 5.8 MB/s (2910562 bytes in 0.477s) pkg: /data/local/tmp/app-debug.apk Success # 二つ以上シミュレータを起動 or 実機を接続している場合 $ adb devices List of devices attached 162EJP011A71181614 device emulator-5554 device $ adb -s emulator-5554 install app/build/outputs/apk/app-debug.apk app/build/outputs/apk/app-debug.apk: 1 file pushed. 142.6 MB/s (2910562 bytes in 0.019s) pkg: /data/local/tmp/app-debug.apk Success
apkはプロジェクトのbuildディレクトリ以下を探せばあると思います。
アプリのアンインストール
$ adb uninstall package Success
アプリの起動
# アクションがandroid.intent.action.VIEWのIntentに反応するActivityへ暗黙的Intentを送る $ adb shell am start -a android.intent.action.VIEW # 特定のActivityへ明示的Intentを送る $ adb shell am start -n io.test.woshidan/io.test.woshidan.MainActivity
Logcatのログを標準出力に出す
$ adb logcat
操作の様子を録画する
# API19以上の実機かAPI24以上のシミュレータ $ screenrecord /sdcard/Movies/demo.mp4 # adb pull で当該ファイルをPCなどに持ってこれる
テストを実行する
ADBを使う
# テストで実行可能なinstrumantationの一覧 $ adb shell pm list instrumentation instrumentation:com.android.emulator.smoketests/android.support.test.runner.AndroidJUnitRunner (target=com.android.emulator.smoketests) instrumentation:com.android.smoketest.tests/com.android.smoketest.SmokeTestRunner (target=com.android.smoketest) instrumentation:com.example.android.apis/.app.LocalSampleInstrumentation (target=com.example.android.apis) instrumentation:com.example.woshidan.myapplication.test/android.support.test.runner.AndroidJUnitRunner (target=com.example.woshidan.myapplication) instrumentation:com.example.woshidan.newtestapplication.test/android.support.test.runner.AndroidJUnitRunner (target=com.example.woshidan.newtestapplication) # プロジェクト全体のAndroidTest $ adb shell am instrument -w com.example.woshidan.myapplication.test/android.support.test.runner.AndroidJUnitRunner # AndroidTestのうち特定のクラスのテストを行う $ adb shell am instrument -w -e class com.example.woshidan.myapplication.test.ExampleTest com.example.woshidan.myapplication.test/android.support.test.runner.AndroidJUnitRunner
gradleを使う
// プロジェクト用のbuild.gradle buildscript { repositories { google() // gradlewでgoogle()リポジトリに探しにいくためにはここに追加する必要あり jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' } }
// アプリ用のbuild.gradle android { compileSdkVersion 26 defaultConfig { applicationId "com.example.woshidan.newtestapplication" minSdkVersion 15 targetSdkVersion 26 buildToolsVersion '26.0.1' versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary= true } ...
# プロジェクトのAndroidTest全体を行う(JUnitを使うUnitテストは connectedAndroid を取る) $ ./gradlew app:connectedAndroidTest # プロジェクトのAndroidTestのうち特定のメソッドのものを行う $ ./gradlew app:connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.example.woshidan.myapplication.MainActivityTest#mainActivityTest
// 出力される実行結果 // build/generated/outputs/connected/以下にある // build/generated/reports/以下にはHTML形式のレポートも <?xml version='1.0' encoding='UTF-8' ?> <testsuite name="com.example.woshidan.myapplication.MainActivityTest" tests="1" failures="0" errors="0" skipped="0" time="0.665" timestamp="2017-12-20T17:11:10" hostname="localhost"> <properties> <property name="device" value="Nexus_5X_API_22(AVD) - 5.1.1" /> <property name="flavor" value="" /> <property name="project" value="app" /> </properties> <testcase name="mainActivityTest" classname="com.example.woshidan.myapplication.MainActivityTest" time="0.563" /> </testsuite>
まとまってませんが色々試して満足したので現場からは以上です。
ライブラリ開発屋がAthenaを利用してログの収集分析をやりやすくした話
この記事はServerless Advent Calender 2017の16日目の記事です。
ライブラリ開発屋として仕事でAthenaを使ってログの収集分析をやりやすくした話をします。
はじめに
普段は開発者としてiOS/Android両対応のモバイルアプリ向けのライブラリの開発やテストをしています。その業務の中でお問い合わせを受けた際、お客さんの状況を聞いてライブラリを修正したり使い方を提案したりして対応させていただくことがあります*1。
その中で、なかなか言葉で状況の説明が難しい場合があり、そういうときは動作検証時のログをいただいて状況の確認をさせていただきます。しかし、いかんせんそういう状況は再現が難しかったりするもので動作検証のログがとれないか試しているうちに時間が経ってしまってもどかしいことが結構ありました。
そこで、なるべく早くお客様に解決方法の提案ができるように、それらしいログを検索して取得できたらいいな、セキュリティ的・S3の予算的にピンポイントで取得したいな、ということで今回Athenaを使ってやってみました。
Athenaについて簡単に
Athenaは標準的なSQLを利用してS3内のデータを分析できるサービスです。
実際中で動いているのは分散SQLクエリエンジンのPrestoで、データフォーマットにJSON形式を用いる場合は下記のような形式のJSONが入っているS3のバケットのパスが s3://athena-examples/users/logs
だったとして
{ "name": "太郎", "address": "日本のそのあたり", "comment": "JSONは実際は1行にminifyしておく必要があります" }
以下のクエリを実行すればSQLを用いて s3://athena-examples/users/logs
以下のデータを検索できるようにしてくれます。
// 単純化のため少々それっぽくないログとなっています CREATE EXTERNAL TABLE IF NOT EXISTS user_logs ( name string, address string, comment string ) ROW FORMAT serde 'org.apache.hive.hcatalog.data.JsonSerDe' LOCATION 's3://athena-examples/users/logs/';
テーブル定義の際に指定した LOCATION
のパス以下はテーブル定義の形式に沿って処理できるデータのみが入っている必要がありますが、上記のテーブル定義はAthenaが検索の際に用いるだけで、S3に入っているデータとは結びついていないので何度でも破棄したり作り直すことが可能です。
他に対応しているデータフォーマットなど、詳しい話についてはこちらをご覧ください。
実際にやってみて気を使ったこと
やってみたことを書くとログの形式をAthenaで検索しやすい形に変更してAthenaを使いましたで終わってしまうので、その際気を使ったことなどを書いていこうかと思います。
Athenaのコスト対策の話
Athenaの料金形態は検索を実行するときのデータスキャン量に対する従量課金で、 スキャンされたデータ 1 TB あたり 5 USD
となっています*2。
そのため、ログをgzipなどに圧縮するとスキャン対象の容量をかなり削減することができます。幸いログファイルには同じ文字列が多く含まれるためか、自分が行った事前調査では単純にgzipにしただけで圧縮前の容量の15~20%まで小さくすることができました。S3にアップロードするファイルの圧縮は比較的簡単に対策ができるためやったほうがいいでしょう。
Athenaのコスト対策はAthenaの料金の話だけでは終わりません。AthenaはS3にあるファイルを取得するためにS3を利用しており、Athenaの料金とは別途にS3の利用料金がかかります。このS3の利用料金が場合によってはAthenaのスキャン料金と同等以上になることがあり、
- 同じクエリを何度も実行しないようにする
- LIMIT句をつけると早めにスキャン & データ取得を打ち切るので必ずLIMIT句をつけるようにする
- パーティションやテーブル定義に利用するロケーションのパスを工夫してスキャン範囲を狭くする
などの対応を取る必要があります。
パーティションやテーブル定義に利用するロケーションのパスを決めるにあたって
前節で パーティションやテーブル定義に利用するロケーションのパスを工夫してスキャン範囲を狭くする
と書きましたが、バケットのパスやパーティション分割のために使える要素としては、モバイルライブラリの場合
- 日付
- 対応OS
- ライブラリのバージョン
- ユーザのサービスアカウントごとのid
などがあります。それぞれ、data=xxx/os=ios/version=nnn/user_app_id=xxxx
のように素直にパーティションを掘ってもよいかもしれませんが、
- ライブラリのバージョンは企業によってはなかなか更新の時間がとれないため、利用されているバージョンが10種類以上とばらついてしまう
- 利用されているサービスアカウントはテスト用のものもあるので1日に数百以上ある
ということを踏まえると、あっという間にAthenaが制限しているパーティション上限数 20000に引っかかってしまうでしょう。
しかし、日頃の調査を振り返ると
- Android用ライブラリの調査をするときにiOS用ライブラリの調査をすることはほとんどない
- ライブラリのログは利用している開発者のアプリごとの利用者規模が6桁~導入時のお試しで1桁、2桁まで様々
- ライブラリのバージョンで区切って検索しているつもりが一番利用者数の多いアプリのログしかスキャンしていないことがありうる
- ログを調査するのはお問い合わせ起点、つまり、調査対象のサービスアカウントや利用バージョンの情報を持っていることが多い
- 新バージョンの不具合などにもとづいてログを調べるとしたら、結局は最新の日付から探していくことが多いだろう
などの事実があり、これらを踏まえると、同時に範囲検索で使う要素は存外少なそうなことがわかります。
結局、大きなテーブルを一つ定義してその中でいくつかのパーティションを利用するのではなく、基本的にはテーブルのロケーションに深めのパスを設定し、そのパスごとにたくさんのテーブルを定義しては捨てる方針にしました。
ややかっこわるいのですが、放っておくとパーティションのキーにあたる値の組み合わせは基本的にどんどん増えていくため、ほとんど一つのクエリで同時に検索しない範囲はテーブルのロケーションの方に突っ込んでもよいと思います。
スクリプトでクエリを生成することにしてクエリ実行結果の再利用やLIMIT句の指定を徹底する
Athenaは従量課金性ですが、一度実行したクエリの結果を再利用することが可能です。クエリを実行した時のquery execution idをパラメータにしてGetQueryResultsのAPIにリクエストを送ることにより、データのスキャンを再度行わずに実行結果を再取得することができます*3。
なので、一度実行したクエリとそれに対応するquery execution idを控えて、実行しようとしているクエリが直近で実行されたものなら以前の結果を再利用することで、コストを抑えることができます。
表記揺れによってほぼ同じクエリが別のクエリとカウントされて似たようなクエリが何個も走るかもしれませんが、いっそのことクエリの生成もスクリプトで行うことにしました。そうすることで、
- 表記揺れがないため、クエリとquery execution idの対応を管理するスクリプトが動きやすい
- テーブルのロケーションを深めに掘ったり、セッションの属性と紐づけてログを検索・分析しやすくした結果、肥大化したテーブル定義を間違えない
- LIMIT句の追加などクエリの中で外してはいけないルールが徹底される
ことになりました。--dry-run
オプションでAthenaに投げる予定のクエリを吐き出すようにしていて、手動でクエリを書きたくなった場合の下書きとしても利用できるようにしたり、実行時のログを一部出力することで、目当てのログのパスを見つけやすくしてなるべくターミナル一つで完結するように工夫しています。最近のブームは小規模なスクリプトのDIYです*5。
今後
今回の対応で社内外からお問い合わせがきたらログを分析しやすくなったので、今後はお問い合わせが来る前になにか気づけたらいいなということで、S3とLamdbaを組み合わせて不具合が起きてそうなときのログの検知もやってみたいと考えています。
DIYの現場からは以上です。
*1:サポートの方とお客様にひたすら助けられるお仕事とも言います
*2:https://aws.amazon.com/jp/athena/pricing/
*3:http://docs.aws.amazon.com/athena/latest/APIReference/API_GetQueryResults.html
*4:こういう http://woshidan.hatenablog.com/entry/2017/10/04/055335
*5:自分以外みんな知ってそうな余談であれなのですが、検索結果は1行1レコードとなっています。一回のクエリで同じファイルが複数レコードとして引っかかることがあるため、類似の用途で使う場合はLIMIT句の数字を用途に応じて増減しましょう
「テストも開発もするモバイルエンジニアのためのXCUITest/Espressoのすすめ」という題でLTをしました
testautomationresearch.connpass.com
要件の細かいことを突いたりテストケースの設計が大好物だったため、そういうのを本職としているテストエンジニアはどういう人たちなのかを知りたかったので「システムテスト自動化カンファレンス2017-2」に参加してきました。
図々しく「テストも開発もするモバイルエンジニアのためのXCUITest/Espressoのすすめ」という題でLTをさせていただいたので、取りいそぎスライドとその補足についてだけでもメモします。
スライド
スライド補足
Appiumはいろんな言語のドライバがあるので好きな言語で書けるという話について
Appiumはブログなどの件数が多いから盛り上がっているという話がありますが、各言語のドライバでQ&Aやブログ記事が割れており、また言語を特定して情報を調べないとある言語の質問について他の言語で返ってくることもあるので*1、そういう数値については3~5分の1に割り引いて考えた方が良いかと思います。
各種言語のドライバの更新状況も言語によって異なっており、たとえば
となっています。不具合があった時に自分でAppiumが利用している各種ツールの状況を調査するコストが取れなければ、更新頻度の少ない言語は避け、いまならCookpad, Mercariが対応すると決めているRubyのドライバを選んだ方がハマりが少ないのではないでしょうか。。
Appiumが安定していなくてつらい話
Appiumは、
- Appiumクライアント(Appiumクライアントライブラリ=各種言語のdriver, テストスクリプト)
- Appiumサーバ
- uiautomator/espresso or instrument/xcuitest
といった構成になっていて*2、テストを動かすために利用しているツールが多いです。
そのせいか、気軽にバージョンアップするとどれかのツールが噛み合わなくて不安定になったり動作が非常に遅くなったりします。
Appium 1.7.1 Automation is too slow · Issue #739 · facebook/WebDriverAgent · GitHub
前述のドライバの言語がたくさんあることと合わせて関連issueがあちこちに散っており、かつ、大量のログが貼り付けられていることも多く必要な条件が見分けにくいため、調査に時間がかかります、というか、ました。
もともとSelenium系のツールに詳しいチームで対応をとったり、安定するまで待つ*3決定をすれば問題ないかもです。
しかし、現状のEspresso/XCUITestを直接使えば、間にそれなりに大きいツールをはさまないため、その分セットアップや調査が楽でした。
上記の「手間がかかる」「楽でした」という言葉について、調べている最中も悩んでいてこの補足を書いている現在も感じることですが、自分が不勉強で手間を惜しむなんて発想をするから云々みたいなことがずっと頭の中でくるくるしています。
ですが、テストも含めてコードは必要でなくなったら捨てたいです。気軽に捨てられるためには学習コストやメンテナンスコストも含めた手間は小さいほうがよいのでは、ということも一緒にぐるぐるしています。
LTタイトルに「モバイルエンジニア」を含めていますが、自分がアプリ開発者としての環境に慣れ親しんでいるのでEspresso/XCUITestで作ったテストなら気軽に捨てられるなぁ、という感じです。
E2Eテストが全部Espresso/XCUITestでいいかという話
もともと開発者*4の自分としてはAppiumで自動テストが書きやすい範囲とEspresso/XCUITestで自動テストが書きやすい範囲が被っているように感じました。それな らば、自動化しやすい部分は動かしやすいEspresso/XCUITestを使い、サーバとの連携、プッシュ通知であったりapk/ipaの更新時の挙動など自動化しにくい部分は手動テストと組み合わせればよい、と考えていました。
とくに、専用のQAチームを置けるほど規模が大きくないチームでE2Eテストが必要な時は「手動 + Appium」より「手動 + Espresso/XCUITest」の方が楽では~くらいの勢いでした。しかし、会場に行ってみると自分が想像していた以上にリリース用apk/ipaを用いたテストを重視する雰囲気だったため、やや場違いとなりもうしわけなかったです。
ただ、それぞれのプラットフォームのツールに乗っかって開発と同じIDEでテストを書くことにすると、テスト時の動作を入ってる変数付きで再現することができます。これにより、テストが悪いか/コードが悪いかの切り分けがかなり容易になり、開発しながらテストを書くハードルもぐっと下がるのでそれだけはお伝えしたかった(誰に。
遅くなった理由
もうちょっとややこしいレイアウトやもうちょっと新しいバージョンでもう一回Espresso Test Recorderの動作確認しようかと思ったらGradle Projectのリフレッシュがなかなか終わらなくてテンパってました。はい。。
最後に運営の皆様ありがとうございました。
現場からは以上です。
*1:たとえば http://discuss.appium.io/t/how-to-close-application-between-tests/1168 . phpの質問についてRubyやJavaのコードがかえってきている
*2:https://github.com/appium/appium と http://www.atmarkit.co.jp/ait/articles/1504/27/news025.html を元にしています
*3:このことを考えると、更新が活発な言語を選択した方が良いと思います
*4:というか今もテスト設計の方が割いてる時間が多いだけで社内の肩書きとして開発者
xcodebuild testのテスト対象のデバイスやテストケースをappiumぽく簡単に指定できるラッパースクリプトを書いてみた
この記事はiOS2 Advent Calendar 2017の3日目の記事です。
xcodebuild testのテスト対象のデバイスやテストケースをややappiumみたいに簡単に指定できるラッパースクリプトを書いてみました。
なお、CocoaPodsでライブラリ管理をしているプロジェクトを対象としています。CocoaPodsをご利用でない場合は、適宜 -workspace
を -project
オプションに読み替えていただけると幸いです。
スクリプト
スクリプト本体 xcode-wrapper.sh
#!/bin/bash # configuration for project, written here WORKSPACE="ExmapleApp.xcworkspace" APP_SCHEME="ExmapleApp" TEST_SCHEME="ExmapleAppTests" BUILD_CONFIG="Debug" # configuration for test target device written in caps.json TARGET_LABEL=$(jq .target < ./caps.json) DEVICE_NAME=$(jq .[$TARGET_LABEL]."deviceName" < ./caps.json | tr -d '"') PLATFORM_VERSION=$(jq .[$TARGET_LABEL]."platformVersion" < ./caps.json | tr -d '"') DEVICE_ID=$(jq .[$TARGET_LABEL]."udid" < ./caps.json | tr -d '"') DEVICE_TYPE=$(jq .[$TARGET_LABEL]."type" < ./caps.json | tr -d '"') build() { if [ "$DEVICE_TYPE" = "simulator" ] then # refs: https://qiita.com/roothybrid7/items/19f0aeeee98573dab2a6 xcodebuild \ -sdk iphonesimulator \ -destination "platform=iOS Simulator,name=${DEVICE_NAME},OS=${PLATFORM_VERSION}" \ -configuration "$BUILD_CONFIG" \ -workspace "$WORKSPACE" -scheme "$APP_SCHEME" \ build else xcodebuild \ -sdk iphoneos \ -destination "platform=iOS,id=${DEVICE_ID}" \ -configuration "$BUILD_CONFIG" \ -workspace "$WORKSPACE" -scheme "$APP_SCHEME" \ build fi } test() { if [ "$DEVICE_TYPE" = "simulator" ] then xcodebuild -workspace $WORKSPACE \ -scheme "$TEST_SCHEME" \ -sdk iphonesimulator \ "$TEST_CASE_OPTION" \ -destination "platform=iOS Simulator,name=${DEVICE_NAME},OS=${PLATFORM_VERSION}" test else xcodebuild -workspace $WORKSPACE \ -scheme "$TEST_SCHEME" \ -sdk iphoneos \ "$TEST_CASE_OPTION" \ -destination "platform=iOS,id=${DEVICE_ID}" test fi } if [ $1 == "build" ]; then build fi if [ $1 == "test" ]; then i=1 for OPT in "$@" do if [ $OPT = "-test" ]; then TEST_CASE_OPTION="-only-testing:${TEST_SCHEME}/${@:$(expr $i + 2):1}" test exit 0 fi i=$(expr $i + 1) done test fi
設定ファイル caps.json
"target" の部分を変更してテストを実行するデバイスを切り替えます。
{ "target": "iPhone5", // テストで使うデバイスの指定 "iPhone5": { "type": "simulator", // シミュレータ "deviceName": "iPhone 5", "platformVersion": "9.3", "udid": "" // シミュレータの指定では使わない }, "iPhone6": { "type": "simulator", // シミュレータ "deviceName": "iPhone 6", "platformVersion": "10.0", "udid": "" // シミュレータの指定では使わない }, "iPhone7": { "type": "simulator", // シミュレータ "deviceName": "iPhone 7", "platformVersion": "11.1", "udid": "" // シミュレータの指定では使わない }, "iPad": { "type": "iphoneos", // 実機 "deviceName": "woshidanのiPad", "" // 実機の指定では使わない "platformVersion": "10.3", "udid": "DUMMY_ID" } }
使用例
# 全てのテストを実行する $ ./xcode-wrapper.sh test # ExmapleTestクラスにおいたテストをすべて実行する $ ./xcode-wrapper.sh test -test ExmapleTest # ExmapleTestクラスにおいたテストメソッドtestAを実行する $ ./xcode-wrapper.sh test -test ExmapleTest/testA # アプリをビルドする $ ./xcode-wrapper.sh build
補足
実行されるテストを指定したい
CLIから見守るだけとはいえ、毎回全てのテストを実行するのは時間がかかります。 xcodebuild test
サブコマンドは only-testing
オプションを用いることで実行するテストを指定することができます。
上記のスクリプトでは、-test
オプションを指定することで only-testing
オプションで指定する文字列を与えることができます。スクリプト自体は -test
オプションなしでも利用可能で、その場合は全てのテストを実行します。
利用できるデバイスの名前やID, OSバージョンの組み合わせについて
caps.json
に書くシミュレータや実機デバイスの名前、OSバージョン、IDなどがわからない場合はXCodeの Add Simulators ...
の画面か $ instruments -s devices
コマンドより確認できます。
XCodeのデバイス管理画面から
ターミナルから
$ instruments -s devices ... iPhone SE (10.0) [7DB19BC4-5A56-4D40-93BD-90F551713043] (Simulator) iPhone SE (10.3.1) [10FE1E72-D129-4593-A18B-AE85F4D9DC78] (Simulator) iPhone SE (11.1) [C511B853-09C3-4599-A88F-737296F02DED] (Simulator) iPhone X (11.1) [95022FBF-DDDB-46A8-8978-0129C0A6142D] (Simulator) ...
もっと色々書こうかと思ったのですが力尽きたので現場からは以上です。
XCode Tools CLIのバージョンアップとビルドに必要なパラメータ、権限の変化について
お仕事の都合で古いOSに対してもXCode Tools CLIを使ってビルドする必要があって調べてみても要領を得なかったんだけど少しわかった気がするので、わかったところまで整理してみます*1。
アプリとして実機やシミュレータにインストールできるファイルの種類について
説明 | |
---|---|
.app | xcrun simctl を経由して iPhone simulatorへインストールできる。 xcodebuild build コマンドやXCodeでシミュレータへ向けてビルドすることで作成可能 |
.ipa | アプリストアへリリースしたり、実機へデプロイするときに作成する必要があるファイル形式。 .app や .xcarchive ファイルから開発者の証明書を何らかの形でアタッチするようなプロセスを経て作成 |
参考
- https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html
- https://qiita.com/HIkaruSato/items/a8d633d1b42c00b5722d
XCode7時代の .ipa 作成方法とXCode8時代の .ipa 作成方法
- XCodeが7の頃は
.ipa
作成に関して.app
ファイルを渡せばxcrun
のPackageApplication
がうまくやってくれていた - XCode8.3. で
PackageApplication
が廃止されてしまった- XCode8.3.2 を使う場合
xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH
というメッセージが出るようになっている
- XCode8.3.2 を使う場合
- このため、
xcrun PackageApplication
の代わりにxcodebuild archive
を使う必要があるxcodebuild
で.xcarchive
を作成した後、.ipa
を作成する際にexportProvisioningProfile
などを自分で設定する必要がある- これの具体的なパス (SampleXXX的なノリなのではなく 'MyMobileApp Distribution Profile' みたいなのりでファイル名などが想像しにくい例が多い) がよくわからなくてつらい
参考
XCode 8.2 -> XCode 8.3 で Automatically manage signing
が有効になっているプロジェクトにおいて .ipa
へのエクスポートが失敗するように
- [試せていない]
exportOptions.plist
のmethod
の値がdevelopment
でない場合、XCodeでビルドしているときに、ログインしているアカウントがAdmin
でない場合、、証明書(開発者登録. キーチェーンに登録している) とProvisioning Profile
(開発者とappIdに紐づいている) が揃っていても権限がたりなくて export に失敗する- [試せていない] CI用にadminにする?
- [試せていない]
xcodebuild -exportArchive -exportOptionsPlist /PATH/exportOptions.plist
で指定するexportOptions.plist
のmethod
の値をdevelopment
にすればうまくいくかも?
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>method</key> <string>development</string> <key>teamID</key> <string>GLPGBQ39X8</string> </dict> </plist>
参考
どうすればいいかわかったら今後追記しますが、詳しい人教えて欲しい感じです。
*1:上長許可あり
ERBとCSVを使って簡単な自分用ドリルを作る
最近シェルの勉強をしたいんですが、以前SQLを勉強した時のように基本的なシェルを反復して書くのが一番では? と思って、ドリルのようなものが欲しくなりました。
そこで、CSVにお題とお題の答えを書き連ねたらアコーディオンで答えを出したり隠したりしてくれるHTMLを出すコードと、そのHTMLを見るアプリ*1を書いたのでポスト。
使い方は、
$ ruby generator/generator.rb input.csv > drill.html
を実行して drill.html
をブラウザで開く、です。アプリで見る場合はさらに
$ cp drill.html cp drill.html CSDriller/app/assets/drill.html
とした後、一緒についているAndroidプロジェクトをビルドしてください。
実際動かしてみると下記のような感じです。
参考
- http://d.hatena.ne.jp/littlebuddha/20081022/1224645199
- https://qiita.com/shizuma/items/7719172eb5e8c29a7d6e
- http://magazine.rubyist.net/?0017-BundledLibraries
- https://qiita.com/kozo002/items/bcf693738a37aa9ee917
特に上記記事のアコーディオンがよすぎて作りたくなったので多謝。
Cocos2d-x 2.2.6をMac OS Sierraで動くようにするまでのメモ
仕事でやってて面白かったので許可を取って公開。
環境
- Cocos2d-x 2.2.6
- Eclipse Oxygen.1a Release (4.7.1a)
- Android NDK, Revision 10e
- Android SDK & tools v24.0.3 のもの一式
- Android Studioとは別に用意
- Eclipseの環境設定で下図のように設定
メモ
プロジェクトの作成
python create_project.py -project MyGame -package com.MyCompany.AwesomeGame -language cpp
Eclipse インストーラからJavaのIDEをインストールして環境変数を設定
Help > Install New SoftWare
Work with
の欄にhttps://dl-ssl.google.com/android/eclipse
を入力
cocos2dxのプロジェクトをインポートとプロジェクト間の依存関係の設定
Import > Andorid > Existing Android Code Into Workspace
でcocos2d-x-2.2.6/cocos2dx
のplatform/andorid/java
をインポートCopy projects into workspace
にチェックしておく
Import > Andorid > Existing Android Code Into Workspace
でcocos2d-x-2.2.6/cocos2dx/ProjectName
をインポートCopy projects into workspace
にチェックしないProjectName
のAndroidManifest.xml 中のminSDKVersion
が小さすぎるので14くらいにあげておく
PackageManager
上でProjectName
の上を右クリックしてProperties > Android
を開き、Libraryのところで、libcocos2dxを指すよう設定するisLibrary
のチェックはしない(アプリプロジェクトにisLibraryのチェックをするとapkが生成されない)
アプリ側のプロジェクトのLinked Resourcesの修正
- プロジェクトのところで右クリックして
Properteis > Resources > Linked Resources
のLinked Resources
のタブを確認。Classes
,cocos2dx
,extensions
,scropting
の壊れているパスを修正
古めのNDKを用意してNDK_ROOTの環境変数を設定
- 古めのNDK(Android NDK, Revision 10e)を https://developer.android.com/ndk/downloads/older_releases.html からDL
Eclipse
のPreferences > Android > NDK
の項目の NDK LocationにDLしてきたNDKを配置したパスを書く
Preferences > Android > NDK
に設定したパスが Eclipse に見えてないことがあるのでC/C++ > Build > Environment
にもNDK_ROOT
として追加Bulid Project
した結果、build_native.sh
は走ってくれたが。。
トラブルシューティング
Could not find BuildTest.apk!
...
- https://stackoverflow.com/questions/4778113/android-eclipse-could-not-find-apk
- アプリケーションプロジェクトのプロパティに
isLibrary
のチェックが入ってないか
Unknown error: Unable to build: the file dx.jar was not loaded from the SDK folder!
Failed to load /Users/woshidan/Library/Android/sdk/build-tools/26.0.2/lib/dx.jar
- https://stackoverflow.com/questions/5228453/android-adt-error-dx-jar-was-not-loaded-from-the-sdk-folder
Eclipse起動時に Failed to get the required ADT version number from the SDK
- Eclipseが想定しているADTのライブラリ構成のパスが古いせいで、ビルドツールの特定のライブラリが見つからないって言われてる(その2)
- Andorid SDKと一緒のディレクトリに入っているツールは
build-tools
以外は最新版しか保持できない。buildtools
以外のツールのバージョンが v26以上だと同様のメッセージが出るのでAndorid Studio用のSDKとは別のディレクトリにEclipse用の古いバージョンのSDKを入れ直してそちらを使う
エミュレータを起動しようとしたら[Start]が押せず詳細を確認したら Google Nexus 5X No longer exists as a device
Description Resource Path Location TypeThe container 'Android Dependencies' references non existing library'cocos2d-x-2.2.6/cocos2dx/platform/android/java/bin/libcocos2dx.jar' ...
- http://renkaze.seesaa.net/article/405756568.html
libcocos2xd
のプロジェクトでjar
を吐き出すパスが別のパスに設定されているlibcocos2dx
のプロジェクトで右クリックしてProperties > Java Build Path < Source
の下側のDefault output folder
をlibcocos2dx/bin/classes
に設定
java.lang.IllegalArgumentException: No configs match configSpec
というエラーでエミュレータで起動するとクラッシュする
- http://mapyo.hatenablog.com/entry/2013/08/27/Mac%E3%81%ABCocos2d-x%E3%81%AE%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E4%BD%9C%E3%82%8B
- エミュレータ作成時の設定で
Emulation Options
のUse Host GPU
をチェック
Eclipse
でエミュレータを起動しようとしたら PANIC: Missing emulator engine program for 'arm' CPUS...
と出る
- Eclipse の ADT からエミュレータのシステムイメージが見えてないとかそういうことな気がする。
- Android Studioで使っている最新のAndroid SDK & Tools とは別にEclipse用の古いバージョンのSDKを入れ直したら解決した
Google Nexus 5X no longer exists as a device
とでて Nexus 5
のスキンのエミュレータがつけない
- Eclipse の ADT は対応しているバージョンより新しいAndroid SDKのスキンは存在しないものとして扱う、みたいな雰囲気
- Eclipse のデバイスマネージャから選択できるスキンのエミュレータを使う
まとめ
そろそろEclipseでAndroidを開発するのをやめたほうがいいのでは。
現場からは以上です。