Ruby on Rails 覚書き

  • config/routes.rbでルーティングを設定してもpublicのindex.htmlがある場合優先される。つまり削除かリネームしておく必要がある。
  • routes.rb設定例
Rails.application.routes.draw do
  get '/aaa', to: 'hogehoges#aaa'
end
  • アクションは特に指定のない限りにおいてメソッド内に記載された処理実行後の最後にapp/views/controller名/アクション名.html.erbを呼び出してユーザーに返す
  • データの受け渡しには「@」を使う
    • コントローラ側 : @hensu='あいうえお';
    • ビュー側 : <%= @hensu %>
  • モデルの全検索
    • コントローラ側 @records = Hogehoge.all
    • ビュー側

<% @records.each do |data| %>
名前:<%= data.name %><% end %>

Ruby on Rails(mac)

Ruby on Railsの最も簡単なサンプル

1.インストール
brew update
brew install ruby
sudo gem install rails

※Homebrewはインストール済みとする

2.アプリケーション作成
rails new first-app
3.コントローラ、ビュー、モデル作成
cd first-app
rails generate scaffold hogehoge user_id:integer name:string

※scaffold指定でコントローラ、ビュー、モデル全部作成

4.マイグレーション
rails db:migrate

マイグレーションマイグレーションファイルをもとにテーブルを作成する。
マイグレーションファイルはモデルを作成したときにfist-app/db/migrate/につくられる

5.テストデータを作成する

seeds.rbを編集

cd ~/first-app/db
vi seeds.rb

(1)テストデータを書き込む

Hogehoge.create(user_id: 1, name: 'あいうえお')
Hogehoge.create(user_id: 2, name: 'かきくけこ')

※先頭は大文字

(2)テストデータをつくる

rails db:seed

(3)以下の要領でDBを確認できる

rails dbconsole
.schema hogehoges
select * from hogehoges;

※最後に「s」がつく

6.サーバ起動
rails s

Cocos2d-x環境構築(Mac)

1.iOSアプリ

(1)XCodeのインストール

  • FinderのアプリケーションからAppStoreを選択
  • Xcodeで検索
  • 「インストール」押下

(2)cocosのインストール
http://www.cocos2d-x.org

  • 「DOWNLOAD」押下
  • ダウンロード後適当な場所に配置(今回はホームディレクトリ配下にcocos2d-x-3.14.1を配置した)

(3)setup.pyを実行
terminalで先に配置したディレクトリに移動し以下のコマンドを実行

cd ~/cocos2d-x-3.14.1
python setup.py

※途中の質問はEnter押下でスキップ(iOSアプリのみの開発であれば不要なため)

(4)環境設定ファイルの読み込み

cd
source .bash_profile

(5)cocosプロジェクト作成
cocos new コマンドを実行し、プロジェクトを作成する。

cocos new TestProject -p com.TestDomain.TestProject -l cpp -d ~/CocosProjects

・new のあとには任意のプロジェクト名を指定
・-p のあとにはパッケージ名を指定
・-l は言語名を指定。cppだとC++
・-d はプロジェクトを格納するディレクトリを指定

(6)XCodeでプロジェクトファイルをオープンして開発スタート
TestProject/proj.ios_mac/TestProject.xcodeproj
f:id:stzx:20170129223010p:plain

2.Androidアプリ

(1)Pythonのバージョン確認

python --version

※2系であること。もし違う場合は以下からインストール
https://www.python.org/downloads/

(2)jdkインストール
以下からJDKをダウンロードしインストールする
http://www.oracle.com/technetwork/java/javase/downloads/index.html

(3)Antインストール
以下からAntをダウンロードし適当なディレクトリに配置(今回はホームディレクトリ配下にapache-ant-1.10.0を配置した)
http://ant.apache.org/bindownload.cgi

(4)Homebrew
terminalを開き以下のコマンドを実行

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

※Homebrewでインストールしたものは/usr/local/Cellar/以下にインストールされる。

(5)android-sdkインストール

brew install android-sdk

(7)SDK Managerを起動。Platform-toolsとBuild-toolsをインストール

android

Android SDK Platform-tools、Android SDK Build-toolsにチェックが入っていることを確認してインストール
f:id:stzx:20170129222441p:plain

(8)android-ndkインストール

brew install android-ndk

(9)setup.pyを実行
terminalで先に配置したディレクトリに移動し以下のコマンドを実行

cd ~/cocos2d-x-3.14.1
python setup.py

※ANT_ROOTのパスをきかれるので(3)で配置したパスを入力

(10)環境設定ファイルの読み込み

cd
source .bash_profile

(11)1.iOSアプリの(5)にて作成したTestProject ディレクトリに移動。Android実機を接続し、以下のコマンドを実行。

cd ~/CocosProjects/TestProject
cocos run -p android

