2013/12/28

VMWare FusionのSCSIドライバを64bit環境用へ変更する

今までVMWare Fusion(v6.0.2)上で32bit版Windowsを動作させていましたが、64bit Windowsへアップグレードすることにしました。

OSの再インストールになりますが、OSアップグレード処理中、旧来のOSがインストールされたディスクへのアクセスが発生するため、新規VMを作成するのではなく、旧環境を更新する必要があります。

環境の変更は、メニューにある「Virtual Machine > Settings....」から「Genral」を選び、「OS」の横にあるプルダウンメニューから適切なOSを選択することで行います。

この変更を行ったVMを起動させようとしたところ、

The BusLogic SCSI adapter is not supported for 64-bit guests.

のエラーメッセージが表示され、起動できません。

この問題を修正するには、.vmx ファイルの書き換えが必要です。VMWare 社の Knowledge Base では1020879として公開されています。

.vmxファイルはVM一式と共に保存されています。

VMの保存場所は、VMWare Fusion のメニューに有る「Virtual Machine Library」から、右クリックなどでショートカットメニューを開くと表示される「Show in Finder」から確認できます。

Finder上では、単一ファイルとして表示されるため、同じくショートカットメニューの
「Show Package Contents」を選ぶと、その中に.vmxファイルが表示されます。

この中から該当するSCSIデバイス番号を親に持つ、virtualDevキーを探します。
例えばSCSIデバイス0のドライバを書き換えるにはscsi0.virtualDevを探します。

この値が"buslogic"になっている場合には、それを"lsilogic"へ書き換えます。

scsi0.virtualDev = "lsilogic"

もしこのキーが.vmxファイルへ存在しない場合には、適当な場所へ追加します。

これで、VMを64bit環境で起動できるようになります。

2013/12/02

iOS の task completion について

TMPTaskCompletionManagerの公開に伴い、task completionについてまとめてみます。

task completion は iOS4 で導入されたマルチタスク処理方式の一つです。アプリがバックグラウンドモードへ入った後も、実行中の処理を継続したいときに使います。実行可能時間は、iOS6までは最長10分間。iOS7では最長3分間へ短縮されました。

バックグラウンドでの実行要求は、
- [UIApplication beginBackgroundTaskWithExpirationHandler:]
で行います。要求は何度でも可能です。
処理が終了したなど、バックグラウンドでの実行が不要になった場合には、
- [UIApplication endBackgroundTask:]
を呼び出さなければなりません。このメソッドを呼び出すか、規定時間が経過した場合、アプリケーションはバックグラウンド処理を終了し、サスペンド状態へ入ります。

StackOverflowでも言及されているように、beginBackgroundTaskWithExpirationHandler:は、名前に「begin」と付いているものの、実際にはバックグラウンド処理を開始しません。このメソッドは、OSに対し、バックグラウンドでの処理継続を要求するために使います。

beginBackgroundTaskWithExpirationHandler:が呼び出される毎に、OSはその回数を記録します(動作可能時間は初回要求時から増えません)。この数値が1以上である場合、OSは、アプリがバックグラウンド処理を要求していると判断します。この回数は、endBackgroundTask:で減算されます。0になった時点で、OSはアプリケーションはバックグラウンド処理を望んでいないと判断します。メモリ管理のリファレンスカウントと同じ原理です。

言い換えれば、endBackgroundTask:を呼び出すまで、アプリケーションはバックグラウンド処理を要求し続けていることになります。例えば、アプリがフォアグラウンドへ復帰するなど、バックグラウンド処理が不要になった場合には、明示的にendBackgroundTask:を呼びださなければなりません。

Appleが公開しているiOS App Programming GuideExecuting a Finite-Length Task in the Backgroundでは言及されていないためか、「Cocoaの日々」「[iOS] バックグラウンド実行見本(Task Completion)」などを除いて、あまりフォアグラウンド復帰時の処理に関し、言及していないように感じています。

この動作を確認するために TaskCompletionSample を作成しました。

https://github.com/n-miyo/TaskCompletionSample

このアプリはアプリケーションバッジを1秒ごとに増加させます。beginBackgroundTaskWithExpirationHandler:の実行はviewDidLoadで行われ、endBackgroundTask:は実行されません。

アプリをバックグラウンドへ落とすと、バッジの増加を通じてバックグラウンド処理を確認できます。アプリを一度フォアグラウンドへ復帰させ、再度バックグラウンドへ遷移させてみます。この処理の過程では新たにbeginBackgroundTaskWithExpirationHandler:を呼び出していませんが、アプリはバックグラウンド実行を継続可能です。

画面の「clear at 'didBecomeActive'」スイッチをONにすると、- [AppDelegate applicationDidBecomeActive:]実行時、endBackgroundTask:を実行するようになります。
この状態で、一度アプリをバックグラウンドへ遷移させ、再度フォアグラウンドへ遷移させた後、再度アプリをbeginBackgroundTaskWithExpirationHandler:へ移行させると、endBackgroundTask:との呼び出し回数が釣り合い、以後バックグラウンドでの実行は行われません。

さて、バックグラウンド処理を要求する場合、時間切れ時に実行されるタスクを登録し、その中でもendBackgroundTask:を実行する必要があります。これらは定形で書けますが、毎回書くのは面倒なものです。

また、複数のタスクをバックグラウンド登録した場合、それらをフォアグラウンド復帰のタイミングで一斉にキャンセルするには、すべてのタスクIDを管理しなければなりません。

これらの比較的定形でありながら、毎回書くのが面倒になるコードをまとめたものが、先に公開した TMPTaskCompletionManagerになります。使い方などは、「iOS の task completion をサポートする TMPTaskCompletionManager を公開しました」を御覧ください。

ご意見などお待ちしております。

iOS の task completion をサポートする TMPTaskCompletionManager を公開しました

今更ではありますが、iOS の task completion をサポートする TMPTaskCompletionManager を公開しました。

https://github.com/n-miyo/TMPTaskCompletionManager

TMPTaskCompletionManagerは、バックグラウンドタスクの登録や、タスク終了時の登録解除処理など、定形的なコードを簡単に書くためのライブラリです。

タスクを登録するには、runBackgroundTask:taskQueue:expirationTask:メソッドで「バックグランドで実行したいタスク」と「時間切れ時に実行したいタスク」を登録します。戻り値は、バックグラウンドタスク識別子です。

「バックグラウンドで実行したいタスク」はtaskQueue:で指定したNSOperationQueue上で実行されます。nilを指定すればQueueは内部で自動生成されます。


処理が終了した場合等、バックグラウンド処理を登録解除したい場合には、cancelBackgroundTask:を使います。


フォアグラウンド復帰時など、すべての登録を解除したい場合には、cancelAllBackgroundTasks が利用できます。-[AppDelegate applicationDidBecomeActive]などで使うとよいでしょう。


各種ご意見など、お待ちしております。

2013/11/17

iPad mini Retina を購入しました

iPad mini Retina モデルを購入しました。

iPad miniは携帯に便利なサイズ、重量で、現在も大変便利に使っています。

一方で、ディスプレイが Retina で無いことから、PDFファイルなど、文字サイズの小さいファイルを読む際には、ディテールが潰れてしまうこともあり、その点が不満でした。

今度の mini は Retina ディスプレイを搭載。非常にきれいな表示で、文字も読みやすく、一段と利便性が向上しました。私がminiで行う作業の殆どはPDFファイルを読むことであり、この為、大変高い満足度を得られる製品となりました。

iPad miniはWi-Fiモデルを使っていましたが、今回はCellularモデルを購入。結果、重量が公称308gから341gへ増加しました。約30gの増加となり、知覚可能です。ただ、デバイスとして、重いとは感じられず、十分に携帯可能です。

