読者です 読者をやめる 読者になる 読者になる

PlayFrameworkでキャッシュの有無によってViewを出し分けするサンプル

PlayFrameworkでキャッシュの有無によってViewを出し分けするサンプル

複数の画面間でフォームから入力した値を保持したかったのでキャッシュを使うことにしたのだけれど、

キャッシュの値の有無によって画面表示を変更しようとしたらつまづいたのでメモ。

サンプルプロジェクト

https://github.com/satomikko94/play-cache-sample

  • PlayFramework 2.4
  • Java 1.8

サンプルコード

PlayFrameworkでキャッシュの値の有無によってViewを出し分けするサンプル ref: h ...

実行結果

http://localhost:9000/ にアクセス。

初期画面

Screen Shot 2015-12-13 at 13.33.02.png

初期画面はCache has no data!と表示される。

フォームに適当な値を入力してSubmit

フォーム送信後

Screen Shot 2015-12-13 at 13.34.14.png

Submitすると、フォームの値が下に表示される。

キャッシュに入れているので、直後に画面を更新してもこの値は残ったまま。

キャッシュ期限の1分を過ぎるとまたCache has no data!と表示される。

ポイント

Cache.set

setCache.scala.htmlのフォームで入力した値をApplication.javaでTask型として取得し、

Cache.set("task", task, 60 * 1);

でキャッシュに保持している。キャッシュ期限は60 * 1 = 1分。

このキャッシュは他のクラスやViewから取り出すことが出来る。

キャッシュデータのviewでの取得

ここがつまづいた所。

この後のif文で使用するためには、キャッシュのデータを

@(task : Task = Cache.get("task").asInstanceOf[Task])

で取得してくる必要がある。asInstanceOfでTask型に直すのを忘れずに。

この1行、これより前にHTMLが書かれていると

')' expected but '=' found.というコンパイルエラーが表示されてしまうので

必ずincludeしてるhtmlの最初に持ってくる必要がある。

この件についてはちゃんとした理由書いてあるページあると思うのだけれど見つからなかった・・・

どなたかわかったら教えて下さい。

取得したキャッシュデータの利用

取得できればあとは簡単。if文は

@if(task == null) { }

このように@ifのなかで取得したデータを使用できる。

また、HTMLに取得したデータを埋め込みたい場合は

id : @task.id<br>

という使い方もできる。

Qiita

qiita.com

Apple WatchのNike Runningアプリ使ってみた。

Apple Watch買ってみた。
f:id:Sato_4tree:20150501060904j:image

消費カロリー測ってきたり、1時間に一回くらい立ち上がれと言ってきたり、ランニングアイコンで圧かけてきたりと、
「巨人(デブ)ら……駆逐してやる! この世から……一匹残らず!」 
という意志を見せてくる素敵な時計である。

で、さっそくNike Runningアプリを使ってランニングしてみた。

f:id:Sato_4tree:20150501062923p:image
Apple WatchのNike Runningアプリを開くと、Startボタンが表示される。
今までiPhoneでStartボタンを押してからiPhoneをしまって走りだす、ということをしてたので、手元で操作してそのまま走り出せるのは便利。

ただこのStartボタンを押す前にやるべきことがある。

1. 手首を上げた時の動作を、「最後の操作を再開」にする

デフォルトの設定のままだと、走ってる最中に今の走行距離を見ようと手首をあげたとき、普通に時計の文字盤が表示されてしまう。
ハンズフリーでペースが見れるのをすごい期待してるのに、ただ時計の表示しかされないときのショックはでかい(一回やった)

手首を上げた時に時計でなくNike Runningアプリの情報を出すには、以下の設定を行う必要がある。

iPhoneApple Watchアプリを開く
>一般>手首を上げた時の動作
「最後の操作を再開」にチェックを入れる
f:id:Sato_4tree:20150501095248p:image

これで、ランニングしながら走行距離やペースを確認することができるようになる。

2.  BluetoothイヤホンはiPhoneに接続する。

他のアプリでもそうっぽいのだが、音はiPhone側から出る。
なので、Bluetoothイヤホンとか持ってる人は、Apple WatchじゃなくてiPhoneに接続が必要である。
Apple Watch側のBluetoothに接続しても全く意味なく、iPhoneから出る音声がどんどん垂れ流されてしまうので注意。

