AWS S3で独自ドメインを変更する (S3お引越し)

こんにちは。カイザーです。

AWS S3で、静的ウェブホスティングを使用すると、AWS S3でWebサイトを公開できます。しかも、独自ドメインを持っていれば、Route 53に登録するか、CNAMEでエンドポイントを設定するだけで、独自ドメインも使用できます。

しかし、AWS S3では、独自ドメインを使用する際、バケット名と同一でないといけません。
そのため、独自ドメインを変更するには、バケット自体をお引越しする必要がありますので、その過程を説明します。

1. 新規バケットの作成

いつも通り作ります。ただし、バケット名は、新しい独自ドメインと同じにしてください。
また、必要であれば設定をコピーしてください。(筆者に場合はエラーでできませんでしたが。)

2. IAMユーザの作成

バケットのコピーはコマンドラインで行います。Webサイトからは行わないので、専用のIAMユーザを作成します。
AWSでIAMのページを開き、下記のように操作します。

とりあえず、AmazonS3FullAccessにしておきます。

「グループの作成」を押すと元の画面に戻り、作成したグループが追加されているので、それにチェックを入れて「次のステップ:確認」を選択します。

その後、アクセスキーとシークレットアクセスキーが発行されるので、必ず控えておきましょう。

3. s3cmdでお引越し

まずはインストール(macOSの場合)

$ brew install s3cmd

次に初期設定

$ s3cmd --configure

最終確認でこんな感じになります。

New settings:
  Access Key: hogehogehogehogehogehoge
  Secret Key: hogehogehogehogehogehogehogehogehogehoge
  Default Region: ap-northeast-1
  S3 Endpoint: s3.amazonaws.com
  DNS-style bucket+hostname:port template for accessing a bucket: %(bucket)s.s3.amazonaws.com
  Encryption password: 
  Path to GPG program: None
  Use HTTPS protocol: True
  HTTP Proxy server name: 
  HTTP Proxy server port: 0

ここまでできたら、あとは下記です。

$ s3cmd sync s3://[移動元バケット名] s3://[移動先バケット名]

少し時間がかかりますが、これでコピーされます。

ちなみに、これだとオブジェクトの設定まではコピーされなかったので、そこは後で設定する必要がありました。

4. 独自ドメインの設定

下記等を参考に。
http://qiita.com/Ichiro_Tsuji/items/c174d580587a622d3358

これで完了です。ドメインを変更するというよりかは、お引越しでした。

[JS] スマホブラウザでズームしてもスクロールしても下に居座り続けるボックスを作る

こんにちは。カイザーです。
今日はJSです。

以前、拡大操作が前提のスマホ用Webサイトに、画面下に固定の情報を置く必要が出てきました。

拡大できないWebサイトや、PCサイトの場合、単にcssで「position: fixed;bottom: 0px;」とするだけでOKなのですが、これだとスマホで拡大するとレイアウトが崩れてしまいます。

これには現状では対応できないようなので、JSで対応しました。

それで、下記を参考に作ってみました。

スマホ対応の参考に。JavaScriptでウェブページがどのくらい拡大されているのかを取得する方法。

実際には「updateInfoPosition()」で「#information」の位置を、現在のスクロール・拡大率を元に更新しています。また、y座標は計算が複雑だったので、「getScrollBottom()」に分けてあります。

また、JSでのDOMを使った描画更新は重いので、タッチ時・ジェスチャー時は「#information」を隠し、それが終わった1秒後に表示するようにしています。1秒間は、スマホブラウザ特有の惰性移動のため、タイマーで待ってもらっています。

[iOS] Googleカレンダーのログイン認証をGIDSignInに移行する

こんにちは。カイザーです。

今年の4月にWebViewを使用した従来のGoogleログインは使用できなくなり、GIDSignInなどを使用する必要が出てきました。
WebViewでは、普段ユーザが使用しているログイン情報を使用することができず、アプリ毎にユーザがログイン情報を入力する必要があり、煩わしいためです。
そこで、URLスキームを使って普段使用するWebブラウザを使用させるか、WKWebViewなどのWebブラウザとログイン情報を共有出来る方法に移行するわけです。

