久しぶりにiOSアプリをビルドしようとしたらエラー
ビルドしようとしたら下記のエラー。
No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).
ググったら、こんなん http://stackoverflow.com/questions/22328882/xcode-5-1-no-architectures-to-compile-for-only-active-arch-yes-active-arch-x 出てきた。
なので、言われたとおり、
- Xcode上でPodsプロジェクトを右クリック→Delete→Remove Reference
- Xcodeを終了
- コマンドラインから
pod install
- .xcworkspace を再度開く
- Podsプロジェクトを選択し、Build Settings→Build Active Architecture Only をNOに (debugがYESになってた)
- 同じく、自分のプロジェクトのBuild Active Architecture Only もNOに (debugがYESになってた)
したら、iOSシミュレータで動くようになった。よかった。
久しぶりにpod installしたらエラー
rubyのバージョン変えてたので、まずはgemのインストール
gem install cocoapods rbenv rehash
で、
pod install
すると、エラーが出てくる。 こんなの
Psych::SyntaxError - (/Users/〜〜〜/.cocoapods/repos/master/CocoaPods-version.yml): mapping values are not allowed in this context at line 3 column 4
ググったら、 https://github.com/CocoaPods/CocoaPods/issues/1853 こんなのが出てきたので、書いてあったコマンドを実行
rm -rf ~/.cocoapods/repos/master pod setup
で、再度
pod install
すると正常に動いた模様。
Vagrantをprovisionしたときにディレクトリを作る
メモ:
ステージング・本番ではcapistranoでデプロイするけど、
ローカルのVagrantではそんなことしないので、
pidを格納するディレクトリが無くて困った。
(nginxで見に行く先を変えればいいけど、そんな部分のchefをいじるのも面倒。。。)
んで、Vagrantfileのsynced_folderとして、テキトーなディレクトリを指定したけど、 sockファイルを作ろうとして、エラーになった。
http://stackoverflow.com/questions/16388342/unicorn-fails-to-start-on-vagrant-box-due-to-errnoeperm
synced_folderしたディレクトリには作れないっぽい。
どうせなので、provision時のshellを使ってみた。
$script = <<SCRIPT mkdir -p /srv/web/shared/pids chown vagrant:vagrant -R /srv/web/shared SCRIPT config.vm.provision "shell", inline: $script
単純にmkdirすると、root権限で作られたので、chownでログインユーザのものに変更。
無事、sockファイルが作れて、nginx -> unicornでページが表示された。
メモ:rspecで変更が無いことをテストする
自分用メモ
expect{hoge}.not_to change{fuga}
で変更が無いことをテストできる
Rank.get_rank_id では、パラメータによって次のランクが返却されるイメージ User#calc_rank!では、Rank.get_rank_id を呼び出し、その結果をDBに保存するイメージ
require 'spec_helper' describe User do describe '#calc_rank!' do let!(:user) { FactoryGirl.create(:user, rank_id: 2) } it do Rank.stub(:get_rank_id).and_return(2) expect{user.calc_rank!}.not_to change{User.find(user.id).rank_id} end end end
Alfred workflowで新規ウィンドウを開く
最近、Alfredを使い始めました。
どうせなら、ということでPowerPackも買って、workflowを使えるようにしました。
- Dash https://github.com/willfarrell/alfred-dash-workflow
- Package Managers https://github.com/willfarrell/alfred-pkgman-workflow
- Launch iOS Simulator http://www.alfredforum.com/topic/2126-launch-ios-simulator/
- IP Address http://dferg.us/ip-address-workflow/
とか入れてます。
で、それなりに便利に使ってたんですが、FinderとかiTerm2を起動しようとして、別のデスクトップに起動してたのがアクティブになるのが不便。。。
というわけで、下記を追加してみた。
Finderを新規に起動する
- Alfredの設定画面を開く
- Workflowsタブを開く
- 左ペインの右下にある"+"を押す
- Templates -> Essentials -> Keyword to AppleScript を選択する
- keywordをダブルクリックする
- Keywordに"nfinder"を入力
- No Argumentを選択
- titleに"new finder"とかを入力
- Run NSAppleScriptをダブルクリックする
- AppleScriptに下記を入力
on alfred_script(q) tell application "Finder" make new Finder window set frontmost to true end tell end alfred_script
上記手順により、Alfred呼び出し -> "nfin"とか入力 -> Enter でFinderが新規に起動します。
iTerm2を新規に起動する
Finderの時と手順は同様。
keywordは"niterm"にしました。
AppleScriptは下記の通り。
on alfred_script(q) if application "iTerm2" is running or application "iTerm" is running then run script " on run {q} tell application \":Applications:iTerm.app\" create window with default profile select first window tell the first window if onlywindow is false then create tab with default profile end if tell current session to write text q end tell end tell end run " with parameters {q} else run script " on run {q} tell application \":Applications:iTerm.app\" activate try select first window on error create window with default profile select first window end try tell the first window tell current session to write text q end tell end tell end run " with parameters {q} end if end alfred_script
これも、Alfred呼び出し -> "nit"とか入力 -> Enter でiTerm2が新規に起動します。
https://gist.github.com/reyjrar/1769355 を参考にしたのですが、zshを利用していたので書き換えました。
アイコンとかサクッと作れれば、フツーに公開するんだけどな。。。
KFCocoaPodsPlugin をインストールしてみる
前に iOSアプリ開発が捗るXcodeプラグイン - Qiita [キータ] で ricobeck/KFCocoaPodsPlugin · GitHub というプラグインが紹介されていました。
便利そうだなーと思いつつ、放置していたのですが、年末年始で少し時間が出来たので、導入してみました。
ただし、githubの説明が
Clone this repo or download the zip, run 'pod install' in the terminal, open the workspace file in Xcode and compile. After a restart of Xcode you have a 'CocoaPods' Menu Item in the Products menu.
しか無かったので、念のためメモ。
※cocoapodsはインストール済みの前提
手順
今回、 ~/bin
に入れておくとします。
cd ~/bin git clone git@github.com:ricobeck/KFCocoaPodsPlugin.git cd KFCocoaPodsPlugin pod install open KFCocoaPodsPlugin.xcworkspace
Xcodeが開くので、Product -> Build
とし、Xcodeを一旦完全に終了させ、再度起動。
すると、公式のgithubにあるように、Productメニュー無いにCocoaPodsが表示されます。
これで入力補完も効くし、黒い画面が無くてもpod install
が出来ます。
SeleniumをRubyから呼んでみる
Gemfileを作って編集する。
bundle init vim Gemfile
入力内容は下記の通り。
source "https://rubygems.org" gem "selenium-webdriver", "‾> 2.38.0”
bundle installを実行する。
bundle install --path vendor/bundle
rubyスクリプトファイルを作成する。
vim drive.rb
内容は下記の通り。
require 'rubygems' require 'selenium-webdriver' driver = Selenium::WebDriver.for :firefox driver.get "http://google.com" element = driver.find_element :name => "q" element.send_keys "Cheese!" element.submit puts "Page title is #{driver.title}" wait = Selenium::WebDriver::Wait.new(:timeout => 10) wait.until { driver.title.downcase.start_with? "cheese!" } puts "Page title is #{driver.title}" driver.quit
実行してみる。
ruby drive.rb
怒られる。selenium-webdriverが読み込めない模様。
`require': cannot load such file -- selenium-webdriver (LoadError)
bundle exec で実行してみる。
bundle exec ruby drive.rb
怒られる。firefoxがインストールされてないから?
Could not find Firefox binary (os=macosx). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path= (Selenium::WebDriver::Error::WebDriverError)
chromeに変えてみて、再実行。やっぱり怒られる。chromedriverが無いとダメらしい。
Unable to find the chromedriver executable. Please download the server from http://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH. More info at http://code.google.com/p/selenium/wiki/ChromeDriver. (Selenium::WebDriver::Error::WebDriverError)
言われたとおり、http://chromedriver.storage.googleapis.com/index.html をブラウザで開いて、最新版(2.7)のmac用をダウンロード。 解凍すると、 chromedriver というファイルが出てくるので、PATHが通っているディレクトリに移動。
で、再実行。
bundle exec ruby drive.rb
無事ブラウザが開き、googleの検索結果が表示され、消えた。 コンソールには
が表示されてた。
・公式のサンプルコードなど
http://docs.seleniumhq.org/docs/03_webdriver.jsp
・参考になりそうなところ
http://qiita.com/tomerun/items/9cb81d7a98150ff22f53
http://morizyun.github.io/blog/selenium-scraping-webdriver-ruby/
doubleのまま計算を続けると、計算誤差が増えるって話
doubleでの計算は、計算誤差が生まれるよ、っていう話。
a の値が正確に"0.9"ではないため、どちらにせよ誤差が生まれるけどね。
コードレビューしてて、doubleだけで計算してるのがあった。。。
小数点を含む計算って、BigDecimalを使うのが当たり前じゃないのか・・・?
iOS用ウェブアプリで出来ないこと
iOS上で動作するサービスを作成しようと思った時、下記のような選択肢があるかと思います。
- ネイティブアプリ(Objective-C で作るようなもの)
- ブラウザアプリ(HTML / JavaScript で作るようなもの)
それ以外にも、それらを組み合わせた
- ハイブリッドアプリ(Objective-C で作った中に、HTML / JavaScriptで作った画面を入れるようなもの)
もありますね。
今回、ブラウザアプリ(Webアプリ?)を作った際に、ネイティブだったら出来るのに、と思ったことを中心にまとめてみます。 (Androidでも、大体同じことが言えるかもしれません)
PUSH通知
ユーザの呼び戻しには、PUSH通知が有効化と思いますが、ブラウザアプリでは実現できない。
- メールアドレスを取得し、それを利用する
- SNSを活用する
あたりで、うまくユーザを呼び戻す必要がある。
クリップボードの利用
PCブラウザでは、「クリップボードにコピーする」ボタンを見たことがあるかと。
これは Flash を利用しており、iOSでは動作しない。
input タグを用意しておき、そこをタップした時に、全選択→iOS標準の「コピー」が表示されるという風にする、というのが妥協案かと。
消えない(消せない)情報を保存する
ネイティブアプリなら、KeyChain が使える。これに入れておけば、アンインストールしても消えない。(はず
ブラウザアプリの場合、データの保存場所としては、Cookie, localstorage などがあるが、
「Cookieとデータを消去」で簡単に消せる。
消されて困る情報は、サーバに保存することになるが、その情報と付き合わせるために、ユーザ認証が必要になる。
特定の環境下で動作させる(Safariだけで動作させる)
ブラウザアプリの場合、Safari 以外で動作する可能性がある。
例えば、Chrome, Operaといったブラウザアプリ、Facebook, TwitterといったSNSアプリなど。
そのへんを、User Agent である程度判定できるが、その後の操作はユーザ任せになる。
そもそも、アプリ側で提供されていないと、Safariで表示させることは不可能になる。
受託の場合は、どこまで対応するか・どのように対応するかなどを、最初に決めておかないともめるかも。
フルスクリーン表示
可視領域を広げる、没入感を与えるといった効果がある、フルスクリーン表示ですが、ユーザに強制することは出来ない。
meta タグなどを利用し、「ホーム画面に追加」を行ってもらい、そこから起動してもらえば、可能。
http://mawatari.jp/archives/web-apps-like-native-apps
アプリがインストールされているかを確認(2013/12/3 追加)
アプリがインストールされていたら、アプリ起動ボタンを表示し、
アプリがインストールされていなかったら、アプリダウンロードボタンを表示する。
みたいなことは出来ない。
http://havelog.ayumusato.com/develop/javascript/e564-url-scheme-fallback.html
こちらにあるように、URLスキームで起動してみて、画面が切り替わって無ければ、ストアへ飛ばす。という動きなら出来る模様。
ただし、見た目はあんまり綺麗には出来ないみたい。(標準のアラートが出てしまったり
Webとネイティブを提供していて、ネイティブも紹介したいだけなら、App Bannerを使えばいいと思います。 https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html
まとめ
いろいろ制約はありますが、Objective-Cエンジニアを必要としないのは、人的リソースの確保はしやすいかも。
ただし、ちゃんとした HTML / JavaScript を書けるエンジニアを探すのも難しいかも。(有象無象が多いイメージ
appleへの申請を必要とせず、好きなタイミングで、全てのユーザに同じ動作環境を提供出来るのは、魅力的だと思います。
他にも、思い出したら・気がついたら追加しようと思います。
第四回 #渋谷java に参加しました
参加してきました。(スポット参戦中のプロジェクトから抜けて)
まとめ
- Grails 使ってみるのはありかも
- groovy 触ってみようかな(とりあえずテストからかな?)
- そのときはSpock を使ってみよう
- Gradle もそろそろ使いたいなー
- JUnitにおけるオブジェクトの等価比較って、他の人も悩んでたんだなー
- コード補完で頑張る以外にも、がんばれば方法はあるんだなー(JSONPath で除外はありかも)
- Servlet のURLって、きれーに出来ないのかなーって思ってたけど、UrlRewriteFilter を使えばよかったのか
- Reactive Extensions って、うまく使えれば便利そうだなー
- ただし、Java8のラムダを使わないと記述量が増えそう
- 並行処理とか、真面目に学ばないとなー
- テンプレートエンジンって、色んなのがあるんだなー
- Juzu Web Framework は、、、まぁ、いいか。
感想
- こういう、色んな技術を知れる場はいいですね〜
- 仕事が無ければ、もうちょっと他の参加者と話してみたかったけど、残念
本
Gradle
- 作者: 五十嵐啓人,伊野亘輝,近藤宇智朗,渡邊恵太,須藤耕平,中島聡,A-Listers,はまちや2,川添貴生,片山育美,池田拓司,濱崎健吾,佐藤太一,曾川景介,久保渓,門脇恒平,登尾徳誠,伊藤直也,mala,後藤秀宣,若原祥正,奥野幹也,大林源,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2013/08/24
- メディア: 大型本
- この商品を含むブログを見る
並行処理
Java並行処理プログラミング ―その「基盤」と「最新API」を究める―
- 作者: Brian Goetz,Joshua Bloch,Doug Lea
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2006/11/22
- メディア: 単行本
- 購入: 30人 クリック: 442回
- この商品を含むブログ (171件) を見る
groovy
- 作者: 関谷和愛,上原潤二,須江信洋,中野靖治
- 出版社/メーカー: 技術評論社
- 発売日: 2011/07/06
- メディア: 単行本(ソフトカバー)
- 購入: 6人 クリック: 392回
- この商品を含むブログ (154件) を見る
雑多なメモ
http://www.slideshare.net/kazuhiroserizawa988/shibuya-java4op ・_y_u_さん Grailsのちょっとイイ話 http://www.slideshare.net/sudoyu/20131116-shibuyajava-grailsgoodness NTTソフトウェアの Grails推進室の方 JGGUGの方 Grails ・Webアプリケーションフレームワーク ・Ruby on RailsのJavaVMで動く奴てきな ・XML設定不要 Groovyのコードで書ける イイところ Javaの世界と地続き JVM環境から逃げたいって人いないですよねー。 中身(一部) Spring Framework Hibernate Apache Tomcat Embed 7 Apache Ivy H2 Database ほとんどのServletコンテナで動く 性能 http://www.techempower.com/benchmarks/ Scala/Lift, Play、Ruby/Rails より速い! Javaの資産の活用 ・Grailsアプリはただのwar いままでの運用ノウハウが活かせる ・Spring / Hibernate の経験が活かせる 学習コストが抑えられる Groovyで書ける クロージャ メタプログラミング / MOP AST変換 DSLを簡単に作れる Groovy-JDK 演算子オーバーロード チェック例外のチェック省略 本:プログラミングGROOVY Spockでテスト JGGUGのワークショップ資料をご覧ください GVM rbenv Goとかぶってる・・・ Grails wrapper Gradle wrapper チェックアウト→コマンドでインストールが不要 Grails console dbconsole DBの中身をWebから見れる プラグイン機構 Security coreとか(View, Controller, Serviceとかがはいる) Serviceとトランザクション 勝手にトランザクション デメリットいところ Checkstyle / Findbugsが使えない CodeNarcを使うことになる パートナー探し Spring / Hibernateの経験があれば! メモリフットプリントが大きい PaaS利用では大きなデメリット ログ出力 log4j内蔵 スタックトレース development モードで画面に出てくる マルチデータソース デフォルトで対応 NoSQL プラグインで対応 Hibernateを使いたくない / SQLを生で書きたくない HibernateのネイティブSQL API Groovy SQLを使う(キャッシュ管理?が必要) MyBatis Grailsプラグインの一覧 list-pluginsコマンド Grailsに対応しているIDE IntelliJ IDEA が一番いい Struts1からの移行 変態プラグインがある Grailsの書籍 2.x系に対応した日本語の書籍は無い 本家のドキュメント 実際の案件で20件ぐらいやってる ものすごい大規模システムで使ったよ、というのはまだない jfluteさん MySQLのJDBCドライバに振り回されるDBFlute フリープログラマーさん 現場での教育や、フレームワークの拡張とかやってます 中がGroovyで出せる 0x1f004 MySQLさん なぜあなたは、バッチ更新しないの? for文で回っとる 別マシンへの通信コストとかあるから、ちゃんと考えようねって教えてたのに。。。 まじでー MySQLさん なぜあなたは、 カーソルフェッチしないの? 数十万件ぐらいだったら、メモリ上に全部乗っかる 本番運用に入って、大量の会員を抱えたあとに発生する(結合テストとかではみつからない) fetchSize に Integer.MIN_VALUE を設定すると、1件ずつの取得になる MIN_VALUEって、、、 い、Integer.MIN_VALUE技!? closeしないから、新しいSQLを発行出来ない。。。 sql_calc_found_rows limitが無かった時の件数が取得できる →MySQLちょっとやるじゃn grimroseさん Gradleについて https://github.com/grimrose/shibuya-java-04 Gradleって何? 現在 version 1.8 世界で一番イケてるビルドツール 本:WEB+DB PRESS val.76 英語ならオライリーにある Gradle 日本語ドキュメント 実験的なところは追いついてないところもある AntからGradle build.xmlのインポート 17章に書いてある project: "Ant + Ivy” MavenからGradle project: “maven” ひな形プロジェクト 1.9からコマンドが変わってる pom.xmlから生成可能 maven plugin→使えません コスト と メリット mavenのレールから外れてる pom.xmlがツライ pluginをそんなに使っていない 使いたいpluginがみつからない →上記に当てはまるひとは gradleへ “mvn …”.execute() プロジェクトに柔軟性を ・gradle wrapper ・custom task or plugin ・task test ・groovy komiya_atsushiさん Junitのオブジェクト透過比較を怠けたい https://github.com/komiya-atsushi/shibuya-java4 代々木の緑色の会社(渋谷じゃない) #TokyoWebmining 事務局 「あるメソッドから返却されるオブジェクトの内容が想定しているとおりか?」をテスト Dto ListBookDto アプローチ ・assertThat() をひたすら並べる →つらい ・equals() を実装する →普通にやるのはつらい、Commonsつかう? ・専用のMatcherを実装する →テストコード量が増える 汎用的な透過比較 Matcher を実装してみた komiya-atsushi/shibuya-java4 IsEquivalentTo の概要&機能 ・データ構造を再帰的にたどる ・equalsをオーバライド ・Json-path的な記法で ・比較的親切(?)なメッセージ 他の人の意見としては、 ・コード補完でがんばる ・toStringでわりきっちゃう kazurofさん UrlRewriteFilterに手を入れてみた http://sssslide.com/www.slideshare.net/kazurof/urlrewritefilterissue120 外向きには綺麗なURLを書き換えるライブラリ 外部:/data/123/… ↓ 内部:/data/get.do?id=123… 3系→4系 URL変換動作の${…}の 関数の連続はNG ネストはOK 木構造で解釈 Interpreterパターン 実際に実装してみることが大事ですね ngsw_taroさん RxJava使ってみた 夢と魔法の待ち時間 https://play.google.com/store/apps/details?id=com.taroid.parkwaittimegetter 自称Kotlinエバンジェリスト Reactive Extensions のJava実装 LINQのデータソースをイベントと非同期処理に拡張したもの ・学習コスト若干高め ・ 書きやすい、読みやすい ・SAM無名クラス(Java8 早く、、、) azusaさん 真にスレッドセーフなHashMapとは http://www.slideshare.net/setoazusa/hash-map-28306457 そのクラスが使われるコンテキストに強く依存する 本:Java並行処理プログラミング タイトルは釣り ConcurrentHashMap使えばいいんじゃね? 新規なら、それ一択 無条件には置き換えられない HashMap extends AbstractMap ConcurrentHashMap extends AbstractMap HashMap の値にnullは入る ConcurrentHashMap の値に nullはNullPointerException synchronizedMap を仕方ないので使う ループするときは呼び出し元で同期しないといけない シリアライズは同期できない ひっかかったケース HttpSessionにHashMapを格納 スレッドごとにオブジェクトを分割すればいい まとめ コレクションAPIには地雷があります スケールアウトの容易さという点では、railsが羨ましい Java並行処理プログラミング を読みましょう eiryuさん Thymeleafのすすめ TwFavViewの作者 Javaのテンプレートエンジン たいむりーふ 最新は2.1系 ブラウザで見てもJSPのように崩れない spring統合用のモジュールがある 属性にth:をつけるだけ data-xxxみたいなのはth:attr マニュアルは短いから、全部読めばいい サンプル:stfm th:text th:each th:remove=“all-but-first" JavaScript inlining URLとか、言語対応とか JSP書いてた人なら問題なく書けるはず スクリプトレットもりもり使ってなければ ブラウザで確認できることはかなり便利 デザイナさんとルール XHTMLで記述する JavaScriptで扱うためのclass名は、”js-“で始める 極力デザイナー作成部分は触らない。逆もまた然り。 追加するイメージ デメリット th:ifの制御 ヘッダ、フッタなど、include はコピペしないといけない Spring以外では、そんなに、、、 seri_k 謎のWAF Juzu FrameWorkを試してみたリベンジ あんまり使われてない? play 1.x系に近い ViewとController機能のみ薄いフレームワーク template は groovy ベース Annotationで機能や設定を指定 mavenでベースをサクッと作れる Annotation Processing を利用する factory pathにjuzu-core.jar 更新を検知して、ファイルが消えちゃう。。。? cleanすると、再生成