AWSの話題を中心に、日々の業務やプログラミングの徒然を綴るエンジニアブログです。

HANDS LAB

HANDS LAB ENGINEERS BLOG

ハンズラボエンジニアブログ

12

カテゴリー: iOS

iOSDC Japan 2017で東急ハンズのiOSデバイス管理手法について話しました


こんにちは。
きんちゃん。(Yusuke Kuroiwa)です。

少しだけ、自己紹介します。
東急ハンズで利用している、HandsPOSと呼ばれる自社のiPad POSレジシステムを、Swiftで1から開発してきました。
普段はiOSエンジニアですが、2015年6月頃から東急ハンズの要件にマッチした、デバイス管理も模索しました。

9月17日に、iOSDC Japan 2017東急ハンズのデバイス管理についてお話してきました。
私は、昨年もiOSDCにて、お話をさせて頂きました。
時間がない、スライドだけみたい人は一番下に貼ってます。
スライドの補足もしてるので、ぜひ読んでほしいです。

iOSDC Japanとは

iOSDC (iOS Developers Conference Japan) は、iOSとその周辺技術に関するエンジニアのためのカンファレンスです。

昨年から始まり、今年が二度目のカンファレンスです。
会場も大きくなり、参加者も増え、セッション数も増大しました!
勉強になるようなセッションが多く、懇親会含め非常に楽しかったです。
スタッフの皆様お疲れ様でした。

発表概要

東急ハンズでは、現在3500台超えのiOS端末を管理しています。
主となるのは、PDAとPOSレジです。
弊社はPDAとPOSを、それぞれiPod touch(iPhone)、iPadに自社アプリを組み込み店舗へ配布しています。
今後、POSの展開が進む中、最終的な管理台数は、4600枚ほどに登る予定です。
さて、このような大量のiOS端末はどのように管理するべきなんでしょうか。
iOSDC Japan 2017では、これらの端末を管理するための実際に得た知見、問題点&ハンズラボが実践するエンタープライズ的対処方法についてお話致しました。

iOSのデバイス管理するための課題と解決

実際に大量のデバイスを管理するとなると、下記のような要件が出てきます。

  • キッティングの問題: 開梱してちまちま設定する必要があり、作業を簡略化してして楽にしたい
  • 業務アプリ(In-House app)配布・管理
  • AppStoreにあるようなアプリを配布・管理
  • 社内ネットワークに接続するためのWi-Fiの設定情報の配布
  • デバイスの紛失時の対処をどうするか

上記のような課題は、MDM(Mobile Device Management)やその他の周辺のサービス、合計4つのサービスを利用することで解決ができます。
4つのサービスの詳細は、スライドを参照を。

MDMから端末へアプリインストール通知が届かない問題

MDMを使えば、管理が簡単になり、キッティングも簡単になり、ハッピーになりました。
ですが、サービス仕様的に回避しようがない問題がたまに現れます。

その1つが、MDMから端末へアプリインストール通知が届かない問題です。
MDMからの端末へコマンド発火はすべてプッシュ通知と同じ原理(APNS)を利用しています。
その為、プッシュ通知が届かない端末へは、デバイスの各種情報、アプリのインストール情報、アプリインストール等ができなくなります。

この中でも特にアプリインストールに関しては、自社のPOSレジ(HandsPOS.app)を配布運用している弊社には大問題です。
プッシュ通知がとどないと、アップデート出来ないのです。
アップデートに失敗すると店舗内で隣のPOSレジはある機能が乗ってるけど、また隣のPOSレジはその機能がないというような問題が発生します。

プッシュ通知が届かないのは、デバイスを再起動を行えば、一時的にプッシュ通知が届くようになりなりますが、数日経てばまた届かなくなります。
根本的な、解決に随分の時間を割いてきました、ポートを開けたり、Wi-Fiを切れないようにしたり、、、根本の解決できず諦めました。
ようわからん。

弊社は、Harakiri-Updater(切腹アップデート、自社でのアプリアップデート手法の呼称)で回避しています。
CrashlyticsのAd-Hoc配信でも同じような方法が利用されていました。

