2013年9月30日月曜日

CoreData での DISTINCT 取得

CoreData で重複の無いデータを取得する方法が必要だったので調べてみた。
NSFetchRequest の setReturnsDistinctResults に YES を渡せばよい。

具体的なコードは、以下の通り
今回は例として、name が重複しているデータから重複を取り除いてデータを取得する処理を行う。
    // NSFetchRequest は、検索条件などを保持するオブジェクト
    // 後続処理で、このインスタンスに色々と検索条件を設定する。
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    
    // 検索対象エンティティを指定する。
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Theme" 
                                              inManagedObjectContext:_managedObjectContext];
    [fetchRequest setEntity:entity];
        
    // ソートを設定
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = @[sortDescriptor];
    [fetchRequest setSortDescriptors:sortDescriptors];

    // コードで絞り込んだ値を取得する
    NSDictionary *entityProperties = [entity propertiesByName];
    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:[entityProperties objectForKey:@"name"]]];
    [fetchRequest setReturnsDistinctResults:YES];   // ← ここで指定する
    
    [fetchRequest setResultType:NSDictionaryResultType];
    
    NSError *error;
    NSArray *fetchResults = [_managedObjectContext executeFetchRequest:fetchRequest error:&error];
    if (fetchResults == nil) {
        // Handle the error.
        NSLog(@"fetch error.");
    }
これで、NSArray に重複が除去されたデータが格納されている。

UITabBar のアイテムを選択する

KIF を使用してテストを書こうとしたが、TabBar のアイテム選択の方法が分からない。

UITabBarController を使用してボタンを選択する方法は良くあるけど、UITabBar だけでの選択方法の情報が無かった。

とはいえ、やはり実現している方はおられたので参考にさせていただいた。

【文法】UITabBarのItem(UITabBarItem)の切り替え
http://teapipin.blog10.fc2.com/blog-entry-66.html

現在サンプルで作成しているアプリがナビゲーションコントロールも使っている事もあって、TabBar コントロールを取得するまでが、これまたしんどかったが、こちらも情報が有ったので知識を拝借させて頂いた。

UIViewからUIViewControllerを見る
http://ameblo.jp/pyon-prog/entry-11329857939.html

上記 2 つを合わせて KIF 用のテストを以下のように書いた。
    -(void) testTabBar0Push {
                
        // TabBar の Delegate を発火させるため ViewController まで辿る
        UIApplication *app = [UIApplication sharedApplication];
        UIWindow *window = app.keyWindow;
        
        // rootViewController を取得
        UIViewController *uiview = (UIViewController *)window.rootViewController;
        
        // NavigationController から対象の ViewController を取得
        UINavigationController *navigationController = [uiview.childViewControllers lastObject];
        NSMutableArray *viewControllers = [NSMutableArray arrayWithArray:navigationController.viewControllers];
        ViewController *view = (ViewController *)[viewControllers objectAtIndex:0];
     
        // TabBar
        UITabBar *tabbar = (UITabBar *)[tester waitForViewWithAccessibilityLabel:@"tabBar"];
        UITabBarItem *item = [tabbar.items objectAtIndex:0];
        
        // 選択
        [tabbar setSelectedItem:item];
        [view tabBar:tabbar didSelectItem:item];
        
        // 確認用コードを以下に書く
        ...
    }
どう考えても力業過ぎてコレで良いのか?
と思うがひとまずの動きが出来ているので良しとしようと思う。

今後もっとスマートな方法があれば、また別の記事で書こうと思う。

2013年9月28日土曜日

VIM NeoBundle の通信プロトコルの設定

先日記事にした NeoBundle を前回は Windows の環境だったが、Mac の Vim にも設定しようとしたが、なんだかうまくいかない。

メッセージ云々を見ると、

「...Failed connect to github.com:8080; Connection refused ...」

というメッセージが見える。
コマンドとしては https のプロトコルで通信をしようとしていたのだが、この部分がまずいようだ。

ネットワークの設定としては別段変なことはしている環境ではないのだが、よくわからない。
ブラウザでアクセスすると問題なくページが見えることから、どこかで変な設定が効いているのであろうと思う。

ちなみにと git プロトコルでファイルの取得を行うと、問題なく取得できる。
このことから、ひとまずここでは git プロトコルでの動作方法を考えたところ、
NeoBundle には以下の設定があるとのこと。
    
let g:neobundle_default_git_protocol='git'
この設定通常(指定がなかったら)は git になっているらしいのだが、あえて追加して確認をしてみると上手く動いた。

調査する部分はあるが、ひとまずはこれで動かして行っておこうと思う。

2013年9月27日金曜日

applicationDidBecomeActive が呼ばれた時に ViewController のメソッドを呼ぶ

CoreLocation を使うアプリを作っているが、アプリを閉じる→再開の繰り返しをすると、数回に一度アプリが落ちる現象が出る。

Xcode のデバッガには、「com.apple.CoreLocation.ConnectionClient」と出て落ちているから当たりは間違い無いとは思うが、原因が分からない。

処理としては、CoreLocation の開始を viewDidLoad で行ってた。
そして、バックグラウンドからの復帰時に CoreLocation の開始が行われていないため、無理矢理 applicationDidBecomeActive で、viewController の viewDidLoad を呼ぶようにしていた。
つまり、連続での CoreLocation のスタートをかけているのがまずいのでは?と思い、この部分にあたりを付けてみた。

さて、この場合 1 回だけ Location をスタートするにはどうすれば?

NSLog を張り巡らして見ていると、真っ新からの起動であろうと、バックグラウンドからの起動であろうと、applicationDidBecomeActive を通る事が分かった(公式のドキュメントにも書いてある)。

要するに、applicationDidBecomeActive で、Location の開始処理を行えば良いのだが、applicationDidBecomeActive は、AppDelegate でのメソッドのため処理の関係上 Location のスタートを開始するには不適切だった。
そこで、applicationDidBecomeActive に入ったときに ViewController のメソッドが発行でき、そのメソッドで Location の開始が出来れば良いと思い処理をする方法を調べたところ、以下の実現方法があったので採用した。

これは通知処理を使って、applicationDidBecomeActive が発生したときに発火するメソッドを登録すると言う物。
この登録を viewDidLoad で行う。
当然、いままで有った Location スタートは削除する。
    -(void) viewDidLoad {
        ...
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationDidBecomeActive)
                                                     name:UIApplicationDidBecomeActiveNotification
                                                   object:nil];
        ...
    }
また、applicationDidBecomeActive 後に発動するメソッドを記述する。
ここに、Location のスタートをする処理を入れる。
    // applicationDidBecomeActive が呼ばれた時に実行する
    - (void)applicationDidBecomeActive {
        // CoreLocation 開始
        [_manager startUpdatingLocation];
    }

これで、立ち上げ→バックグラウンドの連続操作を繰り返してみたところ、アプリが落ちる事が無くなった(とはいえ、安心は出来ないので後日合間を見て検証をしてみる)。
他の遷移の場合を考えたらもう少し手間をかける必要は有ったが、取りかかりとしてはこの線で良かった。

2013年9月25日水曜日

KIF を使ってみる

iOS用の結合テストフレームワーク KIF を使ってみた。
ちなみに KIF は、「Keep It Functional」と言う事らしい。

KIF
https://github.com/kif-framework/KIF

Web で情報を集めてインストール等を行ってみたが、どうやらバージョンが違うらしく、
その通りにやってもエラーが出たので、半ば折れかけになってしまった。
公式の英語を頑張って見れば何とかなったので残しておく。

ちなみに今回インストールするバージョンは、 2.0 系
なお、ここでは、テスト被対象を、「製品ターゲット」とし、テストユニットのプロジェクトを「テストターゲット」として記述していく。

1. 製品プロジェクト(製品ターゲット)の作成
今回も適当に Single View Application のプロジェクトを作成する。

2. テストターゲットの作成
プロジェクトナビゲータを開き、下部にある「Add Target」ボタンを押す。
ターゲットの選択が出るので、iOS -> Other を選択し、
「Cocoa Touch Unit Testing Bundle」 を選択する。