cocos2d-x(Android Stuido)リリースビルド

まずはキーストアを作成する。
jdkに付属のkeytoolでコマンドラインから作成。

keytool -genkey -v -keystore c:\work\keystore -alias mykeystore -validity 10000
  • keystoreは任意の場所と名前を指定
  • aliasの名称は任意で。
  • validityは10000以上推奨。

いろいろ聞かれるので素直?に入れる。
パスワード等ひととおり入力が終わると確認を求められるので「y」を押す。
つづいて鍵のパスワードを入力が求められる。Enter。


次にプロジェクトフォルダに移動してリリース用のapkファイルを作成。

cocos run -p android --android-studio -m release

keystoreの場所を求められるので先ほど生成したkeystoreを指定する。
さらにkeystore作成時のパスワードを入力。
問題なければプロジェクトのbin/releaseの中にapkファイルが生成される。


実行して確認するのではなくコンパイルするだけなら「run」を「compile」に置き換えて、

cocos compile -p android --android-studio -m release


※キーストアはアップデート時に同じものが必要なので削除しないこと。

cocos2d-x(Android)にAdMobインタースティシャル広告を表示する

SDK Managerより、「Android Support Registory」、「Google Play Services」、「Google Repository」をインストールしておく。

build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "xxxx.hoge.co.jp"
        minSdkVersion 10
        targetSdkVersion 22
        versionCode 2
        versionName "1.01"
    }

    sourceSets.main {
        java.srcDir "src"
        res.srcDir "res"
        jniLibs.srcDir "libs"
        manifest.srcFile "AndroidManifest.xml"
        assets.srcDir "assets"
    }

    signingConfigs {

       release {
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                storeFile file(RELEASE_STORE_FILE)
                storePassword RELEASE_STORE_PASSWORD
                keyAlias RELEASE_KEY_ALIAS
                keyPassword RELEASE_KEY_PASSWORD
            }
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            if (project.hasProperty("RELEASE_STORE_FILE")) {
                signingConfig signingConfigs.release
            }
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile project(':libcocos2dx')
    compile 'com.google.android.gms:play-services-ads:+'
}

task cleanAssets(type: Delete) {
    delete 'assets'
}
task copyAssets(type: Copy) {
    from '../../Resources'
    into 'assets'
}

clean.dependsOn cleanAssets
preBuild.dependsOn copyAssets

compile 'com.google.android.gms:play-services-ads:+'を追加。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="s_takahashi.java_conf.gr.jp"
    android:installLocation="auto">

    <uses-feature android:glEsVersion="0x00020000" />
    
    <application
        android:label="@string/app_name"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher">
        
        <!-- Tell Cocos2dxActivity the name of our .so -->
        <meta-data android:name="android.app.lib_name"
                   android:value="MyGame" />

        <activity
            android:name="org.cocos2dx.cpp.AppActivity"
            android:screenOrientation="landscape"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- ここから追加 -->
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
        <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" />
        <!-- 追加ここまで -->
    </application>

    <uses-permission android:name="android.permission.INTERNET"/>
    <!-- ここから追加 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!-- 追加ここまで -->

</manifest>

コメントの箇所を追加。

AppActivity.java
package org.cocos2dx.cpp;

import android.content.Context;
import org.cocos2dx.lib.Cocos2dxActivity;
import android.os.Bundle;
import android.util.Log;
import com.google.android.gms.ads.AdListener;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;

public class AppActivity extends Cocos2dxActivity {

    private static InterstitialAd interstitialAd;
    private static Context context = null;

    private static native void resumeNext();

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        interstitialAd = new InterstitialAd(this);
        interstitialAd.setAdUnitId("ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx");
        requestNewInterstitial();
        final Cocos2dxActivity activity = (Cocos2dxActivity) context;
        activity.runOnUiThread(new Runnable() {
            public void run() {
                interstitialAd.setAdListener(new AdListener() {
                    @Override
                    public void onAdClosed() {
                        requestNewInterstitial();
                        resumeNext();
                    }
                });
            }
        });
    }

    private static void requestNewInterstitial() {
        AdRequest interRequest = new AdRequest.Builder().build();
        interstitialAd.loadAd(interRequest);
    }

    public static void launchInterstitial() {
        final Cocos2dxActivity activity = (Cocos2dxActivity) context;
        activity.runOnUiThread(new Runnable() {
            public void run() {
                if (interstitialAd.isLoaded()) {
                    interstitialAd.show();
                } else {
                    requestNewInterstitial();
                    resumeNext();
                }
            }
        });
    }
}
NativeCodeLauncher.h
#ifndef SEVENS_NATIVECODELAUNCHER_H
#define SEVENS_NATIVECODELAUNCHER_H