下記に貼っつけているのが、実際にHarakiri-Updaterを行ってみた動画です。

  1. アプリが起動した瞬間に、サーバへ必要なバージョン情報を取得
  2. 必要なバージョンより自分のアプリのバージョンが下回っていれば画面にアラート
  3. 従業員の了解を得たら、スライドに乗ってあるURLスキームを開きます( UIApplication.shared.openURL(plistURL) )
  4. アプリを自爆します。※
  5. URL scheme契機で、システムアラートが表示されます。これはたとえ、アプリが死んでも死ぬ前に発火しておけば表示可能です。
  6. 「インストール」ボタンを押してインストールを続行します。

※ iOS 10以下であれば、自爆は不要です。iOS 11では5番で出て来る「インストール」ボタンを押しても自爆しません。
if #available(iOS 11.0, *) 等で対応しておけば良いでしょう。

他にも

上記で紹介した問題にもエンプラのiOSアプリを運用するにはたくさんの課題と解決をしてきました。
昨年のiOSDCでは下記のような内容もお話しました。

  • iPadを有線化する
  • プッシュ通知でアプリを殺して自動アップデートする
  • iPadがスリープ状態でもお行儀とか考えず、バックグランドで音声流して大量のデータを裏でさばく
  • キッティングが問題ないかを確認するために LibMobileGestalt.dylib の利用

バッドノウハウを駆使してでも業務要件に答えなければなりません。
ですが、安定性が一番大事です。そこも考慮しつつ実装・導入は欠かせません。
HandsPOSに関しては、Crash freeは98%-99%です。

iOSの話ししながら手羽先食べます

【iOSエンジニア向け】ハンズラボようこそiOS手羽の会
2017/09/27(水) 19:30 〜 21:30、東新宿で行います。
うまい手羽先食べながら、弊社のことはもちろんですが、iOSについても話しましょう!

スライド公開

スライド公開しているのでぜひ見てください。

nsnextstep.fmにて

先日のnextstep.fmで、今回のiOSDCの中で面白かった発表と評価いただけました!
ありがとうございます!


iOSDC Japan 2017にブースを出展してきました


こんにちは!POSチームの渡邉です。
新卒として2017年春に入社し、7月からPOSチームでえっちらおっちら頑張ってます。
頑張ってブログも書いていきます!よろしくお願いします!

さて、iOSDC Japan 2017、盛り上がりましたね〜!

弊社はダイヤモンドスポンサー、Tシャツスポンサー、ブース出展、エンジニア2名登壇と
気合が入ったイベントになりました!

登壇した黒岩の資料駒場の資料も合わせてご覧ください。
今回はブース出展にスポットを当てて書いていきますよー!

ブースの様子

イベントといえば、ブース出展といえば、
やっぱりノベルティグッズですよね!
ブースでなにか配っていたらとりあえずもらっちゃうのは私だけではないはず。

弊社はロゴステッカーと公式キャラクター「らぼたん」のステッカー、

そして新しく製作したラバーコースターを準備しました。

 

弊社黒岩が飲んでいたビールを奪って撮った使用イメージはこちら。

ラバー製だから結露してもこぼしても大丈夫なんです!

そしてブースの目玉は、
東急ハンズで実際に使われているiPadPOS「HandsPOS」の展示&デモです!

じゃーん

HandsPOSはiPadを2台使っています。
1台はお客さん用ですが、もう1台は店員さんが操作するものなので
店舗でも滅多に見られない画面を見ることができ、
バーコードを読み込ませて店員さん体験もできるという優れもの!

明日東急ハンズでアルバイトすることになってもなんとかなります。

実際にデモをしていただいた方からは
「すごーい」「おおおー!」といった嬉しい反応をたくさんいただきました。

中には5億円のお釣りのレシートを作った方(!)や、
そのツイートをみて5億円を超えるためにブースにいらっしゃった方(!!)、
クレジット決済のサイン欄にお絵描きする方(!!!)もいて
セッションだけでなく、ブースも盛り上がりました!ありがとうございました!