プロジェクト名は、任意。
今回は、「Integration Tests」とした。

これで作成した名前と同じフォルダがナビゲータに作成されている。
このフォルダ内にあるファイル(.m/.h)は不要なため削除する。

ここで、一旦 Xcode を閉じる。

3. KIF のインストール
KIF のインストールは、前回使い方を学んだ CocoaPods を使用する。
ターミナルを開き、上記で作成したフォルダまで移動する。

ここに、CocoaPods用のファイル「Podfile」を作成する。
    $ vim Podfile
    platform :ios, '6.0'
    target 'Integration Tests', Integration Tests
        pod 'KIF', '~> 2.0.0'
    end
以下のコマンドでインストールする。
    $ pod install
これで、CocoaPods 用のプロジェクトファイルが作成されるので、
作成されたプロジェクトファイルで Xcode で起動する。

4. テスト用プロジェクトの設定
プロジェクトナビゲータから TARGETS で、作成したテストターゲットを選択。

次に、Build Settings をクリックする。
検索窓等を使って Bundle Loader を検索する。
この設定値が空なら、以下の項目を入力設定する。
    $(BUILT_PRODUCTS_DIR)/アプリ名.app/アプリ名
同じく、検索窓等を使用して Target Host に以下の値をセットする。
    $(BUNDLE_LOADER)
次に、Build Phases の Target Dependencies に、テストターゲットを追加する。

最後に、Scheme -> Edit Scheme で、
Build の項目に「+」で、テストターゲットを追加
Test の項目に「+」で、テストターゲットを追加
(この設定で、製品ターゲットを Scheme で選択している状態でも Command + U でテストが走るようになる)

5. テストファイルの作成
ここで、テストを記述するファイルを追加する。
テストターゲットのフォルダに、任意のクラスファイルを作成する。

作成した中でヘッダーファイルには、「KIF/KIF.h」 をインポートする。
    #import <KIF/KIF.h>

    @interface hogeTests : KIFTestCase
    @end
実装ファイルには、以下の内容でメソッドを追加する。
    #import "hogeTests.h"

    // 実行前
    -(void) beforeAll {
    }
    // 都度実行前
    -(void) beforeEach {
    }
    // 都度実行後
    -(void) afterEach {
    }
    // 実行後
    -(void) afterAll {
    }
    // テスト
    -(void) testXXX {
        // Accessibility Label が「SignIn」の UIView をタップ
        [tester tapViewWithAccessibilityLabel:@"SignIn"];
    }
以上で、テストを実行すればテストが動くはず。

ちなみに、1.0 系では KIFTestController を継承して作成するが、2.0 では、このクラスが KIFTestCase になっており、
またシナリオという考えから普通のテストと同じ test~ に変わっている。
シナリオについては、ファイル毎に分ければ良いという事だろうか。

1.0系と、2.0系とのテストケースの記述違いについては、以下を参照

変更点ぽい物
https://github.com/kif-framework/KIF/releases/

あと、UIView などの操作は、「Accessibility Label」 を使用(ラベルを元にコントロールを探す)しているので、
付けていなかった場合はつける事(storyboard で付けるかコードで付ける)。

テストで使えるメソッドについては、インストールされた KIF のソースを見ればメソッドが書かれているので頑張って自分で実装したいメソッドを探し利用する。
また、「SenTestingKit」 も継承しているので、OCUnit での記述はそのまま生かせる。

最後に
感想としては、設定については OCUnit と同じ感じなので普段から利用している人にしたら楽に設定が出来るのではないかと思った。
また、はじめにも書いたがバージョンの違いで全く使い方が違うので迷わない事。
Ver1.0 では、シナリオとか書いてあったのに 2.0 系では全く無くなっていたのは困った。

駆け足で書いて、かつ毎度の事ながらスクリーンショットが無いので把握しづらいとは思う。
とりあえず使える状態に持って行くまでが面倒だが、これも一度設定すれば開発終了まで使えるので、設定の価値は有ると思う。

2013年9月24日火曜日

CocoaPods を使ってみた

ここ最近はテスト関連の情報をよく見る。

そこで、それらのライブラリのインストールには github から取得する方法と、
「CocoaPods」 からインストールする方法が書かれいている。

CocoaPods。。。ここ最近色んな技術の名前を見ているので、消化不良気味で一歩引いていたが、何か良い事有るだろうという事で、調べてみた。

早い話、Xcode でのライブラリ管理が行えると言う物。
Ruby の RubyGem の様な物。

CocoaPods
http://cocoapods.org/

このリンクを見れば、全て書かれてあるが、実際に使ってみないと分からないので、試しに使ってみた。

一緒に参考にしたのは以下のページ

開発レシピ:Objective-Cのライブラリ管理ツール CocoaPods
http://www.iosjp.com/dev/archives/451

これまた、上記のページを見れば終わる(。。。この記事の意味は???)
でも気にしない。
今回は、前回の GHUnit の導入までを試してみる。

1. 前準備
CocoaPods のインストールには ruby(rubygems) を使用する。
ruby(rubygems) を最新の状態でのインストールが良いらしいので、最新の状態にしておく。
$ gem update --system
あと、Xcode の Command Line Tools も必要となるので、インストールする。

2. インストール
以下のコマンドで、CocoaPods をインストールする。
$ gem install cocoapods
インストール完了後は、一旦ターミナルを閉じて再度開き直すと良い。

そのあと、CocoaPods のセットアップコマンドを入力
$ pod setup
余談になるが、以下のコマンドでバージョンの確認が出来る
$ pod --version
3. 対象プロジェクトの作成
CocoaPods でインストールする GHUnit の対象となるプロジェクトを作成する。
今回はテストなので、適当に Xcode から Single View Application を作成する。

次に、テストを格納するプロジェクトを作成
Menu -> File -> New -> Target
作成したプロジェクトから、不要となるファイル(AppDelegate.m/h)を削除する。

プロジェクトナビゲータで、インストールに必要な QuartzCore.framework を追加

ここで、一旦 Xcode を閉じる(不要かも知れない)

4. CocoaPods の設定
上記で作成したフォルダまでターミナルで移動する(xxx.xcodeproj が有るところまで)。
CocoaPods が読み込む 「Podfile」 というファイルを作成する。
$ vim Podfile
platform :ios, '6.0'
pod 'GHUnitIOS', '~> 0.5.5'
5. インストール
Podfile が作成できたら、以下のコマンドによりインストールする。
$ pod install
これで、インストールが始まる。
インストールが完了したら、「xxx.xcworkspace」というファイルが作成されている。
(元々のプロジェクトファイル xxx.xcodeproj とは別に作成されているところに注意) このファイルをダブルクリックして Xcode を起動する。
(ターミナルから 「open xxx.xcworkspace」 とコマンドを打っても開く事が出来る)

6. GHUnit 使用前準備
プロジェクトナビゲータで、Build Settings の Other Linker Flags に 「-ObjC -all_load」 を追加する。

テストプロジェクトに main ファイルを作成する。
    int main(int argc, char *argv[]) {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, nil, @"GHUnitIOSAppDelegate");
        }
    }
7. テストを書く
あとは、テストコードを記述していく。
(CocoaPods のインストールなのでここまでで終了)


注意点:
特に大きくはまった事もなくスムーズに導入できたので良かった。
とはいえ、凡ミスが多少あったので記載します。

引っかかった点としては、
  • Podfile を Profile と間違えていた。
    論外ですな。
    でも、間違ってたんです。。。
  • Podfile の記述で「:」と項目の間にスペースを入れてしまった。
    詰めて記述しないとダメなようです。
    ×「platform : ios」
    ○「platform :ios」
本当にしょうもないミスで恥ずかしい。。。

導入するまでは、また新しい技術かと尻込みしたけど、一度使い方を覚えれば、後の作業に十分対応できてしかも簡単となれば、導入する価値は十分有るなと思いました。