#include <jni.h>
#include "cocos2d.h"
#include <unistd.h>
#ifndef _Included_org_cocos2dx_cpp_AppActivity
#define _Included_org_cocos2dx_cpp_AppActivity

class NativeCodeLauncher {
public:
  static void launchInterstitial();
};

extern "C" {

JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_AppActivity_resumeNext();

}

#endif

#endif //SEVENS_NATIVECODELAUNCHER_H
NativeCodeLauncher.cpp
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include "NativeCodeLauncher.h"
//#include "GameScene.h"

#define CLASS_NAME "org/cocos2dx/cpp/AppActivity"

void NativeCodeLauncher::launchInterstitial() {
    cocos2d::JniMethodInfo t;
    if (cocos2d::JniHelper::getStaticMethodInfo(t, CLASS_NAME, "launchInterstitial", "()V")) {
        t.env->CallStaticVoidMethod(t.classID, t.methodID);
        t.env->DeleteLocalRef(t.classID);
    }
}

void Java_org_cocos2dx_cpp_AppActivity_resumeNext()
{
//    Scene* scene { GameScene::createScene() };
//    Director::getInstance()->replaceScene(scene);
}

都度ロードでは遅すぎるのでアプリ起動時にあらかじめ広告をロードしておく。
呼び出し側(ここではGameSceneクラス)からNativeCodeLauncher::launchInterstitial()を実行するとロードされた広告が表示される。
ロードしてから十分な時間を取っておくこと。上記のソースはロードされていない場合の処理を考慮していないがそもそも起動時に表示するのは規約違反
ユーザーが広告を閉じるとonAdClosed()がコールされるので次回の表示に備えて再び広告をロードした後、次の処理(ここではresumeNext)を呼び出す。
resumeNextではcocosの次の画面に遷移している。

AppActivity.javaはもともとapp\src\org\cocos2dx\cpp\AppActivity.javaにある。onCreateは起動時に実行されるメソッド。
NativeCodeLauncher.hとNativeCodeLauncher.cppはcocos2d-xとjavaの橋渡しをするためにapp/jni配下に新規に作成したクラス。

cocos2d-x環境構築(Windows10 Android Studio)

Windows10マシンにcocos2d-xを導入してAndroid Studioでの開発環境を構築した時のメモ。

0.必要なもの
JDK 1.8.0_101 2016/09/04時点
Android Studio 2.1.3 SDKは22が必要、NDKはr12b
Cocos2d-x 3.13 3.10では動かない
Python 2.7.12  
Apache Ant 1.9.7  
1.インストール

JDK
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
f:id:stzx:20160904103508j:plain
ダウンロードしたファイルを実行。普通に「次へ」を選んでいきインストール完了。

Android Studio
https://developer.android.com/studio/index.html
f:id:stzx:20160904104856j:plain
こちらも普通にすすんでいき問題なくインストール完了。

Python
https://www.python.org/downloads/
※2系をインストール
f:id:stzx:20160904104912j:plain
すんなりインストール完了。

Apache Ant
http://ant.apache.org/bindownload.cgi
f:id:stzx:20160904105807j:plain
ダウンロードしたファイルを解凍。Cドライブ直下に配置する。

●Cocos2d-x
ここで大ハマり。
cocos日本語サイトのトップページからのリンクをたどった先にあるv3.10をダウンロードしてインストールするもどうやっても後述のビルドができない。
どうやらバグっているらしい。最新のバージョンをダウンロードしてきてインストールするとあっさりビルドできてしまった。。
英語サイトからv3.13をダウンロード。
http://cocos2d-x.org/download/version#Cocos2d-x
f:id:stzx:20160904113803j:plain
ダウンロードしたファイルを解凍。Cドライブ直下に配置する。

2.Android Studio Setup

Android Studioを起動し初期設定を行う。
(1)JDKのパスを「detect」ボタンを押下または直接入力する。
f:id:stzx:20160904124953j:plain
(2)道なりにすすみSDKコンポーネントのセットアップを行う。
f:id:stzx:20160904125244j:plain
(3)Cofigureをクリックし、そこからSDK Managerを立ち上げる。
f:id:stzx:20160904125415j:plain
(4)以下をインストールする。(最初何が必要かわからなくて苦戦した・・・)

Android SDK Platform 22
ARM EABI v7a System Image
Android SDK Build-Tools 22.0.1
NDK

(a)「SDK Platforms」タブ押下 →右下の「Show Package Details」にチェック→Android5.1(Lollipop)配下の「Android SDK Platform 22」と「ARM EABI v7a System Image」のチェックボックスをON
f:id:stzx:20160904193106j:plain
(b)「SDK Tools」タブ押下 →右下の「Show Package Details」にチェック→Android SDK Build-Tools配下の「Android SDK Build-Tools 22.0.1」のチェックをON
f:id:stzx:20160904193435j:plain
(c)同じく「SDK Tools」タブで表示される一覧から「NDK」のチェックをON
f:id:stzx:20160904193458j:plain
(d)最後に「Apply」ボタンを押下。終わるのをじっと待つ。