(POS一式を頑張って運んだ甲斐があった・・・隣の駅だから近いけど・・・)

iOSDCの後は、iOS手羽だ!!

迷えるiOSエンジニアのみなさん!
ハンズラボでHandsPOSを一緒に作りませんか?

・エンプラの世界でゴリゴリiOSと向き合いたい!
・とにかくiOSが好きだ!
・手羽先が好きだ!
・ハンズラボのiOSエンジニアと話してみたい!

こんな方は、ぜひ「ハンズラボようこそiOS手羽の会」に来てみてください!
お酒を飲みながら、絶品の手羽先を食べながら、iOSの話をしましょう!

ご応募はこちらから↓
ハンズラボようこそiOS手羽の会


HandsPOSゆるふわ開発フロー


最近はTypeScriptが楽しい、駒場です。

東急ハンズの内製iPadPOSアプリHandsPOSのゆるふわ開発フローについて書いてみたいと思います。

issue tracker

課題管理には社内全体で Backlog を利用しています。Backlogの課題に対応したGitHubのプルリクエストが作成された場合、Open時にはPRのURLをコメントしマージされた時にはBacklogの課題をCloseするBOTが運用しています。BOTはGitHubのWebHook, API Gateway, Lambdaで出来ています。コードと絡まないようなタスクもこちらに登録しています。

git workflow

developブランチからforkしてfeatureブランチやbugfixブランチをローカルで作成してプルリクを作成しレビュー後にdevelopブランチにマージするフローで、GitHub Flowに近いです。リポジトリにはGitHubを使っています。最近はRebase mergeが好きです。

git commit-hook + lint

lintにはSwiftLintを利用し警告も出ないようにしています。lintで警告が出るコードをコミットしたくないので、gitのpre-commit hookにswiftlintを実行し警告が出ない事をチェックして警告があるようであればエラーにしてコミットを防止しています。commit hookは.gitディレクトリ配下となりコード管理しにくいため、npmの pre-commit を利用してチーム内で共有しています。また、個々人のインストールしているSwiftLintのバージョンが古く、新規ルールを追加しても必要な警告がその人の環境では出ない事も考えられるため、そこは後述のCI(CI環境のSwiftLintは最新を利用)で実行されるDangerで警告されるようにしています。

CI

developブランチへのコミット及びプルリクされているブランチへのコミット時にはCIを走らせてテスト等を実行しています。

  • DEBUGビルド及びUnit Test
  • Releaseビルド
  • プルリクの場合はDangerの実行

CIサービスは最初は無料だったbuddybuildを利用していたのですが、有料化に伴いビルドの早かったCircleCIを現在は利用しています。Travis, CircleCI, Bitrise, Nevercode, buddybuildを試した結果として最近のCircleCIはマシンパワーが上がってCIサービスの中ではちょっぱやです。でも1コミットに対して並列で何か処理させる事は出来ないので、タスクがいくつもあってMatrixをうまく使えれば総合時間ではTravisが速いかもしれません。

Danger

Dangerはいまのところこんなルールで動かしています。Storyboardファイルを変更していたらスクリーンショットのせてねルールが独特でしょうか。あまり使いこなせている感がないです。

Carthage自動PullRequest

アプリで利用しているライブラリはなるべくCocoaPodsではなくCarthageに寄せています。Carthageは carthage outdated で新しいバージョンがリリースされていないかチェックでき、 carthage update --no-checkout コマンドで実際にはframeworkをビルドせずにCartfile.resolveをアップデート出来ます。これらを利用して週に1回CIをスケジュール実行(CircleCIはスケジュール実行の機能がないためLambdaのスケジュール実行でCircleCIのAPIで実行)させ、新しいバージョンがあればCartfile.resolveをアップデートするPullRequestを自動作成するようにしてライブラリは定期的にアップデートしています。

GitHub Releases