2013年9月23日月曜日

備忘録(リンクのみ) Rails 関連テストについて

覚えとして

Rspec/Capybara/Turnipの入門記事を全力でまとめてみた
http://morizyun.github.io/blog/the-rspec-book-review-rails/

OpenShift で Redmine を立てる

RedHat が提供している Paas で OpenShift と言う物があり、この環境で Redmine を立てる事が出来るとの事なので試してみた。

OpenShift
https://www.openshift.com/

ここの Online というのが Paas の様だ。
また、当然ながら制限もある。

OpenShift Online Pricing
https://www.openshift.com/products/pricing 

個人テストユースなら特に引っかかる事はないとは思うが、目を通しておいた方が良い。
さて、以下からがインストールとなる。

準備
今回は、Windows(7 32bit) 環境で行う。

まず OpenShift のアカウントを作成するところから始める。
これについては、特に問題なく作れると思う。

あと、ruby が使用できる必要があるのでインストールしておく(ruby 1.9)。
同じく git も使うためインストールをする。

1.  クライアントツールのインストール
この作業は、以下を参考として進める。

Get Started with OpenShift
https://www.openshift.com/get-started#cli

このページの最初のツールのインストールまで行う。
D:\> gem install rhc

2. redmine のインストール
この作業は、以下を参考として進める。

openshift/redmine-2.0-openshift-quickstart
https://github.com/openshift/redmine-2.0-openshift-quickstart

まずは、任意のインストール先のフォルダを作成して移動する。
D:\> mkdir openshift
D:\> cd openshift
D:\> rhc app create -a redmine -t ruby-1.9
ログインを求められるので、作成した情報でログインする

次に DB 設定
D:\> rhc cartridge add -a redmine -c mysql-5.1
github よりソースを取得
D:\> git remote add upstream -m master git://github.com/openshift/redmine-2.0-openshift-quickstart.git
D:\> git pull -s recursive -X theirs upstream master
OpenShift のリポジトリへ Push
D:\> git push
ここで、インストール作業が開始される。

3.  確認
インストール完了後に、表示される URL をブラウザで開くか、OpenSift のページをログインしてリンクから辿る事により、Redmine のページが開かれる。

あとは、実際に Redmine にログインしてパスワード(初期は admin/admin)を変更すれば完了。

最後に
2. で書いた quickstart のまんまとなり、全くそのままを実行しただけで出来たので、つまずく事はないと思う。
他にも jenkins も使えるので、後々押さえて行ければと思う。

Hudson プラグイン
http://www.r-labs.org/projects/r-labs/wiki/Hudson

CoreLocation でアプリが落ちる

現在作成している iPhone アプリで、CoreLocation を使用しているが、起動時にアプリが落ちる事がある。
詳細な情報を確認しようと模索するが、どの部分で落ちているかがつかみきれない。
基礎的な部分がまずい気がするので、要調査。

ひとまず、現状での対策ではないかと思われる記事を載せておく。

ipad app running Core Location in background crashes
http://stackoverflow.com/questions/13274148/ipad-app-running-core-location-in-background-crashes

CLLocationManagerDelegate のメソッド内で CLLocationManager インスタンスを release すると EXC_BAD_ACCESS で落ちる
http://d.hatena.ne.jp/glass-_-onion/20110616/1308150765


2013年9月20日金曜日

達人出版会

昨日は GHUnit のさわりをしたけど、それを調べているときに、受け入れテストの自動化についての情報があった。

何と!今はそういう時代なのかと思いながらも、後回しにしていた。
調べてみると、Xcode 標準では、受け入れテストようのコードが厳しいらしい。

今の流行は?と Web をみると、calabash-ios が良いとの事。
早速試してみたけど、簡単には分からなかった(チュートリアルはいける)。

どうやら、この技術は Rails から来ているようで、そこで使われている cucumber という物を iOS に反映したようだ。
そして、その cucumber は、Gherkin 書式と言う物で記述し・・・ああ、気が遠くなる。。。

キュウリやら、ひょうたんやらにまで、やられるとは・・・

さて、ここからが今日の本題。
この cucumber について、Web で調べるのよりも書籍を購入して一貫性をもって確認した方が良いと思い探してみたところ、「達人出版会」というところから電子版での出版物が有る事が分かった。

はじめる! Cucumber 著:諸橋恭介
http://tatsu-zine.com/books/cuke

Rails の本みたいだけど、考え方は同じだろうと思い現在購入検討中。

同じく、今回の目的とは違うが iOS 系の本も有った

エキスパートObjective-Cプログラミング ― iOS/OS Xのメモリ管理とマルチスレッド
著:坂本一樹
http://tatsu-zine.com/books/objc

こちらは、iOS 7 リリース&その他諸々記念で、9/24 までなんと 480 円。

ハッキリ言ってこのスタイルは、すばらしい。
この手の技術書は、パソコンと同じで、数年経ったら過去の技術として陳腐化し、また日本語訳されるには時間がかかり、そして高額と相場が決まっているので、安価でかつスピードが速いとなると、この業界の人には重宝されるのではないかと思ったりする。

ただ、個人的に紙でないのでためらう面もある。
まあ、紙出しすれば良いだけなんだけど。

しかし、この本の発行日は、2012年。
現在は2014年。
そして、Rails では、すでに cucumber から進んでいる様だ。

自分は一体いままで、なにやってたんだろうか・・・

2013年9月19日木曜日

GHUnit のさわりまで使ってみた

GHUnit の導入までを覚えてとして書いておく。
参考とさせていただいたのは、こちら

GHUnitで単体テストをしてみよう
http://alpha.mixi.co.jp/2012/10858/

そのまんまと言う事と、参考先の方が絵があるのでわかりやすい。
(じゃ何でコレ書くの?となるが、やった記録なので。。。)

1. ファイルの入手
github から
https://github.com/gabriel/gh-unit/downloads

今回は、GHUnitIOS-0.5.6.zip — GHUnitIOS 0.5.6 for iOS (Simulator/Device)を使う。

取得した zip を展開する。
GHUnitIOS.framework というフォルダが出来る。
これを組み込んでいく。

2. ターゲットプロジェクト作成
ここでは、確認用なので適当なプロジェクトを作成する。
Xcode から Single View Application を選択
オプションは好みで(Include Unit Tests は不要)

3. テストプロジェクトの追加
2. のプロジェクト作成後、プロジェクトのページを開き
Add Target を押す。

テスト用のプロジェクトなので、Empty Application で良いので選択する。
プロジェクト名はテスト用とわかりやすいようにした方が良いかもしれない。

これで、ターゲットプロジェクト内に、テストプロジェクトが作成される形となる。

4. テストプロジェクトの不要ファイルの削除
テストプロジェクト内(テストプロジェクトのフォルダ内)は、
  • xxxx-Info.plist
  • xxxx-Prefix.pch
以外は不要になるので、上記以外は全て削除する。

5. GHUnit フレームワークを組み込む
ターゲットプロジェクトの Frameworks のフォルダを右クリックし
Add Files to ... をクリックして 1. で入手したフォルダを指定する。
この時、Destination のチェックは要。
Add to targets には、ターゲット/テスト両プロジェクトを指定する。

これで、Frameworks のフォルダに GHUnitIOS.framework が追加される。

6. GHUnit を使ったコンパイル時の設定
プロジェクトのページの TARGET で、テストプロジェクトを選択し、
Build Settings の Other Linker Flags の項目に 「-ObjC」 を追加する。

7. テストメインファイルの作成
テストプロジェクトに、main となるファイルを作成する。
クラスファイルで良い。
名前は任意(SampleTestMain.m/h)
    
    #import <Foundation/Foundation.h>

    @interface SampleTestMain : NSObject

    @end
   
    #import <GHUnitIOS/GHUnit.h>
    #import <GHUnitIOS/GHTesting.h>


    void exceptionHandler(NSException *exception) {
    //    NSLog(@"%@\n%@", [exception reason], GHUStackTraceFromException(exception));
        NSLog(@"%@\n%@", [exception reason], [GHTesting descriptionForException:exception]);
    }

    int main(int argc, char *argv[]) {
        NSSetUncaughtExceptionHandler(&exceptionHandler);
        
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        
        int retVal = 0;
        if (getenv("GHUNIT_CLI")) {
            retVal = [GHTestRunner run];
        } else {
            retVal = UIApplicationMain(argc, argv, nil, @"GHUnitIPhoneAppDelegate");
        }
        
        [pool release];
        return retVal;
    }
