No iOS Development certificate was found に対処する
iOSでの開発を久しぶりに、しかも新しい機種で行おうとしたらxcodeで「No iOS Development certificate was found」というエラーになり、デバイスが登録できないという現象に陥ったので、対処方法を忘れないようにメモしておく。
単にProvisioning Profileの有効期限切れなのだが、どうやったかすっかり忘れてしまっている。これまた久しぶりに iTunes Connect へアクセスし、「Certificates, Identifiers & Profiles」というメニューに入る。左メニューの「Provisioning Profiles」にて[+]マークをクリックすると新しいプロファイルを作成する手順に移行する。
新しいプロファイルの作成過程で、証明書も期限が切れていると証明書(ios_development.cer)も作り直すことができる。この時別の証明書(CertificateSigningRequest.certSigningRequest)が必要になる。もしこれも有効なものが無ければキーチェーンアクセスから認証局に証明書を要求する。これで無事にプロファイル(*.mobileprovision)が作成され、ダウンロードが可能になる。
最後にxcodeのOrganizerでダウンロードしたプロファイルを追加すればデバイスを登録できるようになる。
UIButtonに任意の画像を使ってタップ時にハイライトさせる
今更ではあるがメモしておく。
画面上にボタンを用意するにはUIButtonを使うが、標準の外観では物足りない場合はボタンに見える画像を用意することが多い。ところがHTMLのつもりでImageプロパティに画像を指定してTitleプロパティにラベルを指定…とやってしまうと画像だけ表示されてラベルが表示されない。
その場合はラベルも含んだボタン画像を用意するというのも一つの方法だが、ボタンの種類が多い場合は用意すべき画像が多くなってしまう。背景画像(BackgroundImageプロパティ)に画像を設定する。
ただ、単純に背景画像を設定してもいいが、より細かく表現するにはボタンの状態別に画像を用意する。非活性状態、有効状態、選択状態、押下状態の4種類あればよいだろう。それぞれ次のようなコードになる。
1 2 3 4 | [button setBackgroundImage:[UIImage ...] forState:UIControlStateDisabled]; [button setBackgroundImage:[UIImage ...] forState:UIControlStateNormal]; [button setBackgroundImage:[UIImage ...] forState:UIControlStateSelected]; [button setBackgroundImage:[UIImage ...] forState:UIControlStateHighlighted]; |
これを利用してトグルボタンのような機能を持たせることもできる。タッチイベントを捕捉してOFF状態であればONにし、ON状態であればOFFにするという具合だ。しかし、これがうまく動作してくれない。いや、トグルは動作するのだが、OFF状態のボタン押下中のハイライト画像が表示されないのだ。
まず、adjustsImageWhenHighlightedプロパティはfalseにしておこう。これがtrueだとOFF状態のボタンを押下した時にハイライト画像ではなく、ボタン全体が暗転してしまう。だがそれでもまだ不充分。
どうやらUIControlState~はビット和を指定することが可能らしい。つまりON状態とOFF状態だけでなく、OFF状態のボタンを押下中やON状態のボタンを押下中という表現ができる。それを改良したのが次のコード。
1 2 3 4 5 | [button setBackgroundImage:[UIImage ...] forState:UIControlStateDisabled]; [button setBackgroundImage:[UIImage ...] forState:UIControlStateNormal]; [button setBackgroundImage:[UIImage ...] forState:UIControlStateSelected]; [button setBackgroundImage:[UIImage ...] forState:(UIControlStateHighlighted|UIControlStateNormal)]; [button setBackgroundImage:[UIImage ...] forState:(UIControlStateHighlighted|UIControlStateSelected)]; |
これでボタンの状態に関係なく、ボタン押下中はハイライト画像を表示させることができた。
“Unknown class ‘class name’ in Interface Builder file” に対処する
久しぶりにiOSアプリの開発環境をいじったら久しぶりにハマったのでメモしておく。
現象としてはXcodeからプロジェクトをビルドしてシミュレータで起動しようとすると、起動できずにアプリは終了し、以下のエラーメッセージを吐くというもの。実際には「class name」には作成したクラス名が入る。
Unknown class ‘class name’ in Interface Builder file
対処方法は次の通り。
- XcodeのProject Navigatorでプロジェクトのルートを選択して設定画面を開く。
- Standard editorの左ペインで TARGETS 以下の項目を選択する。
- Standard editorの右ペインの Build Phases タブを選択する。
- Compile Sources のグループを開き、不足しているクラスのソース本体(.m)を追加する。
- ビルド及び実行する。
これはInterface Builderから特定のクラスが見えないという状況なのだが、例えば新規にプロジェクトを作成した時に、他のプロジェクトで作成したクラスをファイルのコピーによって追加したような場合に発生する。(クラスを新規作成で追加した場合は自動でBuild Phaseに追加されるようだ。)
String Encoder / Decoder バージョン1.0.0公開
ダウンロード
◆ これは何か?
- 文字列を符号化および複合するためのツールです。 現在はURLエンコード(パーセントエンコーディング)、およびBase64に対応しています。
URLエンコードはRFC3986とRFC1866に対応しています。両者の違いは、RFC3986が半角スペースを「%20」と符号化するのに対し、RFC1866では半角スペースを半角「+」記号に符号化します。 - 主にWebアプリケーションの開発者、テスト実施者のために作りました。 HTTPのテストツールやcurlコマンドなどで URLに直接パラメータを埋め込みたい場合に役立ちます。
- それだけでなく、Webサイトの運用者またはマーケッターで、 検索ワードなどの収集を行っている方にとっても有用です。多くのキーワード集計ツールは自動で複合してくれますが、何らかの理由でうまく複合できない場合があります。そんな時に手動で変換できます。
- Web上に本ソフトウェアと同等の機能を提供するサービスがありますが、 本ソフトウェアはネットワーク接続を必要としないので、インターネットに接続できないような閉じたネットワーク環境での実行や、 それらのWebサービスにログを残したくない場合などに適しています。またトラフィックによるレスポンスの悪化を気にする必要もありません。
◆ 動作環境
.NET Framework 4.0 が動作する環境。
(Client Profileでは動作しません。フルインストールが必要です。)
- お使いのコンピュータにまだ .NET Framework 4.0 を導入されていない場合は以下のURLからダウンロードしてインストールを行う必要があります。
https://www.microsoft.com/ja-jp/net/netfx4/download.aspx
◆ 使い方
- 変換方法を以下から選びます。
URL Encode/URL Decode/Base64 Encode/Base64 Decode - 文字列の文字集合(Charset)を以下から選びます。
ASCII/UTF-8/UTF-16/Shift_JIS/EUC-JP/ISO-2022-JP - Input欄にテキストを貼り付けます。Output欄に変換文字列が表示されます。
- コピーボタンを押すとクリップボードにコピーされます。
◆ 利用条件
- 本ソフトウェアはフリーウェアとして公開しています。ご利用に当たり料金は発生いたしません。
- 著作権はクロスラボラトリーにあります。
◆ 免責事項
- 本ソフトウェアは無保証です。ご利用によって生じたいかなる損害に対しても作者は責任を負わないものとします。ご自身の責任においてご利用ください。
—
更新履歴
- v0.0.1 (2013-04-01)
公開 - v0.0.2 (2013-04-14)
.NET Framework 4.0のClient Profileのみがインストールされている場合にURLエンコードを行うと例外が発生するのでダイアログを表示するようにした。 - v1.0.0 (2013-05-25)
アイコンを追加して正式版とする
Qt 5.0.2で静的リンク可能なQtをビルドする
Qt5.0.2がリリースされた。以下からダウンロードできる。
http://qt-project.org/downloads
ここでは Qt 5.0.2 for Windows 32-bit (MinGW)
をまずダウンロードして C:\Qt\Qt5.0.2
のような場所にインストールした。ライブラリを動的リンクする設定でビルドするといくつか必要なdllファイルを一緒に配布しなければならないので、必要なライブラリは静的にリンクしたいと思う。だが、デフォルトでは静的リンクが出来るようになっておらず、静的リンクを実現するにはQtそのものをソースファイルからビルドしなければならない。Qt5.0.1ではエラーが出てどうにもならなかったが、Qt5.0.2では修正されてビルドできるようになった。
そこでまず、上のURLにアクセスして qt-everywhere-opensource-src-5.0.2.zip
のような名前でアーカイブされているソースファイルをダウンロードし、例えば C:\Qt\qt_src_5.0.2
のような場所に解凍する。
そしてビルド用に C:\Qt\qt_static_5.0.2
のようなディレクトリを作成する。
1 2 3 4 5 | > cd C:\Qt\qt_static_5.0.2 > set QMAKESPEC=win32-g++ > set QTDIR= > set PATH=%PATH%;C:\Qt\Qt5.0.2\Tools\MinGW\bin; > ..\qt_src_5.0.2\configure.bat -release -opensource -nomake examples -static -opengl desktop |
ここで -nomake examples
オプションが無いとexamplesのビルド中にエラーでこけてしまった。
configure が正常終了したらメイクを行う。
1 | > mingw32-make |
これで2時間ほど放置して出来上がり。
ネットで検索すると、もっと古いバージョンでのビルドの方法が載っていたりするが、このバージョンでビルドするには全くと言っていいほど役に立たないので注意する。(例えばqmake.confを編集するとか。編集してメイクしたらエラーでこけてしまった。)
Windows版EclipseのSymfonyプラグインで任意のバージョンを使う
私は以前からPHPの開発にも統合開発環境ソフトのEclipseを利用してきた。それでも5年程前のものはあまり使い勝手が良いとは言い切れなかった面があるが、WTPそしてPDTの進化に伴って今では私にとって必要不可欠なツールとなっている。
そしてPHPのWebアプリケーションフレームワークであるSymfony2。バージョン1系に比べたら格段に取っ付き易くなった。そしてさらに開発効率を向上させるのがEclipse用のSymfonyプラグインだ。Eclipseで新規Symfonyプロジェクトを作成すると、基本的なWebアプリケーションのアーキテクチャは既に出来上がっている状態で開発をスタートできる。
ところがこのプラグイン、Symfonyのバージョンは2.0.17と2.1.2しか用意されていない。一応カスタムレイアウトと称して、Symfonyのサイトからダウンロードした任意のバージョンのアーカイブファイルを利用してプロジェクトのセットアップができるようになっている。なのにWindowsで作業をした場合、プラグインの不具合のためかエラーとなってしまい先に進まない。今回はそれを解消する力技を紹介したい。
尚、Eclipseのバージョンは3.7(Indigo)、Symfonyプラグインは2013年4月10日現在マーケットプレイスで入手できる最新版を用いた。Symfonyのバージョンは2013年4月10日現在公式サイトでダウンロードできるバージョン2.2.1を試した。
まず普通に設定を試みる。Eclipseのメニューから ウィンドウ>設定 を選択し、設定画面を開く。設定画面のメニューから Symfony>Distributions を選択し、 Custom Symfony distributions 欄の「新規」ボタンを押下する。ファイルダイアログが開いたらアーカイブ(例えば Symfony_Standard_Vendors_2.2.1.tgz
)を選ぶのだが、何故かファイルのあるフォルダを開いてもファイルが見えない。それでもファイル名を直接入力することで登録は可能だ。
次に今登録したアーカイブを使ってSymfonyプロジェクトを作ってみよう。Eclipseメニューの ファイル>新規>プロジェクト… を選ぶ。新規プロジェクトダイアログが開いたら Symfony>Symfony Project を選んで「次へ」ボタンを押下する。 New Symfony project ダイアログが表示されるのでプロジェクト・レイアウトの欄のリストから Custom project layout を選ぼう。すると隣のアーカイブのリストの表示が不自然ではないだろうか。アーカイブを1つしか登録していなくてもリストは2項目表示され、しかも1つ目はドライブレターのみだ。試しに「プロジェクト名」欄に入力してもエラーが表示されて先には進めないはずだ。
これは推測だが、おそらくWindowsのパスに含まれるコロン「:」をUnix系でいうパス区切り文字として処理してしまっているのではないだろうか。その証拠に、リストのアーカイブ名のパスの最後にセミコロン「;」がくっついている。セミコロンはWindowsにおけるパス区切り文字だ。(作者はもしかしたらMacで開発しているのかもしれない。)
しばらく悩んだのだが、これを解決するには直接設定ファイルを書き換えるしかないと思った。この設定ファイルは以下の場所にある。
1 | {ワークスペースのパス}\.metadata\.plugins\org.eclipse.core.runtime\.settings\com.dubture.symfony.ui.prefs |
このファイルをテキストエディタで開き、
1 | Symfony\ distributions=C\:\\path\\to\\archive\\Symfony_Standard_Vendors_2.2.1.tgz; |
となっているところを次のように書き換える。但し、ドライブレターを省略するため、Eclipseをインストールしているドライブである必要がある。
1 | Symfony\ distributions=/path/to/archive/Symfony_Standard_Vendors_2.2.1.tgz\: |
書き換えたら保存してEclipseを再起動してみよう。そして先ほどと同じ様に新規プロジェクトを作成してみて欲しい。今度はエラーもなく、最新のバージョンでSymfonyプロジェクトをセットアップできたはずだ。
余談だが、これをやったら設定画面からは設定し直すことはできない。尤も、設定し直しても全く意味ないが。そのうち作者が気付いてこのような手段をとる必要が無くなるだろう。
—
jQueryにてチェックボックスの状態を取得する
よくWebアプリケーションで一覧表があると、それぞれのレコード(行)の頭にチェックボックスがついていて、チェックしたものをまとめて更新したり削除したりするようなUIを見かける。そして必ずと言って良いほどそれらチェックボックスの全てにチェックを入れたり外したりする操作ができるようになっている。
その操作の手段としては[全選択][全解除]というボタンが用意されていたり、ボタンの代わりに全選択/全解除用のチェックボックスが見出し欄に設けてあったりする。どちらの場合でもjQureyを知らなかった時には実装するのはそこそこ大変だったが、jQueryを使えば簡単にできる。ところが後者の場合にちょっと躓いてしまったので整理してみたい。
後者の場合というのは、全選択/全解除用のチェックボックスがクリックされた時に、チェックの状態によって全選択するか全解除するかを決める。だが、チェックボックスのチェック状態を取得しようとして以下のようなコードを書くと動きそうなのだがうまくいかない。
1 2 3 4 5 | $(function(){ $("#checkAll").click(function() { $("#anyForm :checkbox").attr("checked", $("#checkAll").attr("checked")); }); }); |
オブジェクトの属性は .attr()
メソッドで取得すると覚えていた。ところが公式のドキュメントをよく読んでみると、オブジェクトの属性(プロパティ)は .prop()
で取得した方が良いようだ。以前はうまくいっていたと思っていたのはボタンで実装していたからだった。公式ドキュメントの一部を抜粋して意訳しよう。
jQuery1.6より前のバージョンでは.attr()
メソッドで属性を返す時にプロパティを考慮することがあり、時として矛盾した動作をすることがあった。1.6以降のバージョンでは、.prop()
メソッドが厳密にプロパティを返し、その一方で.attr()
メソッドは属性を返す。 (中略)
W3Cの仕様によると、checked属性は二値なので値があるときはtrue、値が無いか空の場合はfalseである。二値の属性は全て同様である。
尚、公式ドキュメントにはさらに記法による振る舞いの比較表が掲載されている。
コード例 | jQueryバージョン | 返される値 |
---|---|---|
elem.checked | — | true(可変) |
$(elem).prop("checked") | 1.6以降 | true(可変) |
elem.getAttribute("checked") | — | “checked”(初期状態・不変) |
$(elem).attr("checked") | 1.6.0 | “checked”(初期状態・不変) |
$(elem).attr("checked") | 1.6.1以降 | “checked”(可変) |
$(elem).attr("checked") | 1.6より前 | true(可変) |
これを見る限り以前は動いていたというのは錯覚ではなかったようだ。つまり、もしjQueryのバージョン1.6以降を利用しているのなら、先ほどのコードは次のように書かなければならないということになる。
1 2 3 4 5 | $(function(){ $("#checkAll").click(function() { $("#anyForm :checkbox").prop("checked", $("#checkAll").prop("checked")); }); }); |
お飲み物 | |
---|---|
ビール(中瓶) | |
日本酒(1合) | |
焼酎 麦・芋(グラス) | |
ウィスキー(シングル) | |
ワイン 赤・白(グラス) |
Qtでウィンドウを大きくしてもウィジェットのサイズが変わらない?
Qt Designerを使ってGUIアプリケーションを作成する時、フォームに部品(ウィジェット)をペタペタ貼り付けていくだけではレイアウトが固定されており、例えばテキストエディタみたいなものを作ろうとしてText Editウィジェットを貼り付けても
実行してウィンドウを拡げた時にText Editの大きさが固定されたままである。
そこでプロパティエディタでウィジェットの sizePolicy
プロパティを例えば Expanding
に変更しただけでは何らの変化も起きなかった。「Qt」で検索してみてもコードで実現するサンプルはたくさん見つかるが、Qt Designerを使って実現する例はなかなか見つからなかった。そこで「Qt Designer」で検索すると多少ヒントになりそうな記述が見つかった。
GUIアプリケーションプロジェクトを新規作成したばかりの時、フォームは mainwindow.ui
というのが1つあるだけで、それを開くと MainWindow
というオブジェクトに centralWidget
というオブジェクトが乗っているだけだ。この状態でウィジェットを貼り付けていき、 MainWindow
を選択して右クリックするとコンテキストメニューが開くはずだ。そしてコンテキストメニューの一番下に「レイアウト」という項目が無いだろうか。その中の適当な項目を選んでレイアウトを設定すると、オブジェクトインスペクタに表示されている centralWidget
のアイコンについていた禁止マークが無くなる。
↓↓↓
この状態でビルドし、ウィンドウを拡げてみて欲しい。ウィンドウの大きさに合わせてウィジェットが大きくなっていないだろうか。
jQueryで全ての要素を選択する “*”
全ての要素を選択する。
尚、このセレクタを使用すると動作が非常に遅くなるので注意。(セレクタ単独で使用する場合を除く)
次のデモは現在表示されているページ内の全ての要素(headやbodyも含めて)の数を数える。
ブラウザのアドオンが自動的にsytleやlinkなどの要素を追加している場合はそれらも数えてしまう。
1 2 3 4 5 6 7 | $(function(){ $("#btnDemo1").click(function(){ var elementCount = $("*").addClass("demo").length; alert(elementCount + " 個の要素があります。"); $("*").removeClass("demo"); }); }); |
一方、次のデモは特定の要素に含まれる要素の数を数える。
1 2 3 4 5 6 7 | $(function(){ $("#btnDemo2").click(function(){ var elementCount = $("#test").find("*").addClass("demo").length; alert(elementCount + " 個の要素があります。"); $("#test").find("*").removeClass("demo"); }); }); |