Watir WebDriverのインストールに失敗する

bundle installするときにエラーとなった。

...
Installing ffi (1.9.3) 
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/bin/ruby extconf.rb 
checking for ffi.h... no
checking for ffi.h in /usr/local/include,/usr/include/ffi... no
checking for rb_thread_blocking_region()... yes
checking for rb_thread_call_with_gvl()... yes
checking for rb_thread_call_without_gvl()... yes
checking for ffi_prep_cif_var()... no
creating extconf.h
creating Makefile

make
Configuring libffi
cd "/Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/ffi-1.9.3/ext/ffi_c/libffi-x86_64-darwin11.4.2" && /Applications/Xcode 5.app/Contents/Developer/usr/bin/make

/bin/sh: /Applications/Xcode: No such file or directory make: *** ["/Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/ffi-1.9.3/ext/ffi_c/libffi-x86_64-darwin11.4.2"/.libs/libffi_convenience.a] Error 127

Gem files will remain installed in /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/ffi-1.9.3 for     inspection.
Results logged to /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/ffi-1.9.3/ext/ffi_c/gem_make.out

An error occurred while installing ffi (1.9.3), and Bundler cannot continue.
Make sure that `gem install ffi -v '1.9.3'` succeeds before bundling.

make のパスに空白が入っているのがダメとのこと。XCodeのフォルダをリネームした。

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/bin/ruby extconf.rb 
checking for ffi.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
    --with-opt-dir
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/bin/ruby
    --with-ffi_c-dir
    --without-ffi_c-dir
    --with-ffi_c-include
    --without-ffi_c-include=${ffi_c-dir}/include
    --with-ffi_c-lib
    --without-ffi_c-lib=${ffi_c-dir}/lib
    --with-libffi-config
    --without-libffi-config
    --with-pkg-config
    --without-pkg-config
/Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:381:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:506:in `try_cpp'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:931:in `block in have_header'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:790:in `block in checking_for'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:284:in `block (2 levels) in postpone'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:254:in `open'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:284:in `block in postpone'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:254:in `open'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:280:in `postpone'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:789:in `checking_for'
    from /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/1.9.1/mkmf.rb:930:in `have_header'
    from extconf.rb:16:in `<main>'


Gem files will remain installed in /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/ffi-1.9.3 for inspection.
Results logged to /Users/h_yamaguchi/.rbenv/versions/1.9.3-p392/lib/ruby/gems/1.9.1/gems/ffi-1.9.3/ext/ffi_c/gem_make.out

わからん。。。こういう時は信頼と実績のStackOverflow

http://stackoverflow.com/questions/17775115/cant-setup-ruby-environment-installing-fii-gem-error

Google Custom Search API

  • 使い方が結構面倒
  • リクエスト回数の制限が結構ひどい。

https://developers.google.com/custom-search/ http://offsidenow.phpapps.jp/archives/415

Yahooなど他のサービスでも事情は同じらしい。

検索して、画面に表示するには以下のようなURLでGetして、結果をJSONで受け取ってパースすればよし。

home_controller.rb

# coding: utf-8
require 'uri'
require 'net/http'
class HomeController < ApplicationController

    def index
        apiKey = "ほげほげ"
        engine = "あうあう"

        #query = params[:query]
        query = "あいうえお"
        #query = "abc"

        url = "https://www.googleapis.com/customsearch/v1?key=#{apiKey}&cx=#{engine}&q=#{query}&alt=json"
        uri = URI.parse(URI.encode(url))

        http = Net::HTTP.new(uri.host, uri.port)
        http.use_ssl = true
        response = http.get(uri.request_uri)
        @result = JSON.parse(response.body)
    end
end

home/index.html.erb

<% @result["items"].each do |item|  %>
<li>
    <a href='<%= item["link"] %>' >
        <span>
            <%= item["title"] %>
        </span>
    </a>
</li>
<% end %>

Google Map API for iOSのマーカーのドラッグが使えない。

以前、Google Map API for iOSでマーカーのドラッグ&ドロップができるようになったと書いたが、

Google Mapsでマーカーをドラッグする - H_Yamaguchiのブログ

自分の環境ではうまくいかない現象が発生している。

self.marker = [GMSMarker markerWithPosition:coord];
self.marker.draggable = YES;
self.marker.map = self.map;

こんなコードを書いて、初期表示の状態でマーカーを追加していた。

これを実行して、そのマーカーを長押ししてもドラッグ状態に遷移しない。 一度、マップの別の部分をスワイプまたはピンチしてマップを動かしたあとに長押しするとドラッグ状態となる。

で、どうしたかというと、draggable=YESを使うことは諦めて、以下のコードを使った。

https://github.com/rweindl/google-maps-sdk-ios-drag-drop

手順としては

(1)下記の3ファイルをプロジェクトに突っ込んで

https://github.com/rweindl/google-maps-sdk-ios-drag-drop/tree/master/GoogleMapsDragAndDrop/GoogleMapsDragAndDrop/Classes/DraggableMarkerManager