GHUStackTraceFromException(exception) でエラーになるので変更した。

8. テストプロジェクトの確認
この状態で、テストプロジェクトを Scheme から選択して実行すると、
GHUnit 用のアプリが立ち上がるはず(テーブルの画面)

9. テスト対象メソッドの作成
ターゲットプロジェクトに、テスト対象となるクラスを作成する。
今回は、割り算して結果を切り上げる動きをするクラス Calc を作成。
    #import <Foundation/Foundation.h>

    @interface Calc : NSObject

    + (NSInteger)divideRoundUp:(NSInteger)numerator denominator:(NSInteger)denominator;

    @end
    #import "Calc.h"

    @implementation Calc

    + (NSInteger)divideRoundUp:(NSInteger)numerator denominator:(NSInteger)denominator {

        CGFloat value = (CGFloat)numerator / (CGFloat)denominator;
        return floor(value);

    }

    @end
10. テスト用クラスの作成
テストプロジェクトにテスト用のファイルを作成する。
今回は、上記の Calc をテストするので CalcTest と言う名前のクラスを作成
    #import <Foundation/Foundation.h>

    @interface CalcTest : GHTestCase{
        
    }

    @end
    #import <GHUnitIOS/GHUnit.h>

    #import "CalcTest.h"
    #import "Calc.h"

    @implementation CalcTest

    // デフォルトはNOですが、UIのテストやメインスレッドに依存するテストを行う場合はYESにします。
    - (BOOL)shouldRunOnMainThread {
        return NO;
    }

    // 本クラスが実行される前に呼び出されます。
    - (void)setUpClass {
    }

    // 本クラスが終了された後に呼び出されます。
    - (void)tearDownClass {
    }

    // 本クラスの各メソッドが実行される前に呼び出されます。
    - (void)setUp {
    }

    // 本クラスの各メソッドが終了された後に呼び出されます。
    - (void)tearDown {
    }

    // 「test~」というメソッド名にすることでテスト対象一覧に出力されます。
    - (void)testDivideRoundUp {
        NSInteger num = [Calc divideRoundUp:100 denominator:3];
        GHAssertEquals(num, 34, @"test");
    }

    @end
11. テストの実行
テスト記述ができたら、テストのプロジェクトを動かすとテストが動く
右上の Run ボタンを押しても良い

12. わざと間違う
間違えの検出ができるか確認するために、わざと間違えて確認する。
    #import "Calc.h"

    @implementation Calc

    + (NSInteger)divideRoundUp:(NSInteger)numerator denominator:(NSInteger)denominator {

        CGFloat value = (CGFloat)numerator / (CGFloat)denominator;
    //    return ceil(value); ここを変える
        return floor(value);

    }

    @end
この状態で、再度実行するとエラーが出るはず。

エラー内容については、シミュレータ側に表示される。

これで、とっかかりまではできたので作っていくだけ。

2013年9月16日月曜日

VIM NeoBundle を使ってみる

VIM は普段使っているが、それ程カスタマイズをせずに使っている。
カラースキーム程度を変えるぐらいで、それ程困っていなかった。

Markdown の情報を検索しているときに、VIM 使い方紹介などがあり、
今は、「NeoBundle」というパッケージ管理が有るという情報を見つけた。

ヘビーユーザには、今更感が有りすぎかも知れないが、使ってみる事にした。

1. NeoBundle を格納するフォルダを作成する
neobundle.vim を格納するためのフォルダを作成する訳だが、
このフォルダの作成場所をどこにするか迷った。

場所としては、$HOME または、$VIM で表示されるフォルダ内に作成することにした。
(後の vimrc ファイルに場所を指定する所があるので、任意の場所でもいい気がするが気にしない)
    Vim を起動して、「:」を押して
    echo $VIM
    または
    echo $HOME
    で確認できる。
今回は $HOME(C:\vim)の場所が都合良かったのでこの場所にフォルダを作成する。
    cd c:\vim
    mkdir _vim
    cd _vim
    mkdir bundle

2. neobundle.vim を取得する
取得には、git が必要になる。
(別段  https://github.com/Shougo/neobundle.vim から zip なりを落として、1.で作ったフォルダに移動させても良いが、git には慣れておく方が吉)
作成したフォルダで以下のコマンドを発行して取得する。
    git clone git://github.com/Shougo/neobundle.vim

3. vimrc に設定を追加
取得しただけでは、使えいないので、vimrc に設定を追加する。
以下のように記述する。
ここでは、vimfiler を追加するように設定している(unite.vim.git は vimfiler に必要)。
    set nocompatible
    filetype off            " for vundle

    if has("vim_starting")

    set rtp+=$VIM/_vim/bundle/neobundle.vim/  ← ここで1.で作成したフォルダを指定
    call neobundle#rc(expand('~/_vim/bundle'))  ← ここで1.で作成したフォルダを指定
    endif

    filetype plugin indent on     " Required!

    " Installation check.
    if neobundle#exists_not_installed_bundles()
      echomsg 'Not installed bundles : ' .
            \ string(neobundle#get_not_installed_bundle_names())
      echomsg 'Please execute ":NeoBundleInstall" command.'
      "finish
    endif

    " NeoBundle 管理するパッケージを指定する
    NeoBundle 'git://github.com/Shougo/unite.vim.git'
    NeoBundle 'Shougo/vimfiler'

4. NeoBundle を実行
VIM を立ち上げ、「:」でコマンドモードにして、「NeoBundleInstall」と入力し(途中でTab補完を使えば楽に入力できる)実行する事により、問題なければ指定したパッケージがインストールされる(少し時間がかかるときがある)。

上手くいったなら、1.で指定したフォルダ配下にパッケージ管理のためのフォルダが展開されている。

あとは、追加したいパッケージがあれば、vimrc に追加すれば良い。
その際のパッケージの管理コマンドは以下の通り
    更新
    :NeoBundleInstall!
    削除(vimrc から消したいパッケージを削除した後)
    :NeoBundleClean
また、Vim 起動時に「Overwrite previous ~」とアラートが上がる場合は、vimrc に記述がダブっている場所がある可能性がある。

2013年9月13日金曜日

UILabel のタッチで Safari を起動

HTML で言うところの A タグを実現する方法。
ラベルや画像にはアクションが付くものと思い Storyboard から Action で繋げようと頑張ったが、出来なかったので方法を調べてみた。

どうやらラベルや画像のコントロールの userInteractionEnabled プロパティを有効(YES)にすることによって、タッチ時のイベントが取れるようになるようだ。
ただ、これだけではイベント受け取り側ではどのコントロールのイベントが判断出来ないので、判断材料するため tag プロパティに値を設定して、コントロールの判断をするようにする。

あとは、決めうちにはなるが、表示する URL を URLスキームを使用して Safari を起動するようにすれば良い。


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // ラベル
    myLabel.userInteractionEnabled = YES;
    myLabel.tag = 10;
    // 画像
    myImage.userInteractionEnabled = YES;
    myImage.tag = 20;
}

// タップイベント判断
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    if (touch.view.tag == myLabel.tag) {
        [self tapLabel:myLabel];
    } else if (touch.view.tag == myImage.tag) {
        [self tapImage:myImage];
    }

}

// ラベルタップ処理
-(IBAction)tapLabel:(id)sender {

    NSLog(@"label tap!!");
    // タップ元はこれで取得できる(今回は別に使わないが・・・)
    UILabel *label = (UILabel *)sender;

    // ここでは Google を起動
    NSURL *url = [NSURL URLWithString:@"http://www.google.com"];
    [[UIApplication sharedApplication] openURL:url];
 
}