パッケージ構成は、従来とほぼ同じですが、付属ACアダプタが5Vから10Vへ変更になっていました。

左の白いボディがiPad mini Retinaモデル、右の黒いボディが去年のiPad miniモデル。



箱を開けるとACアダプタが違います。


12Vモデルと同じ形状ですが、10V出力モデルです。


保護フィルムは、毎回恒例、ミヤビックスの OverLay Brilliant for iPad mini。カバーには、純正のiPad mini Smart Coverブラックを装着です。


なお、今回の retina 化にあたり、残像問題の生じている機種があるようです。テストが公開されており、自分で確かめることが可能です。

幸い私の実機では問題を確認出来ませんでしたが、問題を確認された方は実験してみると良いかもしれません。


2013/11/04

OS X Mavericksのマルチディスプレイ環境でのDock

OS X Mavericksのウリの一つが「マルチディスプレイ対応の強化」です。

「各ディスプレイでフルスクリーンモードを個別に有効にする」「各ディスプレイへメニューバーを表示させる」といった機能は比較的目につきますが、「各ディスプレイでDockを表示する」機能はやや特殊です。

この機能は、

  1. Dockを下部へ表示する設定としている状態で(「自動的に隠す」はチェックしなくても良い)
  2. 表示したいディスプレイの画面下端へマウスカーソルを押し付けて、
  3. 0.5秒ほど待つと、
  4. そのディスプレイへDockが移動する

といった動作になります。

メニューバーのようにすべてのディスプレイで、常時表示させることはできません。

もとのディスプレイでDockが引込み、新しいディスプレイ上で顔をだす姿は、なかなか楽しく、つい、意味もなく移動させたくなります。

NSURLConnection / NSURLSession に於けるタイムアウト

通信を行うアプリケーションでは、不慮の事態等に備え、タイムアウト処理を実装することが望まれます。特にUIを備えた人間の利用するアプリケーションの場合には、より一層、タイムアウト処理へ気を使う必要があります。

タイムアウト値の選択には、いくつかの異なる視点があります。

例えば、サーバが落ちていたり、サーバまでの経路が切断している場合など、サーバとの接続を確立できない場合は、即座に処理を中断できるよう短いタイムアウトが望まれます。この状況は、待ち時間を長くしても解決できる見込みが少ないためです。

一方、伝送終了までの時間を制限したい場合には、伝送品質や利用回線の状況なども考慮し、先程の例よりも長めのタイムアウト値を設定することが望まれます。この場合、長めの時間を許容することで、通信の終了できる可能性が高まるためです。

iOSやOS XのNSURLRequestでは、初期化時のtimeoutInterval引数によってタイムアウトを設定できます。NSURLRequestを利用するNSURLConnectionクラスは、ここで設定されたタイムアウトを利用します。

iOS5.xまでのNSURLConnectionでは、タイムアウト処理に関し、ドキュメントへ記載されていない制限がありました。それは、HTTP Bodyを持った通信は、NSURLRequestのtimeoutIntervalの値に関わらず、240秒以下のタイムアウトが有効にならない、というものです(この制限を回避するために作成したライブラリが「NSURLRequestのPOSTでTimeoutを機能させる」で紹介したTPTimeoutURLConnectionでした)。恐らく、以前はセルラー系伝送速度が特に遅かったこともあり、通信が途中で打ち切られてしまう事態を避けるための仕様だったのだと思います。

この制約はiOS6.xで変更され、240秒以下のタイムアウトも有効になりました。しかし、このタイムアウト値は伝送処理の時間監視に利用されるため、指定時間を過ぎると通信が終了してしまいます。結果、極端に短い値に設定することはできず、通信不能状況、すなわち、接続できない状況の検出目的で使うのは難しい仕様でした。

幸い、iOS7やOS X 10.9で導入されたNSURLSessionでは、この問題に対し、2つのタイムアウト設定を提供する、ということで解決を試みています。

NSURLSessionでは、Sessionの各種設定をNSURLSessionConfigurationインスタンスを通じて行います。NSURLSessionConfigurationインスタンスでは、timeoutIntervalForRequestとtimeoutIntervalForResourceの2つのプロパティを通じ、2種類のタイムアウトを設定可能です。

timeoutIntervalForRequestは、データ間のタイムアウトを設定するプロパティです。このタイマは新しいデータが到着するとリセットされます。呼の確立までの間や、データが複数個へ分割されている場合など、各データ間のタイムアウト値が設定可能であり、通信が確立できないまま、または切れてしまったまま、長時間待ち状態になる事態を回避できます。

timeoutIntervalForResourceは、従来のNSURLRequestで使われていたtimeoutIntervalに近い機能を持つもので、URLで指定されたデータの取得処理が完了するまでの時間を指定するものです。これは、伝送速度が非常に遅い環境など、通信完了まで非常に長い時間を要してしまう状況を回避するために利用できます。

大変に便利な仕様なのですが、しかし、iOS7.0.3で動作確認を行ったところ、timeoutIntervalForRequestは、データを受信時にタイマがリセットされる状況を作り出すことが出来ませんでした。またその為か、timeoutIntervalForRequestとtimeoutIntervalForResourceの両者を設定した場合、単純に、より短い値がtimeoutIntervalForResource用のタイムアウト値として使われていました。ドキュメントへ書いてある「データ」が、今回の利用想定と異なっているのかもしれません。

さて、NSURLSessionでは、各通信処理をNSURLSessionTask(またはその継承クラス)のインスタンスで取り扱いますが、このTask生成時にNSURLRequestを指定することができます。この場合、NSURLSessionConfigutationによるタイムアウト値と、NSURLRequestによるタイムアウト値が個々に設定可能できることになります。生憎、これらの値の競合に関し、ドキュメント上は記述がありません。

同じくiOS7.0.3で挙動を調査したところ、NSURLRequestへ設定されたtimeoutInterval値は、NSURLSessionでは意味を持たないようです。このtimeoutInterval値が有効なタイムアウト値として利用されることはありませんでした。勿論NSURLSessionConfigurationでタイムアウト値を設定した場合には、その値が利用されます。

今回、上記の調査を行うために、NetworkTimeoutSampleという小さなアプリケーションと、それと共に用いるサーバアプリケーションを作成しました。

クライアントアプリケーションはiOS7上で動作し、NSURLConnection+NSURLRequest、NSURLSession+NSURLSessionConfiguration、NSURLSession+NSURLSessionConfiguration+NSURLRequestの組み合わせで、各タイムアウトを設定し、動作を確認することを目的としています。

サーバアプリケーションは任意のHTTP要求を受け付け、2行のbodyを持つHTTP 1.0レスポンスを返す処理を行いますが、clientからの接続をacceptする前、HTTP Header送出前、1行目のHTTP Bodyを返す前、ならびに、2行目のHTTP Bodyを返す前、それぞれに秒単位のwaitを挿入することができます。

タイムアウト処理の動作確認等へご利用ください。

2013/10/26

OS X Mavericks では bind が同梱されない

従来OS Xへは、ネームサーバとしてbindが同梱され、/usr/sbin/namedへインストールされていました。

このnamedは、デフォルト状態では/etc/named.confを設定ファイルとして参照するように構成されています。また、そのnamed.confに基づき、ゾーン(ドメイン)レコードは/var/namedへ格納するようになっています。

しかし、OS X Mavericksでは、bindが同梱されなくなりました。また旧版からアップグレードを行うと、/usr/sbin/namedなどのバイナリに加え、/etc/named.confならびに/etc/rndc.key、ゾーン情報格納ディレクトリの/var/namedも除去されます。Mavericksへアップグレードを行う場合、これらファイルを事前にバックアップしておくことをお薦めします。