以上。これでApple Watchを使って走りることができる。さあ走ろう!


感想など。
1番の「最後の操作を再開」の設定が必要と書いたけど、ちょっと微妙かなと思ってる。
普段は腕を上げた時に時計の文字盤表示、Nike Runningでランニング中の時だけはNike Runningの画面表示、ってしてくれたら嬉しい(Apple が許可してないのかも)

あと、Appleは現在サードパーティ製アプリの心拍センサーへのアクセスを許可していない。
これが出来るようになると、走ってる間の心拍数とか図れるようになるので、Appleを信じて待つしかない。

ただ、やっぱりRunningアプリをハンズフリーの状態で使えるのは嬉しい。
これで数ヶ月後、ほっそりスリムになった自分の姿を夢見て、今日も私は時計をつけるのである。

Paris New Tech September 2014 に行ってきた

f:id:Sato_4tree:20140918052036j:plain

Paris New Tech September 2014 に行ってきた。

Paris New Tech September 2014 #PNT6 - Paris New Tech (Paris) - Meetup

6 new tech startup companies will present their products and technology (5 min demo+5 min Q&A).

スタートアップの企業が自社のサービスを簡単に紹介するイベント。

パリのイベントには珍しく英語での開催。ありがたい。

f:id:Sato_4tree:20140918052434j:plainf:id:Sato_4tree:20140918052535j:plain

会社から徒歩10分くらいのCafeが会場だったんだけど、行ってみたら思った以上に普通のカフェBar。

ほんとにこんなとこで開催するのか?と思いつつ、とりあえずお酒頼んでみる。

f:id:Sato_4tree:20140918053250j:plain

上の階に行ってみたら、ちゃんと開催されてた。

 

紹介されていたのは、

f:id:Sato_4tree:20140918062904j:plain

自分の採寸の3Dアバター作ってネット上で服の試着が出来るサービスや

f:id:Sato_4tree:20140918063123j:plain

写真にブランドや場所のタグを付けてマネタイズにつなげるっていうサービス

f:id:Sato_4tree:20140918063245j:plain

Dropbox的なクラウドサービスやQiita Teamみたいな技術共有サービスなどなど、バラエティに富んでいた。

(Highly secure, European infrastructure っていうのが面白い。こっちの人的にはクラウドはヨーロッパのほうが安全みたいなイメージが有るのだろうか)

 

全部の発表が終わったら、「じゃ、あとは適当にやっといて」みたいなノリで主催者が撤収して懇親会タイム。ゆるい。

f:id:Sato_4tree:20140918064224j:plain

数人と話したけどみんな技術者じゃなくてマーケティングとか広告関連で来てるみたいだった。

あとカナダ育ちの香港人の女の人にあって、あたりまえだけどめちゃくちゃ英語がうまくて私も頑張らないとと実感。

 

その他イベント的に感じたこと

  • 参加者は60-70人くらい
  • Paris New Techだけど具体的な使ってる技術とか実装の話は全然ない。あくまでサービスの紹介
  • BETA版リリースしてるから使ってねとか、人材募集してるよとか言ってたので、そういう目的の人が多かったのかもしれない
  • 日本みたいにPC開いてる人はほぼいない。メモ取ってる人は少しだけいたけど、たいていみんな発表者の話ちゃんと聞いてる
  • 発表5分・Q&A5分。質問する人はそこそこいる
  • Wifiとかない。ケータイの電波すら危うい
  • 飲み物は勝手にバーカウンターで頼んで持ってくスタイル

 

イベント一つでも日本と違う面が見れて面白いなー

Swiftで自分のクラス名を表示する方法

Swiftで自分のクラス名を表示する方法

NSOdjectのサブクラスのdiscriptionメソッドとかで自分のクラス名を表示したいと思ったのだけど、

Swiftではself.classが使えない。

discriptionメソッドで使うだけなので別にクラス名直書きでもいいのだけれど、

なんだかすっきりしないので調べてみた。

コンソール出力や、Unit testなどでクラスを比較するときに使える。

サンプルプロジェクト

https://github.com/satomikko94/PrintProjectName

実行結果

(コンソール出力)

Class name : PrintProjectName.PrintClassName or 
Class name : PrintProjectName.PrintClassName