// イメージタップ処理
-(IBAction)tapImage:(id)sender {

    NSLog(@"Image tap!!");
    // タップ元はこれで取得できる(今回は別に使わないが・・・)
    UIImage *image = (UIImage *)sender;

    // ここでは メーラを起動
    NSURL *url = [NSURL URLWithString:@"mailto:xxxx@xxxxx.xxx"];
    [[UIApplication sharedApplication] openURL:url];

}

これで少し、ラベル・画像が便利になった。

2013年9月12日木曜日

Blogger の投稿が自動的に Google+ へ

Blogger で公開ボタンを押すと、以前までは Google+ に表示するコメントを書くダイアログが出ていたのだが、いきなり投稿されるようになっている。

ブログ書いてあのコメントを入れるとき、確かに内容に困る事はあるが、あれはあれで良い仕様だった。
なくなったのか?と思ったが、Blogger 側の Google+ の項目が変わっていた。

設定は以前は、Google+ に投稿するかどうかだけだった気がしたが・・・
現在は以下の様になっている。


つまり、この「投稿後に自動的に共有する」と言うのが、変わった動きの原因。
このチェックを外すと、その下の「投稿後に共有のメッセージを表示する」にチェックが移る。
これで、以前通りのスタイルとなる。

しかし、いきなり動きの変更をかけるとは・・・
と、思っていたが、さっき「概要」の所にメガホンマークが出て、それをクリックすると「自動的にGoogle+ に上げるぜ」的なメッセージが表示された。

何となく事後報告っぽい気がするが、気にしない。

NSArray を使った NSDictionary でのソート

CoreData を使っているが、リレーションをしている状態でソートのかけ方が分からなかった。
とりあえず、CoreData については、今後のスキルアップにより方法が見つかるだろうと信じ、別の方法を取る事を考えてみた。
今回は、必要データだけを取り出してソートをかける方法が思いついたので、その方法を取ってみる。

この場合は、NSArray に NSDictionary 型のデータを格納し、NSSortDescriptor を使用する事により、
NSDictionary に格納しているデータをキーとして並び替えが行える事が分かったので実装してみた。

コードは以下の通り
    // 並び替えをするデータを用意
    NSArray *dataArray = [NSArray array];
    for(int i=0; i<5; i++) {
        
        NSDictionary *mdic = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSString stringWithFormat:@"%d",i], @"index",
                              10-i, @"count"
                              , nil];
        dataArray = [dataArray arrayByAddingObject:mdic];
    }
    
    NSSortDescriptor *sortDescCount;
    sortDescCount = [[NSSortDescriptor alloc]initWithKey:@"count" ascending:NO];

    NSArray *sortDescArray;
    sortDescArray = [NSArray arrayWithObjects:sortDescCount, nil];
    
    NSArray *sortArray;
    sortArray = [dataArray sortedArrayUsingDescriptors:sortDescArray];

    // 内容確認    
    for(NSDictionary *dic in sortArray) {
        NSLog(@"sort data count = %@, index = %@", [dic objectForKey:@"count"], [dic objectForKey:@"index"]);
    }

一応ログ出力で、問題ない事を確認した。
上記は、並び替えのキーが一つだが、複数キーも対応できる様だ。
処理の幅が広がるね。

2013年9月10日火曜日

iPhone 向け 艦隊これくしょん用タイマーを作った

「艦隊これくしょん」知ってますか?
戦艦を擬人化かつ女の子にしたブラウザゲームです。

艦隊これくしょん
http://www.dmm.com/netgame/?utm_source=af&utm_medium=asp&utm_campaign=pc

このゲームで、戦艦の開発や、修理、遠征と言ったイベントの際に、ある程度の時間が必要となります。
数分で済むものから、数十時間かかる物までと幅広くあり、その間ゲームが出来るかというと、そういうわけでもないので、その間は別の事をするようになります。

ブラウザにかじりつくのも良いのですが、他にやれる事があればそちらをした方が有意義でしょう。
そのためにタイマーがあれば、ちょうど良いタイミングでゲームが出来ると言うわけです。

既に、この手のタイマーは色々な人が作成しています。
Windowsフォーム用、iPhone 用(Android も有ると思う)と各種揃っています。

今回、自分は、iOS の使い方の習得を兼ねてシンプルな物を作成しました。
名前は、艦隊コレクション用のタイマーと、簡単をもじって「艦タイ」としました。

艦タイ(無料)
https://itunes.apple.com/us/app/jiantai/id696450394?l=ja&ls=1&mt=8

内容はシンプルに1画面で、遠征×3、入渠×4、工廠×4の計11個のタイマーが並ぶだけと言うシンプルな物となっています。

特に、これと言った特徴もなく、ただただ11個のタイマーが並ぶだけのアプリですが、リリースできたので、興味ある方は使ってみてください。

2013年9月9日月曜日

来年へ向けての手帳を購入 2013

手帳の季節ですね。
文具が大好きな自分としては、4月と10月は文具屋が派手やかになるので、ワクワクしてしまいます。

と、いうことで今年も手帳の購入をしました。
とはいっても、綴じ手帳ではなく、システム手帳を使っているので、リフィルの購入となります。
リフィルは、昨年より「フランクリンプランナー」としました。
最初は何となく、自己管理が出来るかなと思って購入したのですが、思ったほど管理は出来ず・・・しかし、継続が必要という事で今年も購入してみました。
(来年やってダメなら普通のに戻そうとは思っている)

このリフィルは、スティーブン・R・コヴィー博士が提唱したシステムで、「新世代のタイム・マネジメント(時間管理)・ツール」だそうで。。。

フランクリンプランナー
http://www.franklinplanner.co.jp/

本来なら、博士が書かれた「7つの習慣」に沿って目標なりを決定して実践していけば、効率よく仕事・生活ができるらしいです。

実際にシステムに沿って使ってみたのですが、目標を立てたりするのが、苦手かつ現状が現状な物で紙に書き出すのが心を締め付けれる位の厳しい状況なため、簡単にかけるところだけ書いて、あとは普通の手帳リフィルとして使っています。
これが、ダメなんでしょうけどね。

あと、欠点としてこれ高いです。
今回通常版を買いましたが、他にもバージョンがあります。
本当は、トモエリバーを使ったタイプも有るのですが、5,000円を超えた為、日和って通常版にしました。
もう一点、リフィルの横幅が広いです。
これは記入できるスペースが増えて良い面でもありますが、普通のバイブルサイズのシステム帳では、閉じたときにリフィルがギリギリ出るか出ないかのサイズになり、見た目が悪くなります。
(オリジナルのバインダーがありますが・・・好みの物が無く、やっぱり良い値段します。。。)

では、なぜこれを選んだのか?ですが、それは「ほぼ日手帳」が、きっかけとなります。

ほぼ日手帳
http://www.1101.com/store/techo/

この手帳(ほぼ日)の前も色々な手帳を購入していたのですが、あまり良い物が無く、また良いと思ったフォーマットの物が、翌年には売られていない状況でした。

そんな中、「ほぼ日手帳」をどこか忘れましたが、見つけ出し購入しました。
この手帳は、1日1ページ、中身のフォーマットは微妙に変化・進化し、紙は薄いにも関わらずしなやかなトモエリバーを使用し、開けば180度開くという気持ちよさが有り、そして4月10月の安定供給という条件があったのですが、サイズが文庫本サイズと言う事と、綴じ手帳のため、職業柄まとめ情報を手帳を変える度に転記しないと行けないという理由から、別の手帳を漁るようになりました(それでも3年は、ほぼ日を使っていました)。

方向性決まらず、毎年を過ごしていたのですが、ふとしたときに数年前に付けていた「ほぼ日手帳」を見返す機会がありました。
そこには、仕事の思い出やプライベートな事や心境。何も書いていない数ページや、それをフォローするかのような書き込みを見て、面白く、考え深い物があり、良い物だなと思いました。