なお、これらのファイルはTime Machineバックアップの対象になっていますので、万が一除去されてしまった場合には、Time Machine内を探すと良いでしょう。

bindは同梱されなくなりましたが、勿論各自でインストールし、利用することは可能です。例えば HomeBrewを使っている場合、
% brew install bind
のようにインストールすることで、従来通りbindを利用することができます。なお、設定ファイルのデフォルト参照先が旧OS X同梱版とは異なります。例えばbind 9.9.4をインストールした場合、デフォルトの設定ファイルは、
/usr/local/Cellar/bind/9.9.4/etc/named.conf
が利用されます。named.confを移動させるか、-cオプションで任意のファイルを指定すると良いでしょう。

また、OS X Serverをインストールしても、DNSサービスが利用できるようになります。

こちらは、ネームサーバのオン/オフやゾーン情報をGUIで設定でき、bindに馴染みの無い方も簡単に利用することが可能です。なお、iOS Developer Connectionの有料会員はOS X Serverを無料でダウンロードすることが可能です。

OS X Serverのネームサーバアプリケーションには、従来同様bindが使われており、2013/10/26現在、バージョンは9.9.2-P2です。

バイナリは
/Applications/Server.app/Contents/ServerRoot/usr/sbin/
ディレクトリへ格納されます。このbindは、デフォルト設定ファイルとして、
/Library/Server/named/named.conf
を参照するように構成されています。またこのnamed.conf内では、ゾーンレコードも、named.confと同じディレクトリの
/Library/Server/named/
へ格納されるようになっています。レコード数が多い場合などは、従来のレコード情報を、このディレクトリ内ファイルへマージすれば、簡単に移行することができるでしょう。

なお、レコードファイルを機械処理しやすくする為でしょう、例えば、

  • ラベル部に書くホスト部は絶対名で書く(e.g. foo.example.com.)

  • A/PTRへ紐付けられていない情報はGUI上では表示されない

などの制約があるようです。特殊な運用をしていた場合は、少し注意したほうが良いかもしれません。

2013/09/23

iPhone 5s 購入しました

昨年の投稿からほぼ一年、予想通り恒例行事になりつつありますが、iPhone 5sを購入しました。

昨年は黒でしたので、今年は白/シルバーを選択。箱の表面が、3GS以来久しぶりに正面からの画になっています。


パッケージを開けたところ。iPhone 5と同様です。


中身も変わりません。もはや形式美です。


iPhone 5と並べたところ。唯一の違いはホームボタンで、周囲にリングが追加され、四角マークが消えたことなのですが、写真が光っていて、よく見えませんね...。


裏面。フラッシュが二灯になりました。


iOS7専用機だからでしょう、iPhoneのフォントが細身になっています。ただし、Pやeが顕著ですが、Helvetica Neue Lightというわけではありません。


あわせて純粋ケースも購入しました。色はおなじみ、(PRODUCT)REDです。


表面。触り心地は非常に快適で、革製iPad Smart Coverと非常に近い触感です。


よく見ると内側へはiPhoneロゴが書かれています。


一方、裏側には一切の文字がありません。


装着するとこんな感じになります。


保護シートは、いつもの通り MIYAVIX の OverLay Brilliant。iPhone 5用をそのまま利用。問題なく装着出来ました。


iPhone 5sの特徴としては、指紋認証のTouch IDや、800MHz帯のサポート、カメラの高機能化などが挙げられますが、プログラマとして一番楽しみなのは、64bit化されたA7 CPUです。

iPhone 5sの性能を活かすには、プログラミングモデルをILP32からLP64へ変更しなければなりません。一方で、その他の機種で動作させるために、従来通りILP32環境のサポートも必須です。

若き日に苦労したIP16からILP32への移行が、こんな小さなデバイス上でも訪れたことに、技術速度の素晴らしさを感じます。

Touch IDや64bit化は、将来のiPadなどでも実装されるのでは、と思います。便利な機能が様々なデバイスで使えるようになると良いですね。

2013/09/22

UISegmentedControlで選択されているSegmentのtapも検出できるライブラリを公開しました

iOSのUISegmentedControlは、複数要素から1つを選択する用途で便利に使えるコンポーネントです。

イベントの変化は -[UIControl addTarget:action:forControlEvents:] を用い、UIControlEventValueChangedを検出するのが一般的です。

但し、ラジオボタンのアナロジーである為でしょうか、現在選択されている Segment を再度選択しても、UIControlEventValueChangedは発火しません。

勿論UISegmentedControlのtouch系イベントは発火するので、それを用いることでtapを検出することが出来ます。

注意すべきは、iOS6以前とiOS7でUISegmentedControlのtap検出タイミングが変化したことです。

iOS6以前は所謂 Touch Down 時点をもって「Segment が選択された」とされていましたが、iOS7からは Touch Up Inside 時点をもっての選択へ変更されました。UIButton の挙動と整合した、という点では、わかりやすくなったと言えるでしょう。

このOSに伴う動作の差などを吸収し、既に選択されているSegmentの再tapを検出するためTPSegmentedControlをgithub で公開しました

UISegmentedControl に対する非常に小さな hack です。UISegmentedControl をそのまま置き換える形で利用できます。

最も単純にはLibディレクトリへ含まれてるTPSegmentedControl.hとTPSegmentedControl.mを自身のプロジェクトへ追加し、UISegmentedControlを使っていたコードを、TPSegmentedControlへ置き換えれば動作します。

CocoaPods へも対応していますのでPodsでインストールすることも可能です。
% edit Podfile
pod 'TPSegmentedControl'

ご意見、ご感想、pull request等お待ちしております。

2013/07/21

Notification Center と UIApplicationDelegate

iOSのUIApplicationDelegate ProtocolはApplicationに関するイベントを伝達するためのプロトコルです。

その中の「- (void)applicationDidBecomeActive:(UIApplication *)application」は、APIドキュメントによれば、「非アクティブステートとアクティブステート遷移を知らせる際に呼び出される」と定義され、「アプリケーションが起動された時」や「電話着信やSMSメッセージ等による中断をユーザが無視した際」に呼ばれる、と書かれています。

また「- (void)applicationWillResignActive:(UIApplication *)application」は、同じくAPIドキュメントへ「電話着信やSMSメッセージ等による一時的な中断」や「ユーザがアプリケーションを中断し、バックグラウンド状態へ遷移し始めた際」に呼ばれる、と書かれています。

しかし、APIドキュメントに明示されていないものの、これらの両メソッドは、利用者がiOSのNotification Center(NSNotificationCenter ではなく、ステータスバーから引き出す「通知センター」)を呼び出した際にも呼び出されます

具体的には、

  •  Notification Center画面を少しでも表示させると、- [UIApplicationDelegate applicationWillResignActive:] が呼び出される
  • Notification Center画面を完全に画面外へ追い出すと、- [UIApplicationDelegate applicationDidBecomeActive:]が呼び出される

ことになります。

なおこれは、Notification Centerに関わらず、ユーザ指示により呼び出される「アプリケーション画面へ覆いかぶさる形式で表示されるシステムメニュー画面」でも同様の挙動となるようです。

実験の為、ただApplicationDelegateの各種メソッド呼び出しを、コンソールへ表示する為だけのサンプルアプリをGitHubへ置いてあります

MacBook Air 2013 + AirMac Exteme を使い 802.11ac で通信速度を計測

MacBook Air 2013 で IEEE 802.11acドラフトが採用されましたが、同時にAirMac Time CapsuleAirMac Extremeも802.11acドラフトを採用した新製品が発売になりました。 

MacBook Airの新調に併せAirMac Extremeも購入し、802.11ac環境を整えることができたので、従来の802.11nとの速度を比較してみることにしました。