(2)GMDraggableMarkerManagerを宣言&初期化

#import "GMDraggableMarkerManager.h"

...
@property (strong, nonatomic, readwrite) GMDraggableMarkerManager *draggableMarkerManager;
...

- (void)viewDidLoad {
...
self.draggableMarkerManager = [[GMDraggableMarkerManager alloc] initWithMapView:self.mapViewdelegate:self];
...
}

(3)マーカー描画時にdraggableMarkerManagerにadd

self.marker = [GMSMarker markerWithPosition:coordOPin];
self.marker.map = self.map;    
[self.draggableMarkerManager addDraggableMarker:self.marker ];

マーカーのアイコン画像を変更する

できるにはできる。GMSMarkerにiconプロパティがあるので、そこにUIImageを設定してあげるだけだ。

CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = @"London";
london.icon = [UIImage imageNamed:@"house"];
london.map = mapView_;

が、このマーカーをRetinaで見ると画像がぼやけて見える。

解決策が今のところ見当たらない。

GMSGeocoderクラスの使い所

がわからない。

- (void) reverseGeocodeCoordinate:(CLLocationCoordinate2D) coordinate
    completionHandler:(GMSReverseGeocodeCallback)   handler 

のメソッドを使って、その緯度・経度に対応する住所を検索してくれるのだが、

[[GMSGeocoder geocoder]reverseGeocodeCoordinate:coordOPin
    completionHandler:^(GMSReverseGeocodeResponse * response, NSError *error){
        for(GMSReverseGeocodeResult *result in response.results){
            NSLog(@"addressLine1:%@", result.addressLine1);
            NSLog(@"addressLine2:%@", result.addressLine2);
        } 
    }];

結果のオブジェクトにはaddressLine1とaddressLine2の2つのプロパティしか無い。

  • どこまでが都道府県で、どこまでが市区町村なのかがわからない。
  • 当然(?)郵便番号などの情報はなし。

上記のコードで実際に出力されるログを見ると、

addressLine1:
addressLine2:東京都台東区秋葉原1−8
addressLine1:
addressLine2:東京都台東区秋葉原1
addressLine1:
addressLine2:東京都台東区秋葉原
addressLine1:東京都台東区
addressLine2:
addressLine1:東京都
addressLine2:
addressLine1:日本
addressLine2:(null)

と出力される。addressLine1と2をどう使い分けろというのか?リファレンス見てもわからなかった。

使い方がわかってないだけかもしれないが、結局、CLGeocoderを使った。

CLGeocoder *geocoder = [[CLGeocoder alloc] init];
            CLLocation *location = [[CLLocation alloc]initWithLatitude:lat longitude:lng];
            [geocoder reverseGeocodeLocation:location completionHandler:
             ^(NSArray *placemarks, NSError *error){
                 for (CLPlacemark *placemark in placemarks) {
                     NSLog(@"administrativeArea:%@", placemark.administrativeArea);
                     NSLog(@"locality:%@", placemark.locality);
                     NSLog(@"subLocality:%@", placemark.subLocality);
                     NSLog(@"thoroughfare:%@", placemark.thoroughfare);
                     NSLog(@"subThoroughfare:%@", placemark.subThoroughfare);
                 }
             }];

localityで市と区が逆に入っているが、そこさえクリアすれば、何とかなりそうな雰囲気。

administrativeArea:神奈川県
locality:鶴見区, 横浜市
subLocality:栄町通
thoroughfare:栄町通 2丁目
subThoroughfare:17番20号

Google Mapsのズームをアニメーションで。

単純にズームしたいだけなら、GMSMapView setCameraUpdateなどを使用する。

GMSCameraUpdate* update = [GMSCameraUpdate zoomBy:17.0f];
 [self.map moveCamera:update];

ただ、これだとズームが即座に行われてなんかカッコよくない。 アニメーションしながらズームさせたい場合はGMSMapViewのanimateToZoomとかを使う。

[self.map animateToZoom:17.0f];

さらに、ここから「アニメーションでズームした直後にほげほげしたい」という場合は単純に

[self.map animateToZoom:17.0f];
[self ほげほげ];

などと書ければよいが、実際にはズームのアニメーション完了を待たずにほげほげが実行される。

アニメーションの完了を待つようなGoogle MapsAPIは用意されていないが、Core Animationと組み合わせれば実現できる。コードが若干長くなるのがいまいち。なんかいい方法ないかな。

[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat: 1.0f] forKey:kCATransactionAnimationDuration];
[CATransaction setCompletionBlock:^{
    [self ほげほげ];
}];
[self.map animateToZoom:17.0f];
[CATransaction commit];

Launch imageを透過でつくる。

と、アプリのアイコンが引き伸ばされたものも一緒に表示されて、残念な感じになる。

f:id:H_Yamaguchi:20131122213508p:plain

うまい方法はないかと調べてたんだけど、無いみたい。Launch Imageは透過でつくるなと。

参考 http://stackoverflow.com/questions/19067480/appicon-overlays-with-launch-image