そしてこれは、「安定したフォーマットと1日1ページは素晴らしい」と言う事に気づき、これらを満たすリフィルは有るか?を調査したところフランクリンプランナーが該当したと言うわけです。
安定したフォーマットと、1日1ページ(今使ってる物は1日見開き2ページ)、そしてシステム手帳なので、情報の転記が不要ということで、条件は完璧。ただ、使いこなせていない。


無駄に長文になりましたが、結局何が言いたいかと言うと、「日々何かの記録を残せば、自分の楽しみと確認が出来る」と言う事です。
過去を振り返るばかりも良くないですが、目標と歩みを見れば、計画通りに向かっているか逸れているかの判断材料になります

どんな形でも良いので、歩みをつけてみるのはいかがでしょうか?

2013年9月7日土曜日

Ruby で APNS を行う(houston)

今日は、Ruby を使って、APNS(Apple Push Notification Service)を行ってみたいと思います。

今回も 1 から作っていくのではなく、mattt さんが作成してるライブラリの力を借りる事にします。
ライブラリの名前は、
houston[ヒューストン] (https://github.com/nomad/houston)

名前の由来等サイトに書かれている気がしますが、、、とりあえず作業に入りたいと思います。
あと、APNS での Push の仕組みなどは Apple のドキュメントを参照してください。

Apple Document: Local Notification および Push Notification プログラミングガイド
https://developer.apple.com/jp/devcenter/ios/library/documentation/RemoteNotificationsPG.pdf

また、今回は完全なシステムを立ち上げるのではなく、あくまで手動で huston を使って Push の確認を取るところまでを記載します。
言うまでもなく実システムに組み込む場合は、細かな処理に手を入れる必要があります。

また、今回は色々なサイトを見させてもらったのですが、PHP で Push を実現する事が出来る apns-php を使っておられる方が非常に分かりやすく解説されており、非常に勉強になりました。
houston 以外の部分(houston もほとんどサイト丸写しなんですけどね。。。)は、こちらのサイトを見たほうがわかりやすいかもしれません。

MonteCut さん
iOS + PHPでPush Notificationを実装する


以下が、作業内容です。
なんども言いますが、1.〜 4. までは確実に
iOS + PHPでPush Notificationを実装する
の方がわかりやすい。。。

1.iOS Developer から Push 用の IDs の取得を行う
Push を行うに当たり、端末の識別番号を取得するなどの処理を行うiPhone側(iOS)プログラムが必要となります。
このプログラムを作りに当たって ID を取得します。
自分は、これまでに IDs の登録時のApp ID Suffix の Bundle ID をワイルドカードの物(Wildcard App ID)で賄っていました。
しかし、Push を行うにはこの形式の物は使えないと、色々なサイトに書かれてあったので、Push テスト用に別途作成しました。


2. 証明書の取得
1. で作成した IDs から証明書ファイルを取得します。
取得した証明書をダブルクリックでキーチェインアクセスへ登録します。

登録後、p12 ファイルを取得します。
取得方法は、キーチェインアクセスで、今回追加した証明書を選択し(キーチェインを「ログイン」、分類を「自分の証明書」を選択すると出てくる)、左の三角を押して、自分の鍵を出した状態で、Ctrlキーで両方選択し、右クリックで p12 形式で書き出します。
(今回名前を AppNameDev.p12 とした) この p12 から pem ファイル形式へ変換します。
$ openssl pkcs12 -in AppNameDev.p12 -out AppNameDev.pem -nodes
そしてその pem ファイルを houston で使用・指定します。

3. プロビジョニングファイルの作成
これも1. 同様に Push で確認を行うためのプログラムを実機で試すために必要なプロファイルです。
どうやら、Push の確認については、実機でないと行えない様なので、これも iOS Developer で取得しておきます。

iOS Developer から Provisioning Profiles と辿り「+」ボタンで作成していきます。
Development は iOS App Development として、Select App ID は、1. で作ったアプリを選択します。
Select certificates. は、自分の証明書を選択
Select devices. は、動かす端末を選択
Name this profile and generate. は、任意のプロファイル名を入れ Generate で作成後、ダウンロードします。
ダウンロードしたものをダブルクリックでオーガナイザに登録します。

4. iOS で Push 対応のプログラムを作成する
XCode を立ちあげ、適当なプロジェクトを選択(Empty Applicationでもいい)し、プロジェクト設定画面を開きます。
PROJECT で、プロジェクトを選択し、Build Settings を選択し、Code Signing の項目の Code Signing Identity の Debug 用プロファイルを 3. で登録した物に設定します。

次に、プログラムを書いていきます。
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...

    // アプリケーションが起動するたびに、デバイストークンを要求してそれをプロバイダに渡すことで、
    // プロバイダが最新のデバイストークンを持つことを保証
    [application registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert)];
    
    return YES;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *) devToken
{ 
    NSLog(@"deviceToken: %@", devToken);
    // 自分のサーバーにトークンを送信する
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *) err
{ 
    NSLog(@"Errorinregistration.Error:%@", err); 
}
実装が問題なくでき、ビルドも通ったら、実行してみてください。
上手くいけば、デバイストークンが取得できるはずです(ログに出力されている)。
ここで、表示されるデバイストークンをメモっておきます。

実際には、ここで取得したトークンを、サーバへ送信して、サーバー側で値を管理する様にしないと行けません。

5. Ruby(huston) のプログラムを作成する
ここでようやく houston の出番です。
houston のサイトから zip ファイルを取得します(git で取得しても良い)
取得したファイルを展開し、任意の場所へ移動します(以降 houstonフォルダとする)。

houstonフォルダ内に、証明書を入れるフォルダを作成します(ここでは、certificateフォルダとする)。
作成したフォルダに、2. で作成した証明書ファイルを入れます。

次に、houstonフォルダに、Push を実行するためのスクリプトファイルを作成します(名前は任意。今回は pushTest.rb とした)
パスの関係上で、Web のサンプル通りだとエラーになったので、各プログラムの読み込むパスを変更しました。
require './lib/houston'  ← ./lib/ を追加
# Environment variables are automatically read, or can be overridden by any specified options. You can also
# conveniently use `Houston::Client.development` or `Houston::Client.production`.
APN = Houston::Client.development
APN.certificate = File.read("./certificate/AppNameDev.pem")

# An example of the token sent back when a device registers for notifications
token = "<4.で取得したトークンを貼り付ける>"

# Create a notification that alerts a message to the user, plays a sound, and sets the badge on the app
notification = Houston::Notification.new(device: token)
notification.alert = "Hello, World!"

# Notifications can also change the badge count, have a custom sound, indicate available Newsstand content, or pass along arbitrary data.
notification.badge = 57
notification.sound = "sosumi.aiff"
notification.content_available = true
notification.custom_data = {foo: "bar"}

# And... sent! That's all it takes.
APN.push(notification)
lib フォルダの houston.rb も同様に
module Houston
  VERSION = "0.3.0"
end

require './lib/houston/client'        ← ./lib/ を追加
require './lib/houston/notification'  ← ./lib/ を追加
require './lib/houston/connection'    ← ./lib/ を追加
ここまで、できれば後は実行するだけです。
$ ruby pushTest.rb
これで、iPhone に Push 通知が飛んできます。

駆け足で書いているため(絵がないからわかりづらい)、抜けているかもしれませんが、また自分でも使うことがあると思うので、その際に修正していきたいと思います。



番外
この huston も、先日のdubai と同様、bin フォルダに apn と言うプログラムが用意されています。
これを使えば、コマンドラインから Push を行う事が出来ます。
(パスは自分の環境に対応してください)
$ apn push "4.で取得したトークン" -c /certificate/AppNameDev.pem -m "Hello from the command line!"

用途に合わせて、使い分けをすれば、軽作業で Push 処理が実現できるかと思います。


2013年9月6日金曜日

目薬購入

技術ネタばかりではなく、たまには買い物ネタをというか、失敗したので戒めのために。。。