AirMac Extremeは非常に縦長の外装。同時に発売されたTime Capsuleと同一の形状です。



 端子類を覆うようにシールが貼られている点はAppleTVでの対応と同様。


国産アクセスポイントなどと異なり、内容物もシンプルな構成で、マニュアル類はほとんど含まれていません。設定を専用のアプリで行うことが前提になっている為でしょう。



まずは、MacBook Air 2013を従来から利用しているアクセスポイントであるNEC AtermWR9500Nへ接続し、速度を計測してみました。

接続には5GHz帯域を使用します。アクセスポイント自体はチャンネルボンディング/3ストリーム対応の為、理論値450Mbpsですが、MacBook Air側が2ストリームまでの対応であるため、理論値は300Mbpsとなります。

設置環境は従来までの計測同様、木造2階建ての1Fと2Fで行いました。但し今回は、計測プログラムへnuttcpを使っています。

   26.6250 MB /   1.00 sec =  223.1951 Mbps
   27.3750 MB /   1.00 sec =  229.6127 Mbps
   27.0625 MB /   1.00 sec =  227.2098 Mbps
   27.5000 MB /   1.00 sec =  230.5712 Mbps
   27.2500 MB /   1.00 sec =  228.6858 Mbps
   27.5625 MB /   1.00 sec =  231.2739 Mbps
   21.5625 MB /   1.00 sec =  180.8837 Mbps
   26.6875 MB /   1.00 sec =  223.6922 Mbps
   26.7500 MB /   1.00 sec =  224.5920 Mbps
   27.7500 MB /   1.00 sec =  232.7531 Mbps

  266.6250 MB /  10.02 sec =  223.3137 Mbps 7 %TX 2 %RX 0 host-retrans 2.14 msRTT

結果は223.3137 Mbps。非常に優秀な成績です。

今度は、アクセスポイントをAirMac Extremeへ切り替えて計測しました。

こちらもアクセスポイントは3ストリーム対応ですが、MacBook Airの制限で理論値866.7Mbpsとなります。接続帯域は、同じく5GHz、設置環境も同様です。

   62.0000 MB /   1.00 sec =  519.7294 Mbps
   66.3125 MB /   1.00 sec =  556.4387 Mbps
   65.8125 MB /   1.00 sec =  551.9108 Mbps
   67.0625 MB /   1.00 sec =  562.8503 Mbps
   66.4375 MB /   1.00 sec =  557.2151 Mbps
   65.9375 MB /   1.00 sec =  553.4338 Mbps
   66.5625 MB /   1.00 sec =  558.3874 Mbps
   66.9375 MB /   1.00 sec =  561.3261 Mbps
   66.1875 MB /   1.00 sec =  555.2543 Mbps
   66.4375 MB /   1.00 sec =  557.5490 Mbps

  660.3750 MB /  10.01 sec =  553.4260 Mbps 15 %TX 9 %RX 0 host-retrans 2.70 msRTT

結果は553.4260 Mbps。802.11n接続時の2.5倍近い速度が計測できました。

一般的に家庭で利用される有線接続がGbEであることを考えれば、その実効速度へ迫る転送速度です。3ストリーム対応クライアントと共に使えば、有線環境を超える速度が得られるかもしれません。もはや「無線は有線よりも遥かに遅い」という固定観念は通じなくなってきています。

802.11acは、まだドラフト段階の仕様ではありますが、対応クライアントをお持ちの方は、アクセスポイントの新調を行えば十分投資に見合う快適な接続環境を構築できる可能性が高いでしょう。

快適な通信速度を求める方へ、非常にお薦めのネットワーク環境です。

2013/07/20

GitLabをインストールする際に陥った問題のまとめ

GitLabGitHubのようなGitホスト環境を手元で構築できる、大変有益なツールです。

主なサポートプラットフォームはLinuxの各ディストリビューションですが、私はGitLab v5.3をFreeBSD 8.4 + ruby 1.9で利用しています。

やや環境設定で戸惑う事があったので、FreeBSD で動作させるコツと共に、ハマった点をまとめておきます。

FreeBSD へインストールする際の参考ドキュメント


FreeBSD へのインストールには、gitlab-freebsd/gitlabhqで公開されているインストールガイドが、大変参考になります。概ねこの手順に従えば、トラブルなくインストールが完了します。

なおgitlab-freebsd/gitlabhqではgitlabhq/gitlabhqのforkが公開されていますが、GitLabのコード自体へ特殊な変更が行われているわけではありません。オリジナルリポジトリへ、FreeBSDのportsと親和性の良い各種設定ファイルを同梱している、と捉えると分かりやすいと思います。

実際、forkされているコードは比較的古い版であるため、設定ファイルを参考に、オリジナルの最新版を動作させると良いでしょう。

FreeBSDではgitlab-shellへ注意


GitLabのv5系はgitlabhq/gitlab-shellへ依存しています。但し、gitlab-shell v1.6までのコードはFreeBSDでは動作しません。

gitlab-shellをFreeBSDで利用する場合にはf13afa2db3以降のコード利用する必要があります。

問題の本質はGNU sedとBSD sedの-iオプション引数取り扱いの差あり、変更差分はわずかです。

FreeBSD向けGitLab起動スクリプト


FreeBSD向けGitLab起動スクリプトとしては、Eyes JAPAN Blogで公開されているスクリプトが綺麗にまとまっており、利用させていただいています。

但し、ここで公開されているスクリプトの最新版にはバグが有り、重要な外部プログラムであるsidekiqが動作しません。

修正した版をgistで公開していますので、こちらの利用をお薦めします。本質は変数の初期設定ミス修正です。

repos_path へは symbolic link を含んではならない


gitlab/config/gitlab.yml ならびに gitlab-shell/config.yml へはrepositoryを格納するディレクトリを設定するrepos_pathがあります。コメントへ書かれている通り、この値はsymbolic linkを含んではいけません。

ここで注意すべきは、FreeBSDを標準設定でインストールした場合、/homeディレクトリが、usr/homeへのsymbolic linkとしてインストールされることです。

結果、GitLab標準設定に基づき、repos_pathとして/home/git/repositories/を指定すると、結果的にsymbolic linkを含んでしまうことになります。

もしこのディレクトリを使いたい場合には、明示的に/usr/home/git/repositoriesと設定するか、/homeの位置を再調整する必要があります。

sidekiq が動作していることを確認する


FreeBSD へ限った話ではありませんが、GitLabではsidekiqプロセスが正しく動作していることが非常に重要です。

sidekiqプロセスが動作していない場合、表面上は正常に動作しているように見えるものの、実際には正常動作しない、という、分かりにくい状況へ陥ります。

例えば、Web画面ではssh鍵の登録が正常終了したように見えたにも関わらず、実際には、authorized_keysへ鍵が登録されていない、といった状況や、プロジェクトの作成指示が正常動作したように見えたにも関わらず、repos_pathで指定したディレクトリ内へはリポジトリが作られていない、という状況になった場合、sidekiqプロセスが、正しく動作していることを確認すると良いでしょう。 

