2016年7月21日木曜日
生産性の低いモバイル・アプリケーション開発
近年、自分が感じているモバイル・アプリケーション開発に対する状況を書いてみよう。(自分はB2B系のシステム開発をしているので、コンシューマ向けの事業を行っている方面の方にはマッチしない考察である可能性があります)
発売されているモバイル端末は多岐にわたる。iOS をはじめとする iPhone, iPad。Android をはじめとする Android 端末、タブレット端末、将来的には ウェアラブル端末。Windowsをはじめとする Windows Phone、Surface、得体のしれないタブレット端末類。どの端末をとってみても、これで開発しておけば安泰なんていう時代じゃなくなってます。少し前まであったAndroidタブレットは、現在生産しているのが数社に狭まり、今後、市場として成立するかどうかは全くの不透明。どの部分が明日には廃れていくか決め打ちするのもリスクが高すぎて選択できません。逆もまた然り。
よって、全方位で製品を提供できる事が理想です。Microsoft社も、このように考えているようです。ひとつの解決策としては Xamarin があります。しかし、考えるに、Xamarin って生産性高いの?という疑問が付きまといます。HTML5も進化して、どんどんとネイティブ・アプリとブラウザ・アプリの差が縮まっているように感じています。札幌で行われたW3C会議のDeveloper Meetup に参加して思ったのは、Worker Service や Universal Payments など、野心的な開拓と提案で、この先も、どんどんと進化していく流れは続きそうだという事です。Google は Native の有用性と Browser の有用性は、それぞれにあり、どちらも必要性を認めていますが、両者の垣根は、だんだんと曖昧になってきていると考えているようです。
ウェブは終わったと煽る記事もありますが、自分は、ウェブをベースにアプリを作成するのが幸せだと考えてます。もちろん Native コードじゃないと話にならない事もあります。アプリのパーツを考えた時、ウェブをベースとした作り方ができれば、生産性は高まります。レイアウトもコードも楽ですし、再利用できるコードも多いですし、なんならウェブ・アプリケーションとして提供するのもコストが少なくて済みます。調べてみると WebViewの出来は最悪みたいで、Android Kitkat 4.4 以上であれば ChromeViewが使えるようです。他には Crosswalk というものもあり、これなら Android と iOS、Windows Phone もプロジェクトがあるので使えそうです。
ここから先の考え方は、現在無いように思う事項です。サーバーを端末内の node.js のようなもので代用できれば最高だと思いませんか?ポートを介して接続したりするので、モバイル端末等におけるセキュリィティの概念が必要でしょうが、VirtualHost的な考え方と認証を組み合わせれば大丈夫でしょう。サーバをローカルにするメリットは、まだあります。WebStorageで頑張らなくてもサーバサイドに機能を寄せる事ができます。フォッグ・コンピューティング的な考え方等を導入する場合でも、ローカル・サーバ・サイドの機能として隠蔽する事が可能なので幅が広がります。残念ながら Android に node.js を入れようと思ったら root化が必要そうではあります。変なサービス・アプリケーションを一生懸命開発するぐらいなら、ローカル・サーバ・サイドの機能として実装するのもアリだと思いませんか?
こうやって、アプリケーション内を部分的にでもWebView的なもので置き換える事ができたら、グッと生産性が上がるんじゃないかな〜?どうでしょう?
2016年6月25日土曜日
macbook pro retina mid 2012 SSD 交換
macbook pro retina display MID 2012 モデルのSSD 256Gで使ってましたが、さすがにディスク容量が足りなくて、交換する事にしました。
mSATA 512G と ebay から macbook pro 用の mSATA Adapter の組み合わせです。
後に判明したのは、星型ドライバーが足りないという事で
macbook pro retina display MID 2012 をバラすのに必要な星形ドライバ
それと、SSD を外すのに必要な星形ドライバ を買いました。
交換し終えた後ですが、こんな感じ。