新しいバージョンを作成する際はgitのタグを作ります。タグのプッシュイベントの場合はCIは通常のタスクの他にxcarchiveを作成しGitHub Releasesにアップロードするタスクを追加で実行させています。現在はタグの作成後にCHANGELOG.mdの生成のために github-changelog-generator を手動で実行していますがこれもCIのタスクに持っていきたいですね。ただ、このgemですとまだdevelopブランチにはマージされていないけれど、featureブランチに向けたPRのマージも、バージョン間にマージされたものとして載ってきてしまうため、もうちょっと良いものはないかと検討中。

deploy

HandsPOSはEnterpriseアプリなので、AppStoreへの登録はありません。代わりにMDMと呼ばれる管理サービスにipaファイルをアップロードし各端末に配信する形です。弊社では CLOMO をMDMに利用していますが、CLOMOに外部向けのAPIがないため現在は作成したipaを手動でアップロードしています。このあたりの自動化は課題の一つ。最近個人的なサイドプロジェクトでpuppeteerを使い始めたので、それで出来たらいいなと構想しています。また、プロビジョニングプロファイルを1年間更新せずに危うく有効期限切れになる事があったため、現在は定期的に再作成しているが新しいバージョンを作る度に再作成しても問題はないため、そこもspaceship等で再作成->ダウンロードした新しいプロビジョニングプロファイルでipaを作成…と出来ると新しいバージョンを作成するとそこから1年有効なipaが作成出来るので嬉しいですね!

まとめ

書いていくうちに後回しにしている改善がそこそこある事に気付かされました。まだまだ改善していこうと思います!

 

「iOSDC 2017」に本ブログの著者 駒場と、黒岩が登壇します!

https://www.hands-lab.com/news/seminar-events/770

マイナビニュース掲載「エンタープライズの世界で挑戦! ハンズラボのiOSアプリ開発現場に迫る」
http://news.mynavi.jp/kikaku/2017/09/01/002/


iOSアプリの証明書とプロビジョニングプロファイルの有効期限が後何日で切れるかを毎週自動でSlackに通知してみた


ios-cers-and-profiles-bot

はじめまして。三井田(みいだ)です。
4月に新卒としてハンズラボに入社して、早半年がたちました。
大学時代は授業で情報科学などを勉強する傍ら、UnityでモバイルARアプリを開発したり、個人開発のAndroidアプリをGoogle Playに公開したりしていました。
入社後は、新人研修の仮想プロジェクトでひたすらjQueryを書き続ける日々を送った後、現在のチームに配属され、DynamoDBを管理したり、PythonでLambdaを書いたり、PHPとJSで管理画面をより使いやすく改善したりしています。

さて、今回は多くのiOS開発者を悩ませる(?)、iOSアプリの証明書とプロビジョニングプロファイルについてのお話です。

やばい!iOSアプリの証明書の有効期限がっ…!!

1年に1回更新しなければならない、iOSアプリの証明書とプロビジョニングプロファイル。ついつい有効期限を忘れてしまい、期限が切れる直前(もしくは切れた後)に慌てて更新、なんてことはありませんか?
弊社でも先日、とあるiOSアプリの証明書の有効期限が切れる寸前になっていました。
その時は弊社エンジニアが気づき、緊急アップデートを行って難を逃れたのですが、もし気づくのが遅れて、証明書の有効期限が切れてしまっていたら。。。と思うとゾッとします。

そこで、iOSアプリの証明書、プロビジョニングプロファイルの更新忘れを防ぐために、証明書、プロビジョニングプロファイルの有効期限が後何日で切れるかを、毎週自動でSlackに通知するようにしてみました!

こんな感じです

ios-certificates-and-profiles-bot

毎週指定の時刻になると、管理サーバーでシェルスクリプトが自動実行されます(cron)。
スクリプトでは、証明書、プロビジョニングプロファイルの入ったプライベートリポジトリをgit pullした後、リポジトリ内の各.cer、.mobileprovisionファイルについて、後何日で有効期限が切れるのかを計算し、その結果をSlackに通知します。
【**注意!**】証明書、プロビジョニングプロファイルは厳重に管理してください!