例えばsidekiqが正常動作している場合、psでは次のように見えます。
# ps ax | grep sidekiq
41032   0  I      0:22.50 ruby19: sidekiq 2.11.1 gitlab [0 of 25 busy] (ruby19
なおsidekiqプロセスは、GitLabの起動スクリプト内で起動されることが一般的です。うまく動作しない場合にはスクリプトを確認すると良いでしょう。

.ssh/authorized_keys 内の鍵へ注意する


これもFreeBSD へ限った話ではありませんが、GitLabを動作させているユーザの .ssh/authorized_keys ファイルは、リポジトリアクセス権管理に使われる重要なファイルです。

何らかの不具合により、このファイル内へ同一の鍵が複数個登録されてしまった場合、GitLabが正常に動作できなくなる可能性があります。

GitLab 管理下にある repository へ push を行った際、
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
といったメッセージが表示された場合、.ssh/authorized_keys が正しいかどうかを確認すると良いでしょう。

なお、鍵が正しくインストールされている場合、
% ssh -t gitlab@GitLabServerName.example.com
とのコマンドに対し、
Welcome to GitLab, <YOUR USER NAME>
との応答が返ります(<YOUR USER NAME>はGitLabで登録したユーザ名です)。この応答が返らない場合、鍵設定に問題のある可能性があります。

GitLabは大変便利なツールです。ツールの規模がやや大きいため、トラブルシュートでやや混乱しがちですが、設定ファイル自体はシンプルなため、問題を適宜切り分ければ、対処は難しくないと思います。

2013/07/06

MacBook Air 2013 を購入しました

MacBook Air 2013 11inchを購入しました。



MacBook Air 2010は現在でも十分使い勝手の良いデバイスですが、バッテリの持続時間に関してはやや不満を感じ始めていました。

Wi-Fiを有効にしなければ、実質計測で10時間程度は持つのですが、Wi-Fiを有効にすると、仕様上謳われている「ワイヤレス環境で最大5時間」程度でバッテリが力尽きてしまいます。

一方MacBook Air 2013 11inchでは、CPUをHaswellへ変更したことが影響しているのでしょう、仕様上の表記が「最大9時間のワイヤレスインターネット閲覧」となりました。2010モデルからバッテリ稼働時間が約2倍へ伸び、まさに望んでいた改良です。最近はWi-Fiスポットも増え、Wi-Fiを有効にしている時間が多くなった為大変嬉しいアップデートとなりました。

加えて、無線LANの規格が802.11ac(draft)へ向上すると共に、2010モデルでは最大128GだったSSDの上限が最大512Gへ拡大されるなど、モバイルデバイスとして魅力が大きく向上しています。

今回購入した構成は、CPU Core i7 1.7GHz、8GBメモリ、256GB SSD、英語キーボード。
従来のモデルは、CPU Core2 Duo 1.6GHz、4GBメモリ、128G SSD、英語キーボードでしたので、大幅な性能向上です。

外箱の様子。上が2010モデル、下が2013モデル。同じ大きさですが、2010モデルで黒かった箱表面の背景は、白になりました。


 開けた様子は変わりません。


中の構成。上が2010モデル、下が2013モデル。


基本収納物は同一ですが、今回Lightning Ethernetアダプタも同時購入した為、2013モデルではそれを収納可能な内箱になっています。この辺りの仕組みは、iMac 27-inch Late 2012の内箱と同様です。


2010モデルではOSのインストールされたUSBメモリが付属していました。


2013モデルでは本体のみで再インストール可能になった為、外部メディアは付属していません。

本体はほぼ見分けが付きません。マイク形状が異なること、また、電源がMagSafeからMagSafe2へと変更になったこと位が判別のポイントです。



動作は大変キビキビしており、全く問題を感じません。特にSleepからの復帰は素早く、蓋を開けた時には既に利用可能な状態になっています。この点は、2010モデルとは一線を画しています。

今まで使っていた2010モデルは、ソフマップの中古下取りへ。売価は34000円と上限価格で買取して貰えました。3年前のモデルですが、この価格で買い取ってくれるという点に、MacBook Airの人気が伺えます。

従来機同様、有効に活用して行きたいと思います。


2013/07/01

iOSアプリでのアイコン設定

iOSアプリでアイコンを設定する場合、「App-Info.plist」ファイルの「CFBundleIcons」key内にある「CFBundleIconFiles」keyへArray形式でアイコンを列挙します。例えば次のような形式になるでしょう。
        <key>CFBundleIcons</key>
        <dict>
                <key>CFBundlePrimaryIcon</key>
                <dict>
                        <key>CFBundleIconFiles</key>
                        <array>
                                <string>Icon-72.png</string>
                                <string>Icon-72@2x.png</string>
                                <string>Icon-Small.png</string>
                                <string>Icon-Small-50.png</string>
                                <string>Icon-Small@2x.png</string>
                                <string>Icon-Small-50@2x.png</string>
                        </array>
                        <key>UIPrerenderedIcon</key>
                        <true/>
                </dict>
        </dict>

しかし、特定の環境下構築した場合、この「CFBundleIconFiles」へ結びついたArray内へ、Default Screenのファイル一覧が含まれている場合があります。具体的には、次のような記述が含まれていました。
                               <string>Default-Portrait@2x~ipad.png</string>
                               <string>Default-Landscape@2x~ipad.png</string>
                               <string>Default-Landscape~ipad.png</string>
                               <string>Default-Portrait~ipad.png</string>
                               <string>Default-Portrait~ipad.png</string>
                               <string>Default-Portrait~ipad.png</string>
                               <string>Default-Landscape~ipad.png</string>
この設定が存在する場合、特定のiOS環境では、アプリアイコンが正しく表示されず、Default Screenをアイコンサイズへ縮小した画像が使われてしまいます。

もし「アプリアイコンがDefaut Screenになってしまう」という状況へ陥っている場合、「CFBundleIconFiles」keyへ紐付いたArrayの内容を確認すると良いでしょう。

2013/06/18

Google Chrome 拡張「Search Date Changer」を Manifest V2へ対応しました

約3年ほど前に公開した Google Chrome 拡張の「Search Date Changer」を更新しました。


この拡張はGoogleのページで表示されている検索結果の対象期間を、ワンクリックで変更できるようにするものです。Googleページでは変更までに3クリック必要なので、2クリックも節約出来ます!(ぇ?)

今回の変更点は次の通りです。

  • (ようやく)ManifestをV2へ更新しました。これでChrome Ver.29以降でも動作可能です。
  • すでにGoogle側でサポートが終了していた「Latest」オプションを廃止し「1 hour」へ変更しました。
  • optionページで使用していたjQueryを2.0系へアップデートしました。

大きな機能追加はありませんが、これにより、今後も従来同様にお使いただくことが可能になりました。

ソースコードも、従来同様githubで公開しています。適宜forkしてお楽しみください。

ご意見などお待ちしております。

「最新版のChromeで動かない!」とご報告下さり、重い腰をあげるきっかけを下さったBenさんへ感謝します。どうもありがとうございました。

2013/05/23

KiwiでNSManagedObject派生クラスへstubを設定する

KiwiはiOSでBDDを実施するためのライブラリです。Mock作成の仕組みなどが組み込まれており、他ライブラリを別途インストールすることなく、素早くテストを行うことができます。

但し、CoreDataのテストを行う目的で、NSManagedObject派生クラスへstubを設定する場合には注意が必要です。そのEntityが持つAttributeと紐付いたPropertyをStubにしようとしても実行時エラーになってしまいます。

例えばBookというEntityを作りauthorというAttributeを設定します。このEntityから生成されるBookクラスは次のようなコードになります。
@interface Book : NSManagedObject
@property (nonatomic) NSString *author;
@end
このauthorをStubにしようと、次のようにKiwiのテストケースを書いたとします。
it(@"foo", ^{
  Book *book = [KWMock mockForClass:[Book class]];
  [book stub:@selector(author) andReturn:@"Anonymous"];
  [[book.author should] equal:@"Anonymous"];
});
残念ながらこのテストは、
[[book.author should] equal:@"Anonymous"];
の実行でエラーになってしまいます。

このような場合、authorを@protocolで括りだし、そのプロトコルに対してテストを行うのが簡単です。

まず、テストしたいAttributeを含むプロトコルを作成します。
@protocol BookAttributes
@property (nonatomic) NSString *author;
@end
次に、NSManagedObjectを継承したBookクラスでこのプロトコルを実装します。
@interface Book : NSManagedObject <BookAttributes>
@end
テストではProtocolのMockを作成し、そのStubを実装します。
it(@"foo", ^{
  Book *book = [KWMock mockForProtocol:@protocol(BookAttributes)];
  [book stub:@selector(author) andReturn:@"Anonymous"];
  [[book.author should] equal:@"Anonymouss"];
});
これでNSManagedObject派生クラスが持つAttributeに対してもテストができるようになります。

2013/05/20

既存gitリポジトリで、親の存在しないbranchを作成する

gitでbranchを作成するには、git branch、またはgit checkout -bを使いますが、稀に、他のcommitから派生していない、すなわち親の存在しないbranchを作りたいことがあります。

例えば、既存branchで各種実装検討を行い、方向性が見えたあとで、 新規にcommitを組み直したい、といった場合です。また、ソースコードの新規公開へむけて、過去の履歴を含まないbranchを新規に作成したい場合にも使えるかもしれません。

このためには、次のコマンドが使えます
git checkout --orphan <branch-name>
これで親のいない、まさにorphanなbranchを作ることができます。

なお、このコマンドを実行してもworking treeへ含まれているファイルは消えません。

2013/04/20

UP by Jawbone 購入しました

ライフログツール、UP by Jawboneを購入しました。

 UP By Jawbone は、一日の運動量や睡眠時間を記録してくれるためのリストバンドです。


日本では2013/4/20発売。当初発売される色は、ブルー、オニキス、ライトグレイ。AppleStore では、Store限定としてミントグリーンが売られています。海外ではもう少し多色展開です。

同じような機能を持つ、人気の高いリストバンドに、NIKEのFuelBandがあります。


残念ながら、FuelBandは、日本ではまだ正式販売されていません。

UPはFuelBandよりも多くの情報を記録することができます。例えば、FuelBandは運動量を取得することへ特化していますが、UPはそれに加え、睡眠時間も記録します。

また、UPはバイブレーションを持ち、目覚ましなどに活用出来ます。電池も、FuelBandよりも長持ちします。

一方FuelBandは液晶がLCDが付いているため、情報を多く表示できます。例えば、運動量をFuelBand本体で確認したり、時計して活用することもできます。UPは本体へ情報表示機能はありません。

また、スマートフォンとの接続もBluetoothが利用できます。UPは本体付属のヘッドフォンジャックをスマートフォンへ差し込む必要があります。

どちらにも良い点がありますが、UPのほうが重量が軽いこともあり、また、記録情報が多いこともあり、日常生活用途として手軽に使えると感じています。

本体が見えるパッケージ。


箱には、腕を通してサイズを確認できる穴がついています。これに腕を通すことでサイズの確認が行える仕組みです。


箱内の本体装填方法は独特。


上がFuelBand、下がUP。


左がUp、右がFuelBand。


FuelBand、Upとも、購入時に一番悩むのは、どのサイズが最適化、ということです。

私は腕が細く、UP用に公開されているUP SIZERで計測したところ、155mmでした。

FuelBandではMを利用していましたが、やや大きめのつけ心地でした。FuelBandのオフィシャル写真などよりもゆるやかで、ゆるめのアクセサリ感覚で利用していました。

UPでは、155mmはちょうどSとMの中間ですが、今回もMを選択しました。

UPは、FuelBandと違い素材はゴムです。そのため、FuelBandよりもサイズへ柔軟性があります。結果FuelBandよりもダブつかせずに装着させることができました。

もし、FuelBandでMサイズを使っている場合、UPでもMサイズを選択するとハズレはないと思います。ただし、フィット感まで考慮すると、やや、UPのほうが小さめと捉えると良いでしょう。

これらのライフログツールは、装着し計測することで、普段は意識していなかったことに気がつくことができるようになります。私は、一週間の自分の運動量を把握することができ、週末、如何に動いていないかを思い知らされました。

ゆるやかな視点で日々を計測してみると、なかなか楽しいかと思います。



2013/04/14

Pebble Watch Face SDKとlibpebbleでPebbleへアプリを転送する

Pebbleは表示装置に電子ペーパを持つ時計です。


iPhoneやAndprodのアプリと通信することができ、また、自作のアプリを動作させることもできます。

現在はPre-Order状態ですが、KICK STARTERでの出資者へ先行出荷が開始され、幸い私も3月半ばに入手することができました。

梱包箱がそのまま送付箱になる、Amazon Kindleなどと同じスタイルです。




 中身は本体と充電ケーブルのみのシンプル構成。


常用している、CITIZEN PROMASTERとの大きさ比較。結構大きな腕時計ですが、それに負けない大きさです。


iPhoneアプリの起動画面とファームウェアアップデートの画面。


本体でもアップデートが確認できます。


今までは、開発者用SDKが公開されていなかったため、アプリを自分で作成することが困難でしたが、とうとう先日、Watchface SDKが公開されました!

まだまだ基本的な画面を構成できる程度のAPIが公開されたに過ぎません。また、所謂「原理試作」的な位置づけで、「大きく変化する可能性が高いです」と宣言されています。それでも、とても楽しそうです。

現状でもSDKやインストールマニュアルは完成度が高く、ドキュメント通りに進めれば、何の戸惑いもなくアプリをbuildし、転送することができます。

本来作成したアプリはiPhoneなどのスマートフォンアプリを使って、簡単にインストールできるはずなのですが、Get StatedInstall the SDKへ書かれているように、現在公開されているiPhoneアプリ(1.0.5)からはSDKを使って自作したアプリをインストールすることができません。

そこでlibpebbleを使う方法が推奨されています。このコマンドラインアプリを使用すれば、iPhoneアプリを使わず、直接Pebble Watchへアプリをインストールすることが可能です。この手法のほうが、より迅速に開発を進める上でも便利でしょう。

libpebbleを、常用しているiMac/Late 2012 & OS X 10.8.3で試してみたところ、SDK同梱のサンプルアプリをインストールすることができました。

転送にあたっての注意点は以下の通りです。
  • 環境依存の話なのかもしれませんが、私の環境では、同じ手順を行なっても、Pebble Watchとの接続に失敗する、または途中で途切れてしまうことが多々ありました。一度失敗しても、何度か試してみると良いでしょう。Pairをやり直すことも効果があるかもしれません。
  • Pebble WatchとiPhoneとのPairは解除しておくと良いでしょう。iMacとの接続が頻繁に切れるため、その度毎にiPhoneと接続してしまうことになり、やや面倒です。
  • iMacのメニューバーへ表示されているBluetoothアイコンをOptionボタンを押しながらクリックすると、connectしているデバイスだけではなく、Pairが確立しているデバイスも確認できます。接続可能かどうかは、この表示を確認すると良いでしょう。




  • Pebble Watch側のSettings>Bluetoothでは、Pairが確立されているデバイスが確認できます。libpebbleからのコマンド送出前は、この表示がconnectedとなっている必要はありません。コマンド操作を行えばconnectedになります。



  • 一度Pairを確立できれば、Pebble Watch側をSettings>Bluetoothのままにしておく必要はありません。時計画面表示でもlibpebbleからのコントロールは可能です。
  • ドキュメントへも書いてありますが、PEBBLE_ID環境変数を設定しておくと便利です。

接続実験にはlibpebbleのpingコマンドが便利です。Pebble Watchのバイブレーションが発動すると共に、画面へメッセージが表示されます(maciaはiMacのホスト名です)。



上記の画面を表示させる際に実行したコマンドラインは次のようなものでした。PEBBLE_ID環境変数が設定しているので、--pebble_idオプションは指定していません。
% ./p.py --lightblue ping
[DEBUG   ] LightBlue process has started on pid 58109
[DEBUG   ] Connection established to 00:11:22:33:44:55
[DEBUG   ] Initializing reader thread
[DEBUG   ] Reader thread loaded on tid Thread-1

SDK付属のアプリを転送するとこんなメッセージになります。
% ./p.py --lightblue load ../pebble-sdk-release-001/sdk/build/sdk.pbw
[DEBUG   ] LightBlue process has started on pid 57402
[DEBUG   ] Connection established to 00:11:22:33:44:55
[DEBUG   ] Initializing reader thread
[DEBUG   ] Reader thread loaded on tid Thread-1
[DEBUG   ] Attempting to add app to bank 2 of 8
[DEBUG   ] Sent 3840 of 3840 bytes
[DEBUG   ] Sent 4000 of 4256 bytes
[DEBUG   ] Sent 4256 of 4256 bytes

ドキュメントを読みつつ、いろいろ遊んでみたいと思います。

2013/03/26

TPMigrationManagerをリリースしました

TPMigrationManagerをリリースしました。

TPMigrationManagerはCoreDataのマイグレーションを簡単に行うための便利ユーティリティです。

github から取得出来ます。MITライセンスです。

git clone https://github.com/n-miyo/TPMigrationManager.git

CoreDataはOS XやiOSで使えるフレームワークで、オブジェクトをファイルへ保存したり、関係性を管理したりすることができます。非常に平たく言ってしまえば、データベースとCocoaのオブジェクトを、便利に橋渡ししてくれるフレームワークです。

データを格納する為には、その格納情報を示したモデル(RDBMS的に言えばスキーマ)が必要になります。モデルを変更した場合、データの移行(マイグレーション)が必要になりますが、CoreDataはその仕組みも提供しています。

CoreDataのマイグレーション機能は非常に多機能ですが、多機能であるが故に、利用するための設定などがやや複雑です。

TPMigrationManagerは、できることを基本機能へ限定することで、なるべく簡単に利用できるようにしました。

マイグレーションは以下の3ステップで完了します。

  1. TPMigrationManagerのインスタンスを作る
  2. - [TPMigrationManager migrationStatus]でマイグレーションの方法を得る
  3. 取得した方法に基づき、マイグレーションを実行する

インスタンスを作成するには、モデルや格納ファイルの場所を明示的に指定する方法と、基本となる名前を引渡し、TPMigrationManagerへ推測させる方法の2種類があります。

前者が - [TPMigrationManager initWithManagedObjectModel:persistentStoreURL:persistentStoreType:]、後者が - [TPMigrationManager initWithBasename:]です。
Xcodeが生成するCoreDataのテンプレートに従っている場合には、後者が便利です。

CoreDataでは2つのマイグレーション方法を提供しています。

一つが「新旧モデルの変更をCoreDataへ自動推測させてマイグレーションを行う」方法、もう一つが「自分で変換のマッピングモデル作成しマイグレーションを行う」方法です。

TPMigrationManagerでは、前者は - [TPMigrationManager migrateByInferredMappingModelWithOptions:completed:]が、また後者は - [TPMigrationManager migrateBySpecificMappingModelWithOptions:progress:completed:]が相当します。

前者は事前準備が必要ない分、より簡単で、また動作も大変に高速です。Appleの推奨もこちらです。ただし、複雑な変更などへは対応出来ません。また、マイグレーションの進捗状況を取得することや、キャンセルを行うこともできません。

後者は、新旧のモデルを自由に変換することができます。例えば、あるモデルでは複数の要素へ分かれていたデータを1つへまとめる、といったことも可能です。進捗状況も取得出来ますし、キャンセルも可能です。但しマイグレーションには多くの時間が必要となります。また、変換方法を示すNSMappingModelを事前に準備し、アプリへ含めて置かなければなりません。

どちらの方法を使うにしても、メソッドを呼び出せば、マイグレーションは終了します。終了後は、指定したblocksが実行されます。

どうぞ、お気軽にご意見などお寄せ頂ければ嬉しく思います。お待ちしております。


2013/02/18

Developers Summit 2013へ参加しました

もはや毎年恒例ではありますが、今年もDeveloper Summitへ参加して来ました。

去年は、モバイルも含めてHTML5/JavaScript全開、という感じでしたが、今年は、ZuckerbergによるHTML5発言があった為でしょう、モバイルに関しては、HTML5によるWebアプリとNativeアプリとに関しての言及が多かった気がします。

今年も、昨年同様HTML系のセッションへを数多く聴講しましたが、やや自身の趣味比重を高めた結果、Ruby 2.0MobiRubyなど、Ruby色が強くなりました。

いずれのセッションも大変楽しかったのですが、中でも多くの刺激を頂いたのは、秋葉ちひろ(@tommmmy)さんの「デザインを考えるときにデザイナーが考えること~デザイナーの頭の中~」と星暁雄(@AkioHoshi)さんの「タブレット進化論」です。







どちらも普段とは異なる視点を手にすることができ、大変感謝しております。どうも有難う御座いました。

来年も現役のまま、若い方々から新鮮な刺激を頂くべく、参加できると良いな、と思っています。

2013/02/04

ソフマップのiMac買取について

ソフマップは中古パソコンの買取で有名で、Macの買取も行なっています。

特にApple Storeで購入した場合、特定日数(例えば30日)以内にソフマップで買取の申し込みをすると買取価格を増額してくれます。このサービスは期間限定ではあるのですが、定期的に開催しているようです。

私も今回のiMac買い替えに伴い、このサービスを利用してみましたので、その際の情報を記録しておきます。

買取の申し込みはWebから行います。型式などを入力すると買取上限金額を確認することができます。そのアイテムを買取カートへ入れることから手続き開始です。

商品は無料で指定日時に引き取りに来てくれます。商品の大きさによっては梱包箱を送ってもらうことが可能なようですが、今回はiMac 24inchと大柄の商品だったため、元々商品が収められていた箱をそのまま使いました。

送付する場合、商品へは、Apple Storeから送られる「商品出荷のお知らせ」メイルを印刷して同梱する必要があります。「Apple Store下取りサービス申込用紙」とともに、箱の中のわかり易い場所へ入れておくと良いでしょう。

商品が引き取られてから、3日ほどで買取査定に関するメイルが届きました。メイルには「査定結果」と「増減内訳」などが記載されています。

今回はiMac 2008年モデル/24inch/2.8GHzでしたが、その査定内容は次のとおりでした。

査定内容
MAC
==カスタマイズ==
「「メモリ」変更 2GB → 6GB」買取上限  1000円
「「HDD」変更 320GB → 1TB」買取上限  1500円
以上により買取上限 15000円から17500円に変更になります。
==状態減額==
液晶 液晶の黄ばみと内部汚れ有り -8750円
==個別増額==
AppleStore下取サービス 15%アップキャンペーン【Appleストア限定】  1320円

液晶の黄ばみは大きな減額となってしまうようです。また、増設品などは適宜増額してくれることがわかります。結果、次の結果となりました。

01 iMac Intel Core2 Duo 2.8GHz/ 24/2048/320G/SuperDrive(DVD±R DL)/AMEx/BT/iSight MB325J/A
上限金額   17500円
増減金額   -7430円
査定金額   10070円

実はこのメイルが届く以前、誤った査定結果のメイルが届きました。その内容は、上記と同じで商品構成でありながら、「OSのインストールディスクやマニュアルが欠品である」と誤って判断された内容で、大きく減額されていました。

査定内容
MAC
==カスタマイズ==
「「メモリ」変更 2GB → 6GB」買取上限  1000円
「「HDD」変更 320GB → 1TB」買取上限  1500円
以上により買取上限 15000円から17500円に変更になります。
==状態減額==
液晶 液晶の黄ばみと内部汚れ有り -8750円
==欠品減額==
「Mac OS X Install Disc(2枚)」欠品 -12250円
「Everything Mac -Macのすべて-」欠品 -270円
「かんたん日本語入力ガイド」欠品 -270円
大幅な減額が発生した為、
買取価格を 1750円とさせていただきます。
==個別増額==
AppleStore下取サービス 15%アップキャンペーン【Appleストア限定】  270円

このことから、OSのインストールディスク有無が、買取金額の中で、非常に大きな割合を占めていることがわかります。

買取を了承するか、返却を希望するかは、一ヶ月以内に返答しなければなりません。

この返答は、Webの「お問い合わせフォーム」を通じて行います。承諾する旨を連絡してから30分も経たず、メイルで連絡が届き、買取が成立したため、支払いを行う旨が書かれていました。

なお支払いは指定銀行への振込となりますが、その際、支払金額から振込み手数料が差し引かれます。手数料は、

振込先銀行が三井住友銀行の場合、合計金額が3万円未満で315円、3万円以上で525円
振込先銀行がその他の銀行の場合、合計金額が3万円未満で630円  3万円以上で840円

とのことで、買取金額が安い場合、結構な比率を占めてしまうことになりそうです。

返信をしてから、実際の入金が行われるまでは、約一週間ほどでした。

以上、買取を検討されている方の参考になればと思います。


2013/02/03

NSURLRequestのPOSTでTimeoutを機能させる

CocoaのNSURLRequestではタイムアウトを設定することができます。

NSURLRequestでは、initWithURL:cachePolicy:timeoutIntervalによるインスタンス生成時に指定可能ですし、NSMutableURLRequestでは、インスタンス生成後に変更も可能です。

但しiOS5以下の環境では、NSURLRequestインスタンスのタイムアウト値が再設定されてしまう条件が存在します。

その条件とは「インスタンスのタイムアウト値が240秒未満の場合」に「HTTPBodyを設定する」ことであり、これを行うと、タイムアウト値が240秒へ再設定されます。

NSMutableURLRequestインスタンスの場合、timeoutIntervalでタイムアウト値を最設定出来ますが、この場合にも240秒未満へ設定することはできません。

この仕様は古くからコミュニティの間で語られていますが(see:https://devforums.apple.com/message/108292/。要AppleDeveloperアカウント)、残念ながら、Appleのドキュメントへは明記されていないようです。

iOS6ではこの仕様は変更され、タイムアウト値が再設定されてしまうことはありません。ただし、iOS5環境をサポートするアプリケーションでは、アプリケーションで対応する必要があります。

対応策の一つは自身でタイマを設定し、タイムアウトになった時点でコネクションをcancelすることです。

これに基づいたライブラリ「TPTimeoutURLConnection」をgithubへ公開しました

同期通信はNSURLConnectionへのカテゴリとして実装しています。追加メソッドは、次の一つです。
+ sendSynchronousRequest:timeoutInterval:returningResponse:error:

timeoutInterval:引数へ、NSURLRequestで設定したかったタイムアウト値を指定します。例えば次のようにして使います。

ここでは、timeoutInterval:を通じて5秒のタイムアウトを設定しています。

一方非同期通信を行うには、NSURLConnectionを稼働させる際にタイマを起動し、自身が設定したdelegateの適切なメソッドでタイマの廃棄などを行わなければなりません。

そこで、先のライブラリでは雛形となるサンプル実装として、TPURLConnectionクラスと、TPURLConnectionDelegateが同梱されています。特にアプリケーション側の制約がなければ、どちらも継承して使うことが可能です。

例えば次のように利用できるでしょう。

注意すべきことは、NSURLRequestへHTTPBodyを設定した時点でtimeoutIntervalue値が変更されてしまってうことです。そのため、NSURLRequestインスタンス作成時に設定したtimeout値を、そのまま用いることはできません。

なお、このライブラリはiOS6でも動作しますが、iOS6はタイムアウトの制限が撤廃されていますので、利用する理由はありません。

iOS5系をサポートするアプリも少なくなりつつあるとは思いますが、ご意見などお待ちしております。

2013/01/03

iMac 27-inch, Late 2012を購入しました

「iMac 27-inch, Late 2012」を購入しました。オンラインのApple Storeで発注したのが12/1、到着が1/1でしたので、丁度1ヶ月での到着でした。

今までデスクトップ機は「iMac 24inch, Early 2008」を利用していたので、4年ぶりの刷新となります。

箱の大きさはiMac24inchと変わりません。手前が24inch、奥が27inchです。


 外箱が台形となっている為、幅は27inchのほうが薄型になっています。


箱を開けると上部の発泡スチロールの窪みへ、キーボードとマウスを収めた白箱が格納されています。




この白箱は余分な空間がなく、キーボードとマウスが綺麗に収まる専用のサイズになっています。


キーボードやマウスはCTO可能であり、テンキー付きキーボードや、Magic Trackpadも選択可能である為、この白箱と上部の発泡スチロールは、組み合わせの数だけ用意されているのだと思われます。この辺りへのこだわりは、相変わらず見事です。

外箱の開き方もコンピュータ系としてはあまり例を見ないものです。まず前面が前に倒れ、本体を手前へ引き出せるようになります。


その後両脇から発泡スチロールを引き抜きます。


設置してみました。上が24inchを置いていた状態、下が同じ場所へ27inchを置いた状態。



右端の黒いモニタと比べれば分かる通り、24inchと27inchの高さには、それほど差がありません。これはモニタの比率が4:3から16:9へ変化した為です。

横幅の必要面積は増加しています。しかし27inchへは24inchへ備わっていた光学ドライブがありません。24inchではCD等の出し入れのために本体右横を空けておく必要がありましたが、27inchではその空間を詰めることができます。結果、24inchと27inchは、設置空間に大きな差がありませんでした。

以前購入したワイヤレスキーボードと付属のワイヤレスキーボード。上が古いもの、下が新しいものです。F3とF4のシルクが最近のものに変わっています。


今回、メモリは8Gモデルを購入し、別途用意した16Gを増設しました。リテールショップで購入したTranscendのDDR3-1600MHz、SO-DIMM 8Gを2枚です。


メモリの装着はモニタ下面から挿入する24inchとは異なり、背面から行います。電源ケーブルを外すとスイッチが現れ、それを押すことで上部の蓋が開き、メモリへアクセスできるようになります。電源ケーブルを抜くという行為を強制させる、優れた方法だと感じました。




メモリ横のレバーを押すことでメモリスロットが開放され、増設できるようになります。空間が狭い為、やや作業は窮屈です。


結果、総メモリは24Gバイトとなりました。


なお「iMac 21.5-inch, Late 2012」モデルはユーザが自分でメモリを増設することができません。この点は両モデルの大きな違いです。

iMac 27inchの使用感ですが、当然ながら、2008モデルから大きく快適度が増しました。メモリが従来の6Gから24Gになったこと、また、ディスクがFusion Driveとなったことが大きく影響してそうです。開発ツール群の立ち上げが非常に快適になり、複数のアプリケーションを同時に活用できるようになりました。

MacBook ProのRetinaモデルも魅力的であり、選択が悩ましいところですが、持ち運びを行わずに据え置きで利用する方、または大きな画面で作業を行いたい方へは、iMacがお薦めだと思います。Macbook Proよりも安価に高い性能を入手することが可能です。

既にiMac 24inchをお持ちで、iMac 2012モデルへの乗り換えを検討されている方は、21.5inchモデルよりも27inchモデルをお薦めします。接地に必要な面積が24inchと概ね変わらず、一方メモリ増設の自由度やディスク性能が21.5inchよりも大きく優れていることがその理由です。

今まで愛用していたiMac 24inch, Early 2008同様、大事に使っていきたいと思います。