解説

PrintClassName内のdescriptionメソッドで、

{Project Name}.{Class Name}

の形式でクラス名(及びプロジェクト名)を返している。

func description() -> String {
    return "Class name : \(NSStringFromClass(self.dynamicType)) or \nClass name : \(reflect(self).summary)"
}

NSStringFromClass(self.dynamicType)

dynamicTypeを使うと、インスタンスのクラス自身(サブクラス化されていればサブクラス)が参照される。

(参考 : インスタンスメソッド内でクラスメソッドを呼ぶ #Swift)

Objective-Cself.classとだいたいおなじようにself.dynamicTypeが使えると思われる。

ただ、self.dynamicTypeはそのままコンソール出力すると(MetaType)と出力されるだけなので、

NSStringFromClassを利用してStringに変換すればOK!

reflect(self).summary

reflect()メソッドはオブジェクトの情報を取得するメソッド

そこに.summaryをつけることで、String形式に変換している。

これじゃだめだった

println("\(self.dynamicType)")
// Prints "(Metatype)"

println("\(object_getClassName(self))");
// Prints "0x7b680910 (Pointer)"

println("\(self.className)")
// Compile error!

println(PrintClassName.self)
// Prints "(Metatype)"

Qiitaにも投稿してみた

Swiftで自分のクラス名を表示する方法 - Qiita

モンサンミッシェルに行って来た〜Capitaine Trainでチケット取って旅に出る方法

2週間ほど前だけど、パリからモンサンミッシェルに行ってきた。

f:id:Sato_4tree:20140830060125j:plain

f:id:Sato_4tree:20140902070656j:plain

f:id:Sato_4tree:20140902070741j:plain

その際Capitaine Trainというサービスを使って電車+バスのチケットを取ったのだけど、

これが結構便利で使いやすかったので、チケット予約や発券のやり方を書いておこうと思う。

モンサンミッシェル以外の都市に行くときも使えると思う。

Capitaine Train

Capitaine Train

Capitaine Train: train tickets 6
カテゴリ: 交通
Google Playで詳細を見る

Webサイトの他に、iPhone, Android Appがある(実際私はAndroid Appで予約した)

今回はWebサイトの画面で。

(1) Sine up

会員登録はFacebook認証使って出来る。便利。FBアカウントない人はここで会員登録

(2) 出発元、行き先、往復の時間を指定。

f:id:Sato_4tree:20140831055940p:plain

  • 時間は前後の時間を出してくれるのでだいたいでOK
  • 同行者がいる場合はここで指定する。身分を確認されることがあるから名前はちゃんと入れたほうがいいらしい(今回は全くチケット確認されなかったけど。。)
(3) 行きの道を指定

f:id:Sato_4tree:20140831060316p:plain

  • 電車+バス全て含めた時間と料金が表示される→電車会社のHPで予約するより楽!
  • 1st, 2ndは好きな方を選ぶ(2ndでも十分快適だった)
  • 右下のSeatingのところで座席タイプの希望を出せる(次で詳しく説明)
    • Indifferent : なんでもOK
    • Window : 窓側
    • Aisle : 通路側
    • Twin side-by-side : 隣同士。2人とかで行くとき用
    • Next to... : 多分どこか特定の席と隣にしたいときに使う。詳細不明
  • その下のFacing direction of travelのチェックを入れると進行方向の向きの席を希望できる。(わたしはこれやり忘れて逆向きだった。。。)

最後にSELECT(price)のボタンを押すと、次に進む

(4) 帰りの道を指定。

f:id:Sato_4tree:20140831201408p:plain

これは行きと一緒

(5) 金額、時間、名前を確認。

f:id:Sato_4tree:20140831201815p:plain

OKだったらPAY(price)のボタンを押すと、クレジットカード入力画面に行ける。

ちなみにここまで行けば1回Cartに予約情報が入ってる状態になるので、1回閉じてもCartのところを見れば自分が選択したチケットが表示される。

なのでカード情報の入力はあとからでもOK。

また、下に黄色で囲まれて書いてある「can only be...」は、チケットが駅じゃないと発券できないという意味。

チケットの発券方法

上で言った通りチケットは駅の"SNCF self machine"で発券する必要がある。

発券は当日モンパルナスとか出発する駅で行ってもいいし、前日以前にあらかじめ他の駅で発券することも可能。

何がいいかというと、駅でのチケット発券にはクレジットカードが必要ない。たまに機械で日本のクレジットカードが読み取られなかった、みたいな話も聞くので、これはかなり楽で安心。

駅にあるこういう黄色い機械で発券できる。

https://blog.capitainetrain.com/wp-content/uploads/2014/06/borne-jaune-SNCF1.jpg

発券の仕方は以下のリンクに詳しく載っているのだけど、ここでくわしく説明する。

How do I print my ticket at a French station? - Capitaine Train Help (FAQ)

(1)メールを確認

Capitaine Trainでチケットを予約するとメールが送られてくる。

そのメール本文に書いてある以下の情報を確認。

Reference:

• {6文字の英数字} / {自分の名字}

メールには添付ファイルもあるけど、実際チケット発券に必要なのはこの部分だけ。

(2)真ん中の‘Collection with a file reference number’を選択

https://blog.capitainetrain.com/wp-content/uploads/2014/06/print_at_station_screen.png

(画像引用元上記サイト)

真ん中の一番下にある緑で選択されてるボタンがそれ。上2つはクレジットカード使うやつで違うので注意

(3)‘File and electronic ticket collection’を選択

右側に並んでるボタンから選択。

(4)メールにあった英数字を入力

入力画面が出てくるので、前述したメールにあった{6文字の英数字}を入力

(5)苗字を入力

さらに入力画面が出てくるので、前述したメールにあった{自分の名字}を入力

(6)チケットを選択して印刷

チケットの確認画面が出てくるので、印刷するチケットを選択してPrintボタンを押す。

同行者がいたりで何枚か発見が必要な場合でも、1回で発券できる

(7)チケットを確認

f:id:Sato_4tree:20140902061818j:plain

印刷されてくるチケットがこれ。

画像が見にくいけど、上のチケットの真ん中の方に書いてある「TGV 8091」が電車番号。

何番線のホームかはチケットに書かれてないので、当日自分の番号の電車が何番線に来るのか駅の電光掲示板などで確認すること。

また、右側に書かれている「VOITURE 17」は17号車、「PLACE ASSISE 77」は77番の席という意味。何号車かは電車に書いてある。

あと行き先や乗り継ぎ、時間も要確認!

(わたしはてっきり行きも帰りもレンヌで乗り継ぎかと思ってたら、行きはドル=ド=ブルターニュ乗り換えだって電車乗る直前に気づいた。危なかった・・・)

 

以上がチケット予約して発券するまで。

Capitaine Trainは電車とバスいっぺんに予約できるし候補の時間を色々出してくれるところと、チケット発券がクレカ無しで出来るのがすごく良かったと思う。

モンサンミッシェルまでの金額・時間について

最後にチケットの取り方関係ないけど、モンサンミッシェルまでの金額・時間について。

自分でチケット取っていく方法と、パリからバスツアーで行く方法を比べてみる。

日帰りで行って帰ってくるのを前提。どっちもそんな詳しい知識ないのでだいたい。。

行き方 値段 モンサンミッシェルで過ごせる時間
電車+バス 交通費:往復で75€(10月)〜140€(8月)
修道院チケット:9€
(日本語オーディオガイド+4.5€)
お昼代:約15-20€
--------------------------------
計:約110〜175€
4-5時間
バスツアー 交通費・チケット代・ガイド代・お昼代 (場合によっては他の場所の観光代)込み
------------------------------
計:約130〜180€
2-4時間

私の場合は8月3連休の中日という絶好のタイミングで行ったので交通費だけで140€したけれど、日本語ガイドとかいらないから自分でゆっくり回りたくて電車で行った。

値段も大きく変わらないので(場合によってはツアーのほうが安い)、どっちがおすすめかは人それぞれだと思う。

今くらいの時期なら電車で行ったほうが安い。

あと何点かあるとしたら

  • 4,5時間あってもお昼食べてチケット並んで修道院と島探索しておみやげ買って、ってしてたらほんとにあっという間だった。島滞在2時間とかのバスツアーはほんとに行ってちょっと見て終わりになると思う。
  • 団体で行けば団体専用入り口で並ばずに修道院に入れるので、そこはツアーで行ったほうが時間短縮になる。8月に行ったら20,30分くらいは並んだ
  • Capitaine Trainでみた時に片道4.5-5時間を超えるような道のりだったら、やめてバスツアーにした方がいい(or日にち変えて再度検索)。私の場合は電車バス含めて片道4時間弱で行けた。

f:id:Sato_4tree:20140902071015j:plain

そんな感じで!いつかは泊まりで行きたいなあ。

皆様よい旅を!Bon Voyage!

SwiftでUILabelにHTMLを表示する方法

SwiftでUILabelにHTMLを表示する方法

Objective-Cとあまり変わらないけど、若干つまづいたのでメモ。

注)UILabelなので、あくまで表示しかできません。<a>タグでリンククリックとかさせたい場合はUIWebView使いましょう

