Provisioning Profileを変えても駄目で、Xcode5の事例で出てたrestartも駄目で開発機再起動も駄目で何度やっても弾かれるしどうしようもなくなってたが、Application loaderを使うことで解決。
https://developer.apple.com/library/ios/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide_Jpn/Chapters/SubmittingTheApp.html#//apple_ref/doc/uid/TP40014483-CH33-SW8
Organizerでipaにexportして(Save for iOS App Store Deployment)、Application Loaderからアップロードするとそのままアップロード出来た。
というか、新生TestFlightはなぜあんな処理に時間かかるのか。アップロード完了してからアクティブになるまでひどい時だと30分くらいかかる。
2014年12月16日火曜日
2014年12月4日木曜日
単一Fragmentを表示するActivityの共通化
全画面想定のFragmentをActivityで取り回したい場合。AaaFragment, BbbFragmentに合わせてAaaActivity, BbbActivityとか作るのは面倒なのでActivityのWrapperを共通化。
Fragmentは public static XxxFragment newInstance(Bundle args);を実装している想定。
画面遷移時は、FragmentからならWrapperActivity.openFragmentActivity(getActivity(), SecondFragment.class, secondFragmentsArguments); という感じで行える。
Fragmentは public static XxxFragment newInstance(Bundle args);を実装している想定。
画面遷移時は、FragmentからならWrapperActivity.openFragmentActivity(getActivity(), SecondFragment.class, secondFragmentsArguments); という感じで行える。
package hoge.fuga.activities;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.View;
import android.view.View.OnClickListener;
import jp.arithmetic.arithmusic.R;
import jp.arithmetic.arithmusic.model.FragmentReplacer;
public class WrapperActivity extends Activity {
public static final String TAG = "WrapperActivity";
public static final String ARGS_FRAGMENT = "app-fragment";
/**
* 1つのFragmentを全面に表示する共通化Activity
* @param fromActivity
* @param clazz
* @param args
*/
public static void openFragmentActivity(Activity fromActivity, Class clazz, Bundle args) {
// setup bundle
if (args == null) {
args = new Bundle();
}
args.putString(ARGS_FRAGMENT, clazz.getName());
// setup intent
Intent i = new Intent(fromActivity, WrapperActivity.class);
i.putExtras(args);
// start activity
fromActivity.startActivity(i);
}
/**
* close
* @param fromActivity
*/
public static void closeFragmentActivity(Activity fromActivity) {
fromActivity.finish();
}
public static void closeToStartActivity(Activity fromActivity) {
Intent i = new Intent(fromActivity, SomeStartActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
fromActivity.startActivity(i);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_empty_container);
// intentパラメータ優先
Bundle args = (getIntent() != null) ? getIntent().getExtras() : savedInstanceState;
if (args == null) {
throw new RuntimeException("Wrapper: Empty arguments");
}
// 呼び出しFragment特定、初期化
String className = args.getString(ARGS_FRAGMENT);
if (className == null || className.isEmpty()) {
throw new RuntimeException("Wrapper: Empty class name");
}
Fragment f = null;
try {
Class clazz = Class.forName(className);
Method newInstance = clazz.getMethod("newInstance", Bundle.class);
f = (Fragment)newInstance.invoke(null, args);
replaceFragment(f);
} catch (ClassNotFoundException e) {
e.printStackTrace();
finish();
} catch (NoSuchMethodException e) {
e.printStackTrace();
finish();
} catch (IllegalAccessException e) {
e.printStackTrace();
finish();
} catch (IllegalArgumentException e) {
e.printStackTrace();
finish();
} catch (InvocationTargetException e) {
e.printStackTrace();
finish();
}
}
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
closeFragmentActivity(this);
} else {
super.onBackPressed();
}
}
public void replaceFragment(Fragment f) {
getSupportFragmentManager()
.beginTransaction()
.addToBackStack(null)
.replace(R.id.empty_container, f)
.commit();
}
}
2014年11月17日月曜日
AndroidでBlur effect
要はiOS7以降のBlur effectぽいことをしたい場合。
・android-stackblurを使う。
・RenderScriptはradiusがMAX25までしか設定できないぽいので期待しない。
・Eclipse想定
・stackblurをDLして、StackBlurディレクトリをプロジェクトimport。
・プロジェクトのコンテキストメニューから、Build Project
・libsディレクトリ配下にビルド成果物ができるので、まるっと開発プロジェクトのlibs配下にコピー
※stackblurのrenderscript8.jarでの競合が無ければIs Libraryでの追加でも大丈夫かも。
>そうするとDialogの位置とサイズが崩れる。styleで色々設定しても駄目。
>なのでAlertDialogは諦めて自前でCustomViewを作る必要がある。
>それも含めたベースのDialogFragment
/hoge/fuga/AbstractDialogFragment.java
/res/layout/dialog_base.xml
・Dialogを使う場合はAbstractDialogFragmentをextend。
・dialogの設定をするときはonCreateDialog()をoverrideしてsuper.onCreateDialog()してから設定。
・ViewはonCreateView()をoverrideして、super.onCreateView()してから子Viewを作り、super.addViewToContainer(childDialogView)する。
GPUImage for androidがblur effect対応してくれたら嬉しいな〜。
・android-stackblurを使う。
・RenderScriptはradiusがMAX25までしか設定できないぽいので期待しない。
・Eclipse想定
StackBlurライブラリの開発プロジェクトへのインストール
・NDK導入・stackblurをDLして、StackBlurディレクトリをプロジェクトimport。
・プロジェクトのコンテキストメニューから、Build Project
・libsディレクトリ配下にビルド成果物ができるので、まるっと開発プロジェクトのlibs配下にコピー
※stackblurのrenderscript8.jarでの競合が無ければIs Libraryでの追加でも大丈夫かも。
利用例
StackBlurManager _stackBlurManager = new StackBlurManager(orig); _stackBlurManager.processNatively(radius); Bitmap blurred = _stackBlurManager.returnBlurredImage();
利用例:Dialogで使う場合
Dialogに背景画像設定する場合は、DialogのWindow層に設定。>そうするとDialogの位置とサイズが崩れる。styleで色々設定しても駄目。
>なのでAlertDialogは諦めて自前でCustomViewを作る必要がある。
>それも含めたベースのDialogFragment
/hoge/fuga/AbstractDialogFragment.java
package hoge.fuga;
import com.enrique.stackblur.StackBlurManager;
import hoge.fuga.R;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnShowListener;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
abstract public class AbstractDialogFragment extends DialogFragment implements OnShowListener {
public static final String TAG = "AbstractDialogFragment";
protected Dialog mDialog;
private ViewGroup mContainer;
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mDialog = super.onCreateDialog(savedInstanceState);
// Get status bar height
Rect rectgle= new Rect();
getActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(rectgle);
int statusBarHeight = rectgle.top;
// Screen shot http://stackoverflow.com/a/9596132/1121509
View v = getActivity().getWindow().getDecorView();
v.setDrawingCacheEnabled(true);
Bitmap ss = v.getDrawingCache();
if (ss != null) {
ss = Bitmap.createBitmap(ss, 0, statusBarHeight, ss.getWidth(), ss.getHeight() - statusBarHeight);
}
v.setDrawingCacheEnabled(false);
// Blur effect
if (ss != null) {
int radius = (int) (ss.getHeight() * 0.25);
radius = radius > 100 ? 100 : radius;
StackBlurManager _stackBlurManager = new StackBlurManager(ss);
_stackBlurManager.processNatively(radius);
Bitmap blurred = _stackBlurManager.returnBlurredImage();
mDialog.getWindow().setBackgroundDrawable(new BitmapDrawable(getResources(), blurred));
}
// without title
mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// set listener
mDialog.setOnShowListener(this);
return mDialog;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// コンテナの設定
mContainer = (ViewGroup) inflater.inflate(R.layout.dialog_base, container, false);
return mContainer;
}
public void addViewToContainer(View contentView) {
((ViewGroup) mContainer.findViewById(R.id.dialog_container)).addView(contentView, 0);
}
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@Override
public void onShow(DialogInterface dialog) {
// サイズ調整、このタイミングでないとうまく動かない
Point size = new Point();
Display display = getActivity().getWindowManager().getDefaultDisplay();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
display.getSize(size);
} else {
size.x = display.getWidth();
size.y = display.getHeight();
}
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams)mContainer.getLayoutParams();
lp.width = size.x;
lp.height = size.y;
ViewGroup dialogContainer = (ViewGroup) mContainer.findViewById(R.id.dialog_container);
FrameLayout.LayoutParams lp2 = (FrameLayout.LayoutParams) dialogContainer.getLayoutParams();
lp2.topMargin = (size.y - dialogContainer.getMeasuredHeight()) / 2;
}
}
/res/layout/dialog_base.xml
・Dialogを使う場合はAbstractDialogFragmentをextend。
・dialogの設定をするときはonCreateDialog()をoverrideしてsuper.onCreateDialog()してから設定。
・ViewはonCreateView()をoverrideして、super.onCreateView()してから子Viewを作り、super.addViewToContainer(childDialogView)する。
GPUImage for androidがblur effect対応してくれたら嬉しいな〜。
ElasticSearchのインストール
検索サーバElasticSearchのインストールと設定。AWS(EC2)での利用。2014.11.15現在。
http://stackoverflow.com/questions/25518908/issues-after-elasticsearch-1-3-2-upgrade
※kuromoji, cloud-awsはelasticsearchのバージョンに応じて入れるバージョンが変わる。それぞれ公式のsetup情報にバージョン対応表が載ってるので確認。上記は1.4.0の場合。
※host_typeはpublic_ipでも問題ないと思われる(未確認)
※ regionなしだと接続できずv2.4.0
ttp://ipaddar:9200/_plugin/HQ/
プラグインをインストールできてれば、上記でアクセス可能。
Multi masterは出来ないので複数台構成にしてもmasterサーバはひとつ。可用性を考えるなら、dataを持たないゲートウェイ的なマスタを作り、そこに子をぶら下げる形か。
trittonn, mroonga, Lucene, Solrと比べて検索システムの中ではだいぶ導入が容易な印象。運用考えると日本語対応した今はCloudSearch使ったほうが楽かも。ただElasticSearchからCloudSearchへのスイッチはサービス拡大に応じて行えるレベルかな。
1. Javaのバージョンを1.7.xにする
もし問題なければ飛ばす。単純アップデートだと古いのものこってて競合するそうなので、古いのはremoveするhttp://stackoverflow.com/questions/25518908/issues-after-elasticsearch-1-3-2-upgrade
# java -version # yum install java-1.7.0-openjdk # yum remove install openjdk-6-jre # yum remove java-1.6.0-openjdk
2. ElasticSearch本体及びプラグインのインストール
# rpm -ivh https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.0.noarch.rpm # /usr/share/elasticsearch/bin/plugin --install mobz/elasticsearch-head # /usr/share/elasticsearch/bin/plugin --install royrusso/elasticsearch-HQ # /usr/share/elasticsearch/bin/plugin --install elasticsearch/elasticsearch-analysis-kuromoji/2.4.1 # /usr/share/elasticsearch/bin/plugin --install elasticsearch/elasticsearch-cloud-aws/2.4.0※head, HQはおこのみで。
※kuromoji, cloud-awsはelasticsearchのバージョンに応じて入れるバージョンが変わる。それぞれ公式のsetup情報にバージョン対応表が載ってるので確認。上記は1.4.0の場合。
3. 設定ファイル
1台構成ならcluster.name位設定しとけばほかはいらない。EC2で複数台サーバを連携する場合は自動でネゴシエートするためのbroadcastが使えないので、cloud-awsプラグインを入れて設定を行う。また利用するEC2インスタンスはSecurity Groupで9200-9400のPortを開けておく。cluster.name: hoge # multi-server for EC2 settings discovery.zen.ping.multicast.enabled: false cloud.aws.access_key: XXXX cloud.aws.secret_key: XXXX cloud.aws.region: ap-northeast discovery.ec2.host_type: private_ip discovery.ec2.ping_timeout: 5s discovery.type: ec2 discovery.ec2.groups: IDorNAME※access_key, secret_keyはAWSのIAM Roleの設定で、EC2のDescribeの権限を付けたものを設定
※host_typeはpublic_ipでも問題ないと思われる(未確認)
※ regionなしだと接続できずv2.4.0
4. 起動
# chkconfig --add elasticsearch on # /etc/init.d/elasticsearch start
他
PHPのクライアントをComposerでインストール
$ php ../composer.phar require elasticsearch/elasticsearch:">=1.0"
HQ, headによる状態確認
ttp://ipaddar:9200/_plugin/head/ttp://ipaddar:9200/_plugin/HQ/
プラグインをインストールできてれば、上記でアクセス可能。
Multi masterは出来ないので複数台構成にしてもmasterサーバはひとつ。可用性を考えるなら、dataを持たないゲートウェイ的なマスタを作り、そこに子をぶら下げる形か。
trittonn, mroonga, Lucene, Solrと比べて検索システムの中ではだいぶ導入が容易な印象。運用考えると日本語対応した今はCloudSearch使ったほうが楽かも。ただElasticSearchからCloudSearchへのスイッチはサービス拡大に応じて行えるレベルかな。
CakePHP3の環境切り分け
CakePHP3でのdevelopment/productionなどの環境ごとの設定をどうするか。
公式ドキュメントを読むと、どうもbootstrapで設定を追加読み込みするよう促しているのでそれに倣う。
以下の設定で、基本は本番環境になり、developmentの環境変数を設定することで、開発環境の設定を上書きする形になる。
Apacheの場合は
公式ドキュメントを読むと、どうもbootstrapで設定を追加読み込みするよう促しているのでそれに倣う。
以下の設定で、基本は本番環境になり、developmentの環境変数を設定することで、開発環境の設定を上書きする形になる。
config/bootstrap.php
app.phpの読み込みをした後に、追加の設定を環境に応じて読み込む。config/app_development.phpに開発環境で上書きする設定を記述する。try {
Configure::config('default', new PhpConfig());
Configure::load('app.php', 'default', false);
// Add this 3 lines
if (env("APPLICATION_ENV") == "dev" || env("APPLICATION_ENV") == "development") {
Configure::load('app_development.php', 'default', true);
}
} catch (\Exception $e) {
die('Unable to load config/app.php. Create it by copying config/app.default.php to config/app.php.');
}
Server setting
nginxの場合はvirtualhostなどserverの設定でphpに渡す環境変数を設定する。server {
location ~ \.php$ {
fastcgi_param APPLICATION_ENV development;
}
}
Apacheの場合は
SetEnv APPLICATION_ENV developmentかな。最近触ってないから忘れたけど。
2014年10月23日木曜日
ChromeでAjax(POST, PUT, DELETE)の実行テスト
1. 下記jsの2行目にHTTPMethod、URL、urlencoded形式のリクエストデータを追加
2. Chromeの開発者ツールのConsoleなどページでjs実行できる画面開いて以下実行。
(function(m,u,p){var x=new XMLHttpRequest();x.onreadystatechange=function(){if(x.readyState==4)console.log("res:"+x.responseText);};x.open(m,u);x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader('Content-Type','application/x-www-form-urlencoded');x.send(p)})
("POST","http://example.jp/”, 'url=encoded¶meters=string');
2014年9月23日火曜日
CakePHP3.0でDBを使わずBasic認証
CakePHPのBasic認証はdb使わなくちゃいけなくて不便。そんなユーザ増やすわけでもないしソースに記述があれば十分。みたいな時に使う。
passワードの記述は適当なsalt混ぜてmd5とかでハッシュ化しとくとより良さそう。
passワードの記述は適当なsalt混ぜてmd5とかでハッシュ化しとくとより良さそう。
代替クラス
# src/Auth/BasicwodbAuthenticate.php $p) {
if ($username === $u && $password === $p) {
return array('username' => $username);
}
}
return false;
}
}
設定
# src/config/app.phpreturn [
'App' => [
'Basicwodb' => ['some-username' => 'some-pass'],
],
];
登録:
投稿 (Atom)