ここ数日、目の調子が悪い。
なので、目薬を買いに行ったのでした。

今回は、前々から気になっていた目薬があったので、近くの薬局へ買いに行きました。

その目薬の名前は、「ボーティエ」。
参天製薬が販売しています。
↓ これ

なぜこの目薬か?それは見てください、この形のすばらしさ。
どうやらデザイナーさんが参加しているらしい。
(なんでしょ。普通の目薬でもデザイナーさんがいるはずなんですけどね)

そのデザイナーは、「吉岡徳仁」氏。

どこかで聞いた事ある名前だなと思っていたら、AU の携帯の時にお世話になったデザイナーさんだった。

また、イメージキャラクターが「杉本 彩」さんとなっている。

どうやら、これは女性向けの商品らしく(見たら分かるだろ。。。)、目薬によって美容までやってのけてしまう目薬らしいです。とても画期的だ。

と言う事で、早速買いに行ったのですが、数店回っても置いていなかった。
売れすぎなのかしら?と思い、街中まで足を運んだところ、数店舗回ってやっと置いてある所を見つけました。
購入意欲が高まりすぎて、颯爽と目薬を握りしめレジへ向かったのでした。
そして、驚愕の事実が判明してしまった。

店員さん「1,570円です。

ファッ!高ぇ高えよ。。。

しかし、ここまで来て帰るのもどうかと思い、購入したのでした。

どうです?この金額。普通の目薬なら3~4個程度購入が可能な金額です。
嗚呼と凹みながら、確実に使い切ってやろうと思った次第です。
使うの忘れそうなので、リマインダーへ登録いや、アプリでも作っちゃおうかと思ったぐらいです。

実際に使ってみると、性能は申し分なさそうです(当たり前か)。
そして、この目薬バラの香りがします♪
おっさんから、バラの香りがするわけです。正直キモイです。
あと、エイジング効果が発動するので、目が少年の様になるはずです。
そう、金額をロクに見ずに商品を購入する無謀な少年のように。。。

結論としては、値段見て買えよという事と、Amazon に目を通しておけと言う事でした。
最後に、AUの携帯とのツーショットをどうぞ


Ruby で Passbook を作る(Dubai)

iPhone に標準搭載されている Passbook。
みんな使っていますか?

今回は、Ruby を使用して Passbook を作成する方法を記載します。
とは言っても、1 からの作成ではなく、既にライブラリとして用意されている物を利用させて貰います。

ライブラリ名前は Dubai(ドバイ)
https://github.com/nomad/dubai 作者は Mattt Thompson 氏。
Heroku の方らしい。

ライブラリの名前の由来がダジャレっぽかった気がするが、気にしない。
(ドバイとか分かりやすい名前は良いのだが、情報を調べる際に関係ない物が多くかかるので、こういうネーミングはあんまり好きじゃない)

さて、今回は Passbook を一度作成した事がある方を対象とする。
細かな説明については、他の方が書かれているから。

さて作成に入る。

1. Pass 作成用の p12 ファイルを作成する
iOS Developer から Passbook 用の IDs を作成して、証明書を取得する。
証明書をキーチェインアクセスで選択して p12 形式で書き出す。
(この時のパスワードを覚えておくこと)
このファイルを後ほど使用する。

2. プログラムの取得
github から取得する(今回はGitクライアントを使わずに zip ファイルを落とした)。

次に、zip ファイルを展開する。
dubai フォルダが作成されるので任意の場所へ移動する。

次に、ターミナルで dubai フォルダまで移動する。
ここで、必要ファイルを取得するために
bundle install
をする。

3. 証明書ファイルのフォルダを作成
本当は、どこでもいいんだろうけど、今回は dubai フォルダに
「certificates」 というフォルダを作成し、1. で作った p12 ファイルを格納する。

4. Passbook のフォルダを格納する
Pass が作成できる前段階まで仕上げた物(フォルダ)を dubai フォルダに格納する。
(ここで言う、前段階まで仕上げた物というのは、Appleから取得したテンプレートフォルダに有った signpass プログラムで Passbook が作成できる段階のものを指す)

5. ruby スクリプト作成
dubai フォルダに、適当な ruby ファイルを作成する(今回は passbookCreate.rb と言う名前のファイルにした)

後は、Web のサンプル通りにすれば良いが、パスの指定で、エラーが出たので、
lib フォルダの dubai の読み込みと、lib/dubai.rb のファイルの読み込み部分を変更した。
(ここの辺が、ruby が分かっていない点)
require './lib/dubai' ← "./lib/"を追加

Dubai::Passbook.certificate, Dubai::Passbook.password = "./certificates/証明書.p12", "証明書パスワード"

# Example.pass is a directory with files "pass.json", "icon.png" & "icon@2x.png"
File.open("作成するPassの名前.pkpass", 'w') do |f|
  f.write Dubai::Passbook::Pass.new("Passの元フォルダ.raw").pkpass.string
end
require './lib/dubai/pass'    ← "./lib/"を追加
require './lib/dubai/server'  ← "./lib/"を追加
require './lib/dubai/version' ← "./lib/"を追加
6. 実行
上記まで作業が完了したら、作成したスクリプトを実行する。
$ ruby passbookCreate.rb
これで、.pkpass のファイルが作成されている。
出来たPassbook ファイルをダブルクリックすれば Mac なら Pass を開いて見ることができる。
また、iPhone へ Pass をメールで添付すれば、iPhone に保存することも出来る。
iOS シミュレータなら Pass をドラッグアンドドロップでも行ける。
Web での配信もできるが、面倒なのでここではしない。


番外? pk プログラム
dubai フォルダ内の bin には pk と言うプログラムがある。

これは、
・ Passbook 雛形作成
・ Passbook 生成
・ 配信サーバー機能
が出来る。

Passbook 雛形作成
以下のコマンドで、Passbook 用の雛形フォルダ及び、データが作成される。
$ pk generate [Pass データフォルダ] -T [Pass の種類]
Pass の種類は以下の通り
・ boarding-pass
・ coupon
・ event-ticket
・ store-card
・ generic

これで、作成された pass.json を編集・画像ファイルを準備すれば Pass 作成の準備が完了となる。


Passbook 生成
Passbook 生成前のファイルが準備出来たら、以下のコマンドで Pass の作成を行う
$ pk build Example.pass -c /path/to/certificate.p12
Web ページには、上記の様に書いているが、この通り(Pass名や証明書ファイルとかは当然変える)すると、
Error: PKCS12_parse: mac verify failure
You may be getting this error because the certificate password is either incorrect or missing
とエラーが出る(エラーでも空パスが作成される)。
以下のように -p オプションを付与すると、パスワードを聞いてくるようになる。
$ pk build Example.pass -c ./certificate/pass_certificate.p12 -p
ここのパスワードは、証明書を作成した時のパスワード。
これで、パスが作成される。


配信サーバー機能
※ 正直動いていないのでよくわかない。

以下のコマンドで、パスの作成と配信用のサーバ(Sinatra)が起動できる。
ここでも後ろに -p オプションを付けないとエラーになる。
$ pk serve Example.pass -c /path/to/certificate.p12 -p
Enter certificate password:

== Sinatra/1.4.2 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.5.0 codename Knife)
>> Maximum connections set to 1024
>> Listening on localhost:4567, CTRL+C to stop
これで、localhost の 4567 番ポートにアクセスすればパスが取得できるはずだが、上手く行かなかった。
今回は使わない機能だったので、これ以上の深追いをしないこととした。
ひょっとしたら、localhost ではなくドメインの設定とかも出来るかもしれない。。。

長々と、書いたが非常に簡単なステップで Passbook  の作成ができるので、興味のある方はどうぞ。

2013年9月5日木曜日

Passbook 使っていますか?

iPhone にデフォルトrで入っているアプリに 「Passbook」 と言う物がある。

iOS 6 のPassbook の紹介




実際に、iPhone を所持しているがこのアプリの意味(存在意義)がよく分からなかった。