サンプルプロジェクト

https://github.com/satomikko94/HTMLToLabel

サンプルコード

var htmlText = "空は<font color=\"blue\">青い</font>。<br>" +
               "An apple is <font color=\"red\">red</font>."

var err:NSError?
self.htmlLabel.attributedText = NSAttributedString(
                  data: htmlText.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true),
               options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType],
    documentAttributes: nil,
                 error: &err)
self.htmlLabel.font = UIFont(name: "System", size: 14)

実行結果

ScreenShot.png

ポイント

NSAttributedString

基本的には以下のリンク(Obj-C)のとおり、NSAttributedStringを使ってHTMLを変換しています

xcode - Display HTML text in UILabel iphone - Stack Overflow

NSErrorはOptionalに

NSErrorの値は必ずnilが入りうるので、?をつけてoptional型にしましょう。

これを忘れると "Extra argument 'data' in call" とか全然関係なさそうなコンパイルエラーになります

fontの設定

HTMLを表示すると、Storyboardで設定したSystemフォントが英字で無効になっちゃうので あとからUIFontで設定してます。

SwiftではfontWithNameが非推奨になってinitでfont設定するようになったようですね

UILabelのLinesは0に

HTMLに限ったことではないですが、UILabelの値が可変で2行以上表示させたい場合には