GIDSignInは、この新しいログイン周りが簡単に行うことができるGoogle公式のライブラリです。WKWebViewを使用します。
今回は、従来の認証からGIDSignInに移行し、Googleカレンダーで使用する、という想定で進めていきます。

1. まずは導入

下記URLに従って導入します。とりあえずログインは出来るようになります。
https://developers.google.com/identity/sign-in/ios/sign-in?ver=swift
その際、以前の「GTMOAuth2ViewControllerTouch」でログインしていた処理は削除してください。

2. ログイン結果を通知

以前は、該当のViewControllerでログイン結果を受け取ることができましたが、今回はAppDelegateで行うようになっています。
そのため、AppDelegateからNotificationを使ってViewControllerに受け渡します。

AppDelegate.swift

extension Notification.Name {
static let googleSignInSuccess = Notification.Name("googleSignInSuccess")
static let googleSignInFailed = Notification.Name("googleSignInFailed")
}

AppDelegate.swift

func signIn(signIn: GIDSignIn!, didSignInForUser user: GIDGoogleUser!,
withError error: NSError!) {
if let _ = error {
// サインインが失敗
NotificationCenter.default.post(name: .googleSignInFailed, object: nil)
} else {
// サインインが成功
NotificationCenter.default.post(name: .googleSignInSuccess, object: nil)
}
}

これで、サインインできた時に通知するところまではできました。

3. ログイン結果の受け取り

あとは、受け取る側のViewControllerでNotificationの受け取りを設定します。失敗の場合はエラー表示します。
LoginViewController.swift

var service: GTLServiceCalend

override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(loginSuccess), name: .googleSignInSuccess, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(loginFailed), name: .googleSignInFailed, object: nil)
}

deinit {
NotificationCenter.default.removeObserver(self)
}

func loginSuccess() {
// ログイン成功
}

func loginFailed() {
let alert = UIAlertController(title: "ログインエラー", message: nil, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil))
present(alert, animated: true, completion: nil)
service?.authorizer = nil
setGoogleAccountLabelText(nil)
}

4. カレンダーAPIのリクエスト