売りしては、
  • クーポン券や搭乗券などが一括管理できる。
  • 場所や、日時指定によりサーバーから更新とプッシュ通知が出来る。
と言う事らしい。
PCやスマホを使っている人にすると、「で?」という反応しか返ってこない。

つまり、わざわざ専用のアプリで管理する必要無いじゃないかと言う事らしい。
Safari(Web) があれば良いだろと。

確かに。
メールとWebを組み合わせれば、一括管理も出来無くないし、位置情報や日時についても、
今日日のHTML5等々を駆使しすれば出来ない事はない。

じゃ、なぜ Apple がこんな物をと思ったが、要するに「プッシュ通知」が出来る点と、情報を見せるだけのアプリなら「オリジナルでアプリ組まなくても良いよ」ということを売りにしたいのではないか?と思っている。

あと、よく分からないけど、惹かれる物がある。
子供の頃にカードとか集めてた時の楽しい気分が有るからだろうか?

心配なのは、対応しているサイトのない事。。。

Apple 好きの人曰く、Apple は時折使われないようなアプリを平気で入れてくると言っていた。
Passbook が該当しない事を期待しつつ。

何か出来ないか模索したいと思っている。

2013年9月4日水曜日

Heroku の使い方

Heroku の使い方色々。
使い慣れている人には何でもない情報かもしれない。

ログイン
まずは、ログインしないとコマンドを受け付けて貰えない。

$ heroku login


ログの確認
--tail を付ける事によりリアルタイムでの確認が出来る。

$ heroku logs
$ heroku logs --tail


アプリの一覧
登録しているアプリの一覧が取得できる。

$ heroku apps 



毎回 --app と言われて困る
Gui 使っているからか?毎回コマンドを発行する度に --app でアプリを指定しろとメッセージが出る。
言われた通りにアプリ名を指定すれば良いのだろうけど、コマンド毎は流石にしんどい。
remote に設定したら不要になるらしい。
$ git remote add heroku git@heroku.com:アプリのURL.git
既に、remote になっているにかかわらず、app の入力を求められる場合は、以下のコマンドで設定することにより入力不要になる。
$ git config heroku.remote heroku

2013年9月3日火曜日

これが iAd の現実?

iAd を組み込む確認をしていた。
なぜかサンプル通りに書いてみて(というかコピペ)みても、iAd のテストすら表示されない。
この問題は、別記事で出来ればいいとして、今回の本題。

iAd を調べている時に、以下の記事を見つけた。

Studio Loupe スタジオルーペ(さん)|個人iPhoneアプリ開発者のブログ
iAd広告を出稿するとアプリはどれだけダウンロードされる? 76万回表示で0ダウンロード!!?


詳細は、リンク先で確認すると分かるが、要するに
  • iAd の個人で広告主になりやすくなった
  • 出してみたら 76 万回は表示された
  • しかし、ダウンロードはされなかった
ということらしい。
一応、広告クリックで、微々たる収入はあるけど、残念な金額だろうし、今回の目的で行くと紹介しているアプリをダウンロードして貰うのが一番の目的だっただろうから結果失敗と言う事になる。

広告を出すアプリの内容にもよると思うが(今回はバトミントンに関する物。無料)、結構厳しい結果。
ただ、自分としても興味ないアプリは落とさないから、当然の結果か?
これが、ゲームとか少しでも触ってみたいと思うアプリなら結果が変わっていたかも知れない。

あと、76 万回の表示なので、CM 媒体にはなると言う事と、表示させるにはしばらく時間がかかる(~30秒)ので、ある程度画面を開いてもらえるアプリだったんだなと思った。

ものすごい量のアプリが存在するので、その中から選んで貰うには簡単には行かない事が改めて分かった。

PG::Error: ERROR: invalid value for parameter "TimeZone": "UTC"

Rails 備忘録。

今やろうとしている内容が PostgreSQL を使用するものだが、PostgreSQL をインストールせずに rake をかけたら以下エラーが表示される。
$ rake db:create db:migrate db:seed
could not connect to server: Connection refused
 Is the server running on host "localhost" (::1) and accepting
 TCP/IP connections on port 5432?
could not connect to server: Connection refused
 Is the server running on host "localhost" (127.0.0.1) and accepting
 TCP/IP connections on port 5432?
could not connect to server: Connection refused
 Is the server running on host "localhost" (fe80::1) and accepting
 TCP/IP connections on port 5432?
/Users/xxxx/.rbenv/versions/2.0.0-p247/lib/ruby/gems/2.0.0/gems/activerecord-…

ここでは、エラー内容をみると、「5432」ポートとか出ているので、PostgreSQLをインストールした事ある人なら、このポート番号でピンと来ると思う。

なので、この問題については PostgreSQL をインストールすればよい。
調べてみると、インストール方法も数種類(Postgres.app/Fink/MacPorts/Homebrew)存在するため、迷ってしまった。

今回は、app を採用。
インストールと言っても、app をダウンロードするだけ(zip→app)。
(アンインストールの時関連ファイル等をキレイに削除できるのか不明)

起動は、app を実行すれば完了らしい
(メニューバーに像のアイコンが出る) 。

この状態で、再度 rake コマンドを発行してみた。
PG::Error: ERROR:  invalid value for parameter "TimeZone": "UTC"
: SET time zone 'UTC'
/Users/xxxx/Program/Rails/passbook_rails_example-master/config/environment.rb:5:in `'
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
またエラーだ。
内容としてはタイムゾーンがどうのこうのらしいが、よく分からない。
対応方法を調べると、Mac の再起動をかけると良いらしい。
う~んと思いながらも、再起動をかけると。。。上手くいった!!

これは、app を使用したからかも知れない。

Rails rake バージョン違いによるエラー

エラー内容がそのままとなるが、簡単な内容のエラーでも結構あせるので、備忘録として残す。
$ rake db:create db:migrate db:seed
rake aborted!
You have already activated rake 10.1.0, but your Gemfile requires rake 0.9.2.2. Using bundle exec may solve this.
/Users/tatsuosaeki/Program/Rails/passbook_rails_example-master/config/boot.rb:6:in `'
/Users/tatsuosaeki/Program/Rails/passbook_rails_example-master/config/application.rb:1:in `'
/Users/tatsuosaeki/Program/Rails/passbook_rails_example-master/Rakefile:5:in `'
(See full trace by running task with --trace)
自分が持っている rake のバージョンと、今回求められているバージョンに相違があると言う事。
アップデート処理をすると、上手くいった
$ bundle update rake

Mac Heroku toolbelt のプロキシ設定

Mac で Heroku toolbelt を使用する際に、何をやってもエラーが出る。
毎度の事ながらプロキシの設定をしておく必要があった。
$ heroku login ← この処理を実行するとエラーが出る
proxy をセット
$ export http_proxy='http://ユーザID:パスワード@プロキシのサーバアドレス:ポート番号'
$ export https_proxy='http://ユーザID:パスワード@プロキシのサーバアドレス:ポート番号'
毎回なので面倒くさいから .bashrc にでも書けばいいのだが、何か気が引ける。

2013年9月1日日曜日

Firefox アドオン互換性無視と設定の削除

備忘録。
Firefox のアドオンの互換性を無視する方法

「about:config」で設定画面へ移動する。
設定項目が並ぶ部分で右クリックして「新規作成」→「真偽値」

extentions.checkCompatibility.x.x

として(x.x にバージョンを入れる。e.g バージョン23 なら 23.0 とする)、値を 「False」 にする。

これで、互換性は無視できる。
また、これはバージョンごとの指定となるが、

extensions.minCompatibleAppVersion

の値を4.0 となっているところを 0 にすれば、バージョン関係なく無視できる。

これを戻すときは、バージョン関係無しにする方は、4.0 に戻せばいいが、バージョン指定の方は設定を消した方が良い。

これを消す方法は、消す項目で右クリックして「リセット」を押す。
この時点では、表示が残っている。
ブラウザを再起動することにより、削除される。
(起動時に設定値がない項目については削除するようになっているようだ)