Timecapsule を持っていたので、楽観視してましたが、付け替えた SSD 512G を "Case Sensitive FS" でフォーマットしたら、ハマりました。
Case Sensitve FS とは、大文字小文字を区別するファイル・システムの事なんですが、こいつを選択すると、Timemachine が見えなくなります。この状況が理解できなくて、SSD 256G に戻したら、このSSDが交換作業で飛んじゃって、元のデータがどこにも無い状態で、焦りまくり。
なんとか、新しく mac os x をインストールして、ディスク・ユーティリティのFast AID で Timemachine を復元して、必要なファイルだけを Timemachine に入って取り出す事に成功しました。Timemachine からの復元は失敗する状況です。
Adobe Creative Cloud Photographer を契約しているので、Creative Cloud をインストールしようとしたところ、「Case Sensitive FS はサポートしていません」と怒られました。調べてみると、Case Sensitive FS をサポートしているアプリケーションは少ないとの事。
泣きながら、普通のファイル・システムで SSD 512G を初期化し直したら、なんて事もなく Timemachine から前回使用していた環境を復元できるじゃないですか!!!!!
いや、もう参りました。
という事で、2万円かけずに 256G から 512G の環境に移行する事ができました。
ディスク容量があるって、幸せです。
mSATA 512G と ebay から macbook pro 用の mSATA Adapter の組み合わせです。
後に判明したのは、星型ドライバーが足りないという事で
macbook pro retina display MID 2012 をバラすのに必要な星形ドライバ
それと、SSD を外すのに必要な星形ドライバ を買いました。
交換し終えた後ですが、こんな感じ。