スクリプトのソースコードはこちら(GitHub)です。(Linux環境用です。ローカルのMacで実行したい場合は、「$ brew install coreutils」を行った後、「date」コマンドの代わりに「gdate」コマンドを使えば実行できます。)

流れとしては、iOSアプリ証明書の有効期限を取得し、「年/月/日」の形にした後、

後何日で有効期限が切れるのかを計算します。

そしてその結果を、Slackに投稿します。

プロビジョニングプロファイルについても有効期限を取得し、同様の処理を行います。(弊社iOSエンジニア駒場に有効期限の取得方法を教えてもらいました!)

30日以内に有効期限が切れる場合は、アイコンと文言を変えるようにしました。

emergency

【おまけ】有効期限が切れると…

expired
…切れないように気をつけましょう。

まとめ

iOSアプリの証明書とプロビジョニングプロファイルが後何日で切れるのか、Slackに毎週自動で通知されるようになったので、余裕をもって年次更新を行うことができるようになりました!
また、Slackに通知することで、特定の開発者だけが有効期限を把握するのではなく、より多くの人の目で期限をチェックできるのも良いですね!
それでは、今回はこの辺で。

Happy Coding! 😉

参考


はじめまして、1/1からハンズラボにジョインした平井です。


皆さま、はじめまして、1/1からハンズラボにジョインした、アプリケーションエンジニアの平井です。

〜自己紹介〜

■以前は何をやっていたのか

以前は、アプリケーションエンジニアとして、主にエンタープライズ向けのWebアプリや
BToC向けのWebサービスの開発に携わっていました。

■所属チームについて

今は外販のチームに所属しています。
Webアプリ/iOSアプリの開発や巷でホットなSORACOMを使った開発に携わっており、毎日が充実しています!

■今後について

田部井や井上が行っている様なAWSを活用したアーキテクチャ設計・構築や東急ハンズのノウハウを活かした自社サービスの立ち上げ(現時点では未定)にチャレンジしたいと考えています。

今後とも、宜しくお願い致します。

〜Objective-C→Swiftコンバートツールについて〜

■背景

ハンズラボでは、iOSアプリの開発には、Swiftを使うという、じばにゃんからの指示があります。

しかし、今回案件で利用するカードリーダーのSDKの組み込みサンプルは、Objective-Cでの提供しかなく、Objective-Cのコードを目で見て、手動でSwift化するのは、時間的に厳しいと感じました。

そこで、Objective-Cで必要な部分を作ってからコンバートツールを使ってSwift化しました。

今回は、「objc2swift」と云うYahoo!様が開発したツールを使いましたのでそちらをご紹介をします。

■「objc2swift」利用手順

0.前提

事前に以下のモジュールのインストールをしておいてください。
・JDK(ツールはJDKが無いと動きません。)
また、以下の環境の例になります。
Mac OSX(10.11.2)

1.Gradle(SDKMAN!)のインストール

GradleをMacにインストールする際に、Groovy関連のプロダクトのバージョン管理を行うツール(SDKMAN!)を使って Gradleをインストールするのが一般的なやり方みたいです。

最初に、SDKMAN!をインストールします。

「sdk help」でhelpが表示されたらSDKMAN!のインストール完了です。

次に、Gradleのインストールをしてみます。

「gradle -v」でバージョンが表示されたら「gradle」のインストール完了です。

2.objc2swiftのビルド

■使ってみた感想

・300Stepくらいのプログラムで50箇所程度、コンバート時にエラーがありました。
・統計を取った訳ではありませんが、オプショナル型に関してのエラーが多かった様に思えます。
・同じ様なエラーが多く、まとめて修正できたので、1〜2時間くらいで疎通確認まで完了しました。
(ちなみに私はSwiftを始めたばかりですので、Swiftに慣れた方ならもっと早いと思います。)

この記事を読んで、Objective-Cの辛みから皆さまが開放されるきっかけになれば幸いです。


12
  • IT酒場放浪記 記事一覧
  • エンジニア募集中!