StoryBoardでUILabelのLinesを0に設定しておきましょう

Screen Shot 2014-08-24 at 21.52.20.png

   

P.S.

同じ内容だけど初めてQiitaに投稿してみた。

SwiftでUILabelにHTMLを表示する方法 - Qiita

QiitaはSwiftシンタックスハイライトしてくれていいなあ。。(こっちではJavaってことにしてる)

Swiftのクラスメソッドの中でクラス定数を使う

私もちゃんと理解してないんだけど、メモ用。Swift限定の仕様じゃないかもしれない。

変なとこあったらご指摘ください。

 

Swiftのクラスメソッド(SwiftではType Methodかな)の中でクラス定数を使おうとした。

Objective-C

#define TEST_VALUE 1

@implementation TestClass

みたいになってるクラスを書き換えたかったのでやってみると、コンパイルエラーで止められる。。。

class ClassHasInstanceMethod {
    
    let testValue:Int = 1
    class let testValue2:Int = 1 // Error! Class variables not yet supported
    
    func getValue() -> Int{
        return testValue
    }
    
    class func getValue2() -> Int{
        return testValue // Error! 'ClassHasInstanceMethod.Type' does not have a member named 'testValue'
    }
}

var instance = ClassHasInstanceMethod()
println(instance.getValue())  // 1

not yet supportedってなんなんだって話なのですが、とりあえず使えない。

あとちゃんと定義してるのにdoes not have a memberって言われてさらに腑に落ちない。

(ちなみにjavaっぽくstaticもつけてみたけど、static letはだめっぽい)

 

結局いろいろ試行錯誤したら、下のようにするとどうにか動いた。

private let testValue:Int = 1 // Define constant out of class
class ClassHasTypeMethod {
    
    class func getValue() -> Int{
        return testValue
    }
}

println(ClassHasTypeMethod.getValue())  // 1

class宣言の外で定数を定義すると、そのファイル内で使える定数になるみたい

(他のクラスから使わないようにするならprivateをつける。)

 

そういわれてみればObj-Cの#defineも@implementationの前でやってるし、これが普通なのか・・・?