Timecapsule を持っていたので、楽観視してましたが、付け替えた SSD 512G を "Case Sensitive FS" でフォーマットしたら、ハマりました。
Case Sensitve FS とは、大文字小文字を区別するファイル・システムの事なんですが、こいつを選択すると、Timemachine が見えなくなります。この状況が理解できなくて、SSD 256G に戻したら、このSSDが交換作業で飛んじゃって、元のデータがどこにも無い状態で、焦りまくり。
なんとか、新しく mac os x をインストールして、ディスク・ユーティリティのFast AID で Timemachine を復元して、必要なファイルだけを Timemachine に入って取り出す事に成功しました。Timemachine からの復元は失敗する状況です。
Adobe Creative Cloud Photographer を契約しているので、Creative Cloud をインストールしようとしたところ、「Case Sensitive FS はサポートしていません」と怒られました。調べてみると、Case Sensitive FS をサポートしているアプリケーションは少ないとの事。
泣きながら、普通のファイル・システムで SSD 512G を初期化し直したら、なんて事もなく Timemachine から前回使用していた環境を復元できるじゃないですか!!!!!
いや、もう参りました。
という事で、2万円かけずに 256G から 512G の環境に移行する事ができました。
ディスク容量があるって、幸せです。
2016年6月16日木曜日
固定小数点クラス
ずっと昔64ビット長の固定小数点クラスがほしくて、書いたやつ。
今なら、8ビット長の固定小数点クラスなんですかねー。
#pragma once
/*!
@file fixed_float.hpp
@brief 固定精度浮動小数点クラス・ヘッダ
*/
#include <boost/assert.hpp>
#include <boost/operators.hpp>
#include <limits>
//! 64ビット長固定精度浮動小数点クラス
class fixed64 :
private boost::addable<fixed64>,
private boost::subtractable<fixed64>,
private boost::multipliable<fixed64>,
private boost::dividable<fixed64>,
private boost::equivalent<fixed64>,
private boost::partially_ordered<fixed64>
{
public:
static const int exponent_ = 16; //!< 指数部長
private:
int64_t value_; //!< 値
public:
//! コンストラクタ
inline fixed64() : value_() {}
//! コンストラクタ
inline explicit fixed64(
int64_t value //!< [in] 値
) : value_(value << exponent_) {
BOOST_ASSERT( value <= (std::numeric_limits<int64_t>::max() >> exponent_) );
BOOST_ASSERT( (std::numeric_limits<int64_t>::min() >> exponent_) <= value );
}
//! コンストラクタ
inline explicit fixed64(
double value //!< [in] 値
// ) : value_(static_cast<int64_t>(value * (1LU << exponent_))) {
) : value_(static_cast<int64_t>(value * pow(2.0,exponent_))) {
//BOOST_ASSERT( value <= (static_cast<double>(std::numeric_limits<int64_t>::max() >> exponent_) );
//BOOST_ASSERT( (static_cast<double>(std::numeric_limits<int64_t>::min()) >> exponent_) <= value );
}
//! コピーコンストラクタ
inline fixed64(
const fixed64& value //!< [in] 値
) : value_(value.value_) {}
//! オペレータ +=
inline fixed64& operator += (const fixed64& rhs) {
value_ += rhs.value_;
return *this;
}
//! オペレータ -=
inline fixed64& operator -= (const fixed64& rhs) {
value_ -= rhs.value_;
return *this;
}
//! オペレータ *=
inline fixed64& operator *= (const fixed64& rhs) {
value_ = static_cast<int64_t>(
(
(
((static_cast<int64_t>(value_)) * (static_cast<int64_t>(rhs.value_)))
// 切り上げを行う
//& pow( 2.0, exponent_ - 1 )
)
>> exponent_
)
);
return *this;
}
//! オペレータ /=
inline fixed64& operator /= (const fixed64& rhs) {
value_ = static_cast<int64_t>(
(static_cast<int64_t>(value_) << exponent_) / static_cast<int64_t>(rhs.value_)
);
return *this;
}
//! オペレータ =
inline fixed64& operator = (const fixed64& rhs) { value_ = rhs.value_; return *this; }
//! オペレータ ==
inline bool operator == (const fixed64& rhs) const { return value_ == rhs.value_; }
//! オペレータ <
inline bool operator < (const fixed64& rhs) const { return value_ < rhs.value_; }
inline double get(){
return static_cast<double>(value_ / pow(2.0, exponent_));
}
inline operator double() const
{
//return double(value_ * (1 >> exponent_)) ;
return double(value_ / pow(2.0, exponent_));
//return double(value_ * (static_cast<int64_t>(1) >> exponent_)) ;
}
//! オペレータ =
inline fixed64& operator = (const double& rhs) {
value_ = static_cast<int64_t>(rhs * pow(2.0, exponent_));
return *this;
}
};
2016年5月27日金曜日
気質
幼稚園の頃の記憶は5シーンぐらいしか残っていません。
その中のひとつ。
車が走ってくるところ(そんなにスピードは出ていない)に、道路の真ん中に大の字に立って通せんぼする私。
当然、運転手にカンカンに怒られる。
そこで「やってみたかってん」という自分。
運転手は「やってみたかったんならショウガナイな」と呆れ顔で言う。
大人しい性格だったが、試してみたいと思うと衝動を抑えられない。
そんな一面があると思う。
だからこそ、試行錯誤するプログラミングの世界が性に合っているのかもしれない。
逆に日本語は、とても苦手だった。人とは、どこか感覚が異なるのかもしれない。知的ジョークの類は、ツボに嵌まらなければ、とことん何が面白いのか理解できない。その点、コードはクリアだ。結果に現れる。
そんな事を思い出した。
その中のひとつ。
車が走ってくるところ(そんなにスピードは出ていない)に、道路の真ん中に大の字に立って通せんぼする私。
当然、運転手にカンカンに怒られる。
そこで「やってみたかってん」という自分。
運転手は「やってみたかったんならショウガナイな」と呆れ顔で言う。
大人しい性格だったが、試してみたいと思うと衝動を抑えられない。
そんな一面があると思う。
だからこそ、試行錯誤するプログラミングの世界が性に合っているのかもしれない。
逆に日本語は、とても苦手だった。人とは、どこか感覚が異なるのかもしれない。知的ジョークの類は、ツボに嵌まらなければ、とことん何が面白いのか理解できない。その点、コードはクリアだ。結果に現れる。
そんな事を思い出した。
2016年5月18日水曜日
windows unistd.h 忘備録
OpenCV を Windows でコンパイルしようとしたり、何かにつけて、引っかかるので、忘備録。
ここを参照しろ。
http://d.hatena.ne.jp/tt_clown/20100602/1275457123
http://d.hatena.ne.jp/deraw/20070517/1179334643
winsock2.h を include してる部分で嵌るので、unistd.h は
#ifdef NEED_GETHOSTNAME
#ifndef _WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#pragma comment( lib, "ws2_32" )
#include <winsock2.h>
#endif
と、修正する事。
今後、コンパイルエラーで
gethostname を使用している箇所があれば、
#define NEED_GETHOSTNAME
#include <unistd.h>
#undef NEED_GETHOSTNAME
としてやれば良い。
面倒でも、こうしないと、あちこちエラーで悩まされるだろう。
3rdparth 中の zlib ライブラリの
zconf.h
ここで、Z_HAVE_UNISTD_H の定義を消す事
ACCESS_MASK が winnt.h と、namespace cv::ACCESS_MASK でバッティングしている。
test_grfmt.cpp はテストユニットみたいなんで、コンパイルのターゲットから外してしまうか、
// using namespace cv;
のように、コメントアウトして、地道に cv::Mat みたいに namespace を付けて回るか?
以上。
補足:
cmake-gui でエラーとか、com をコンパイルでエラーとか、全部、管理者権限が脳足りんのじゃ。
追記:
VC11とか、include dir の設定が共通化でけん。
ここを参照しろ。
http://d.hatena.ne.jp/taiyakisun/20130406/1365248215
VC11 は、こんな感じ。
よく無いって怒られる。cstdint とか、unistd.h とかを入れといたった。
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IncludePath>$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);$(WindowsSdkDir)include;D:\Libs\cstdint</IncludePath>
<LibraryPath>$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);$(WindowsSdkDir)lib;</LibraryPath>
</PropertyGroup>
</Project>
2016/07/28追記:$(WindowsSDK_IncludePath); では、SDKのパスが取れず、$(WindowsSdkDir)include を追加した。lib も同様
http://d.hatena.ne.jp/tt_clown/20100602/1275457123
http://d.hatena.ne.jp/deraw/20070517/1179334643
winsock2.h を include してる部分で嵌るので、unistd.h は
#ifdef NEED_GETHOSTNAME
#ifndef _WINDOWS_
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#pragma comment( lib, "ws2_32" )
#include <winsock2.h>
#endif
と、修正する事。
今後、コンパイルエラーで
gethostname を使用している箇所があれば、
#define NEED_GETHOSTNAME
#include <unistd.h>
#undef NEED_GETHOSTNAME
としてやれば良い。
面倒でも、こうしないと、あちこちエラーで悩まされるだろう。
zconf.h
ここで、Z_HAVE_UNISTD_H の定義を消す事
#ifndef ZCONF_H #define ZCONF_H /* #undef Z_PREFIX */ //#define Z_HAVE_UNISTD_H
ACCESS_MASK が winnt.h と、namespace cv::ACCESS_MASK でバッティングしている。
test_grfmt.cpp はテストユニットみたいなんで、コンパイルのターゲットから外してしまうか、
// using namespace cv;
のように、コメントアウトして、地道に cv::Mat みたいに namespace を付けて回るか?
以上。
補足:
cmake-gui でエラーとか、com をコンパイルでエラーとか、全部、管理者権限が脳足りんのじゃ。
追記:
VC11とか、include dir の設定が共通化でけん。
ここを参照しろ。
http://d.hatena.ne.jp/taiyakisun/20130406/1365248215
VC11 は、こんな感じ。
よく無いって怒られる。cstdint とか、unistd.h とかを入れといたった。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<IncludePath>$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);$(WindowsSdkDir)include;D:\Libs\cstdint</IncludePath>
<LibraryPath>$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);$(WindowsSdkDir)lib;</LibraryPath>
</PropertyGroup>
</Project>
2016年5月13日金曜日
登録:
投稿 (Atom)