3.環境変数の設定

(Windows10で復活した)スタートメニューで右クリック→「システム」→「システムの詳細設定」→「環境変数
(1)システムの環境変数の「新規」ボタンを押下。以下の設定を追加。

変数名 変数値
JAVA_HOME C:\Program Files\Java\jdk1.8.0_101
ANDROID_SDK_ROOT C:\Users\【自身のユーザー名】\AppData\Local\Android\sdk
NDK_ROOT C:\Users\【自身のユーザー名】\AppData\Local\Android\sdk
ANT_ROOT C:\apache-ant-1.9.7\bin

(2)システムの環境変数で変数「Path」を選択し「編集」ボタンを押下。環境変数名の編集画面で新規を押下し以下を追加。
・C:\Users\【自身のユーザー名】\AppData\Local\Android\sdk\platform-tools
・C:\Users\【自身のユーザー名】\AppData\Local\Android\sdk\tools\ndk-bundle
・C:\Python27

4.setup.pyを実行

スタートメニュー右クリックからコマンドプロンプトを起動し、Cocosを配置したディレクトリ直下のsetup.pyをたたく

cd c:\cocos2d-x-3.13
python setup.py

f:id:stzx:20160904132841j:plain

5.cocosプロジェクト作成

コマンドプロンプトを一旦終了し、再度コマンドプロンプトを立ち上げる。
cocos new コマンドを実行し、プロジェクトを作成する。

cocos new TestProject -p com.TestDomain.TestProject -l cpp -d C:\CocosProjects

・new のあとには任意のプロジェクト名を指定
・-p のあとにはパッケージ名を指定
・-l は言語名を指定。cppだとC++
・-d はプロジェクトを格納するディレクトリを指定

6.Application.mkを編集する

C:\CocosProjects\TestProject\proj.android-studio\app\jni\Application.mkの最後に以下の一行を追記する。

APP_PLATFORM := android-15

※Android4.0.3(API15)以降を対象

7.settings.gradle編集する

C:\CocosProjects\TestProject\proj.android-studio\settings.gradleの最後に以下の二行を追記する。

include ':Classes'
project(':Classes').projectDir = new File(settingsDir, '../Classes')
8.エミュレータを作成し起動する(実機がない場合)

(1)コマンドプロンプトからAVD Managerを起動する。

android avd

(2)AVD Managerが立ち上がったら「Device Definitions」タブを選択→「Nexus5」を選択→「Create AVD...」ボタンを押下
f:id:stzx:20160904200329j:plain
(3)作成用の画面がポップアップするので

AVD NAME 任意の名前 デフォルトのままで変更しなくてもOK。今回はNexus5に変更
Taget Android5.1.1 API Level 22  
CPU/ABI ARM(Armeabi-v7a) ほかにインストールしていないのでTarget選択時に自動で入力される
Skin No skin  
Use Host GPU チェックする  

最後に「OK」ボタンを押下する。
f:id:stzx:20160904200853j:plain
(4)エミュレータが作成される。
引き続き「start」ボタン→「Launch」の順に押し起動する。
むちゃくちゃ重い!!
なので実機を用意して接続したほうがいい。
f:id:stzx:20160904145551j:plain
※以降エミュレータの起動のみであれば、コマンドラインから

emulator -avd Nexus5

でOK。引数は先ほど作成時に付けた名前。

9.ビルド&ラン

(1)Android Studioを立ち上げる。
「Open an existing Android Studio project」から、手順5で作成したプロジェクトフォルダ(C:\CocosProjects\TestProject\proj.android-studio)を選んでOKを押す。
f:id:stzx:20160904150658j:plain
f:id:stzx:20170104215903p:plain
(2)termialウインドウを開く。
f:id:stzx:20170104221353p:plain
(3)ビルド
ターミナルウインドウで以下のコマンドを実行する。

cocos run -p android --android-studio

(2回目以降に単に実行するだけなら画面上部のRunボタン押下だけでよい。)
(4)そして、Hello World
f:id:stzx:20160904203354j:plain


AndroidでServiceを再起動させない

起動時に1回だけサービスを起動しようとしてBroadcastReceiverでACTION_BOOT_COMPLETEDを受け取るようにしてstartServiceでサービスを起動した。
これ自体はうまくいったが、しばらくすると、勝手にサービスが開始される。。
どうやらシステム側でメモリ不足になったときにサービスをKillしてリソースが空いたところで再起動しているのではと予想。
再起動しないように、onStartCommandでSTART_NOT_STICKYを返すようにすると解消された。