// これは以前と同じです
private let service = GTLServiceCalendar()
func fetchEvents() {
// セッション切れになっているかもしれないので、再ログインしておく
GIDSignIn.sharedInstance().signInSilently()
if let auth = GIDSignIn.sharedInstance().currentUser {
// 以前「GTMOAuth2ViewControllerTouch」から取得していた認証情報は、「auth.authentication.fetcherAuthorizer()」で取得できる。
service.authorizer = auth.authentication.fetcherAuthorizer()
}
// カレンダーのイベントを取得します。service.authorizerに認証情報が入っているため、以前と同じように使えます。カレンダーイベント取得後「finishedWithObject」が呼ばれます。
let query = GTLQueryCalendar.queryForEventsList(withCalendarId: "カレンダーID")
let calendar = Calendar.current
var components = (calendar as NSCalendar).components([.day, .month, .year], from: selectedDate)
components.month? -= 1
var date = calendar.date(from: components)
query?.timeMin = GTLDateTime(date: date, timeZone: TimeZone.autoupdatingCurrent)
query?.singleEvents = true
query?.orderBy = kGTLCalendarOrderByStartTime
service.executeQuery(
query!,
delegate: self,
didFinish: #selector(CalenderViewController.displayResultWithTicket(_:finishedWithObject:error:))
}

ここでポイントになるのが、以前から使用していた「GTLServiceCalendar().authorizer」と、「GIDSignIn.sharedInstance().currentUser.authentication.fetcherAuthorizer()」が同じinterfaceを適用しているので、キャスト可能であるということです。

これは特に文献がなかったので、宣言部をひたすら見て行くしかなかったですね。。(GTLSercieとGIDSignInは両方ともObjective-Cで書かれているので、ヘッダファイルを見ていきます。)

まとめ

GIDSignInに切り替えても、従来のGTLServiceは利用可能。
ちなみに、AndroidはWebViewログインを行わず、OSの機能でログインできるので対応は不要です。

GoogleのAPIを使用していて、まだWebViewで認証している方は、急いで移行してください!

Swiftのmap、filter、forEachでワンランクアップ!

お久しぶりです。カイザーです。

さてみなさん、Swiftしてますか?
いいですよね、Swift。

今日は、Swiftのmap、filter、forEachについて紹介します。

まず概要についてはこちらです。
http://qiita.com/motokiee/items/cf83b22cb34921580a52#enumerate要素と要素のインデックスが欲しい時に使う

つまるところ、これまでforinなどの高速列挙を使って、配列の要素に対して、統一した処理を行ったり、条件分岐して絞り込みを行ったり、、、みたいなことが簡単にできます。

ここでサンプルです。


self.stamps = resultStamps.filter({ (element) -> Bool in
element.category == .normal
})

あるコントローラは「stamps」という配列を持っていて、それは「category」というプロパティを持っています。
その「category」がnormalのスタンプのみを絞り込んでいます。

先ほどの記事の例では数字に関するものが多かったですが、このように、モデルクラスに対しても便利に使うことができます。

そのほかにも、filterはこんな風にも使えます。


self.stamps.filter({ stamp -> Bool in
stamp.count > 0
})

先ほどのスタンプで、所持しているものがフィルターされます。

このような感じで、Swiftでは少し気をつけると、かなり簡潔にプログラミングできます、

配列が関連するループでは、forinさえもあまり使わなくても良さそうですね。
ちなみに、Java 8でも同じような機能があります。Android開発でJava 8を使う際も積極的に使っていきたいところですね。

これを使って格好よくプログラミングしちゃいましよう!

BrabioをTODO代わりに使って1ヶ月経って思うこと

お久しぶりです。カイザーです。今日はTODO管理について紹介します。

人間は必ず忘れる生き物、動物である限り仕方のないことですが、生きていく上では忘れてはいけないことも数多くあります。それをメモしたり、写真にしたりして、記録することにより記憶を補完しているわけですが、簡単な方法の一つとしてTODOリストがあります。

TODOリストはご存知の方は多いと思いますが、現代では様々なTODO管理の手法があります。そのうちの一つを紹介します。

筆者はこれまでメインのTODOリストは「リマインダー」アプリを使用していました。MacとiPhoneで同期を取ることもでき、とても便利なのですが、機能がシンプルであるが故、リマインダーの件数が多くなってくると破綻します。基本的にやるか先延ばしにするか、しかないためです。

そこで、Brabioというプロジェクト管理ツールを新たにTODO管理として使うことにしました。見た目はこんな感じです。

Brabioはガントチャートに特化したプロジェクト管理ツールで、少人数であれば無料で利用できます。TODOはこのガントチャートに登録していく訳ですが、Brabioが優秀なので基本的なガントチャートとしての機能を網羅しており、作業の着手・未着手や、新着率、グルーピングも設定することができます。

また、これもガントチャートの基本ですが、色分けがしっかりなされているため、視覚的にもいつまでに何をやらなければならないのか、何が終わっていないのか、全体の進捗率は何%なのか、すぐにわかります。

というわけで、「ブログを書く」というタスクが、早速遅れてますね(笑)

ダッシュボードでは、プロジェクト管理ツールらしく、こんなグラフも表示されます。

TODOの消化はあまりできていませんね。今週は消化を目指して頑張るぞ!

ちなみに、プロジェクト管理ツールはこれ以外にも、Backlogやサイボウズ、Redmineなどがあります。広義ではGithubやBitbucketもそうですね。これらの機能も紹介できる時があればいいなと思います。

それでは!

岐阜の公共交通 No.1 – 岐阜市の鉄道編

初めまして。カイザーです。

今日は、岐阜市の公共交通について紹介します。
弊社「タイムカプセル株式会社」は岐阜県岐阜市に本社を置いており、
スタッフの中には、今年の4月から、岐阜で生活している方もいらっしゃいます。

岐阜といえば車社会の印象が強いですが、鉄道やバスを駆使すれば、
様々なところに行くことができます。

そこで、岐阜市で使用できる公共交通機関について、紹介します!
(仕事やプライベートなどに活用してくださいね!)

今回は鉄道編です。
岐阜市は、4本の鉄道路線があり、東西南へのアクセスに優れています。

1. JR 東海道本線
大垣方面と名古屋方面に乗車することができます。
駅は、岐阜駅、西岐阜駅が岐阜市内に該当します。

例えば、ソフトピアジャパンに向かうときは、大垣方面の列車に乗車です。
名古屋方面へのアクセスも良好で、競合する名鉄名古屋本線より安く、早く到着します。
しかし、時間帯によってはかなり混雑するため、混雑を避けたいときは、名鉄の特別車がおすすめです。

また、「特急しらさぎ」も発着しているため、金沢方面へのアクセスも良好です。

2. 名鉄名古屋本線
名古屋方面に乗車することができます。
駅は、名鉄岐阜駅、加納駅、茶所駅が岐阜市内に該当します。

競合するJR東海道本線よりも時間とお金がかかりますが、東海道線が通っていないところに駅があったり、
途中の停車駅近辺に、商業施設があるなどの利便性に優れています。
また、特急・快速特急・ミュースカイの種別には、基本的に「特別車」があり、
360円の一律料金を支払うだけで、混雑時でも着席&テーブルが使用できます。(パノラマ席を除く)

移動中に緊急の作業が発生しても、これで快適に作業できますね!

さらに、この名鉄名古屋本線も、JR東海道本線も、豊橋行きが存在しますが、
長距離であれば名鉄の方が安いので、もし豊橋などに行く際は、名鉄を使用するとお得ですよ!
(浮いたお金で、パノラマSUPERの最前列のミューチケットを買うのもアリですね!)

3.JR高山本線
鵜沼・美濃太田・高山方面に乗車することができます。
駅は、岐阜駅、長森駅が岐阜市内に該当します。

本数は、データイムで、美濃太田までは1h/3本で、そのうち1本が「特急ひだ」になります。
美濃太田から先は、さらに本数が少なくなり、高山から先は1日の本数は1桁台です。

「君の名は。」の聖地で有名な「飛騨古川駅」もこの高山本線の駅です。

競合する路線としては、後述の「名鉄各務原線」がありますが、各務原線と近くに駅を持つ「那加駅」「各務ヶ原駅」「鵜沼駅」の各駅へは、
各務原線よりも早く、安く着くことができます。

さらに、日中は可児・多治見方面へ向かう「太多線」と直通しているため、東濃地域へのアクセスも良好です。
ただし、普通列車の本数は競合する各務原線の半分なので、ダイヤを確認してから乗ると良いでしょう。

4.名鉄各務原線
鵜沼・犬山方面に乗車することができます。
駅は、名鉄岐阜駅、田神駅、細畑駅、切通駅、手力駅、高田橋駅が岐阜市内に該当します。

本数は、データイムで、1h/4本と日常使用に適しています。
途中の新鵜沼駅までは、先ほどの高山本線とほぼ並行して走っているため、主要駅へは高山本線を使った方が、早く・安く行けます。

しかし、各務原線のメリットは、その駅の多さです。
ほとんどの駅がとても近くにあり、次の駅まで乗車時間で2分もかかりません。

ただし、日中 15分頃発・45分頃発の電車は、途中の新那加駅から急行となるので注意が必要です。
途中から急行となる電車は、新鵜沼駅では名古屋方面の急行に乗り継ぐことができ、犬山駅では新可児行きの電車に乗り継ぐことができます。
さらに、この乗り継いだ電車は、新可児駅で御嵩行きの電車に連絡しています。

このように、各務原線は、岐阜市・各務原市以外の移動のほか、乗り換えで可児市や御嵩町へのアクセスも良好です。


いかがでしたか?
次回は技術系の記事にしたいと考えていますが、またそちらの方がネタ切れになってしまったら、
岐阜紹介の記事を書こうと思います。

次回の「岐阜の公共交通」は岐阜市のバス編を予定しています。
ありがとうございました。