OpenHackDay3に出ております。
残り開発可能時間3時間ほどを残して、ちょっと手が空いたので、
勉強したこととかまとめようかなぁと思います。
作ったもの。
スニャ〜ト家電 neconote
むずかしいし、ややこしいIotのプロダクトから難しさを差し引いいて代わりにカワイさ(猫)をもりもりに盛り込んだプロダクトになります。
どんなものかというと、__スマートでない家電にアプリから操作できるスイッチをつけて、スマート家電化するプロダクト__になります。
今回はハードエンジニアの方と組みまして、僕はアプリケーション側を実装いたしました。
BLEなどハードと連携する部分はKonashiのSDKを使っています。
_人人人人人人人人人人人人人人人人_
> 僕にはよくわかりませんでした <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
僕は主に猫を動かすロジックを作ってました。
_人人人人人人人_
> 猫ロジック <
 ̄Y^Y^Y^Y^Y^Y ̄
学んだこと
SwiftとObjcのライブラリを用いたアプリ実装を複数人やるときの注意
一番問題になったのは、これ
Manifest.lock: No such file or directoryとかPods-resources.sh: No such file or directoryとか出るとき 【Xcode】【Pod】
相方様と少し環境がちがうために生じた?っぽい。ずっとビルドが通らずに困っていた
pod関係のものを一部ignoreしないでpushしていて、
それが問題になったようだ。
3時間ほど無駄な時間を過ごした・・・
結局
- Pods-[project name].xconfigを再読み込み
- Copy Pod Resourceをログに従い修正
したら治った。
マルチスレッド
複数のセルでバラバラに動くアニメーションを実装していて、それぞれが並列で動く必要があった。
enum CatAnimationType{
case walk
case sit
case back
case sleep
}
のようなenumを用意して、
func startAnimation(){
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),{
while (true){
switch (self.status){
case .walk: self.animation(String(format:"fl%d_neco_walk",self.floor), start_ctn: 1, end_ctn: 4)
case .sit: self.animation(String(format:"fl%d_neco_sitdown",self.floor), start_ctn: 1, end_ctn: 2)
case .back: self.animation(String(format:"fl%d_neco_walk",self.floor), start_ctn: 1, end_ctn: 4)
case .sleep: self.animation(String(format:"fl%d_neco_sleep",self.floor), start_ctn: 1, end_ctn: 2)
default :break
}
}
})
}
func animation(prefix:String, start_ctn:Int, end_ctn:Int){
for (var i=start_ctn;i<=end_ctn;i++)
{
var img_name = String(format: "%@%d", prefix, i)
let delay = 0.8 * Double(NSEC_PER_SEC)
dispatch_async(dispatch_get_main_queue(), {
self.catImage.image = UIImage(named: img_name)
// walkなら画像の更新だけでなく座標も動かす
if(self.status == .walk)
{
self.catImage.transform = CGAffineTransformMakeScale(1, 1)
self.toGoal(16.0)
}else if(self.status == .back){
self.catImage.transform = CGAffineTransformMakeScale(-1, 1)
self.toBack(16.0)
}
})
NSThread.sleepForTimeInterval(self.getRandomNumber(Min: 0.5, Max: 0.6))
}
}
上記のようにして、アニメーション処理条件分岐をサブスレッド、描画をメインスレッドにちゃんと分けて並列で動くようにした。コマ送りで特定の連番の画像を特定の感覚で連続描写しつつ、それを複数わけてやるのに手こずりました。
久々にいじったので忘れていた・・・
swiftでのxibファイルでのViewの管理
一画面のシンプルなアプリだが、パーツの再利用性とレイアウトのやりやすさを考慮し
xibファイルをちゃんと使いました。
class func instance(frame:CGRect) -> SwitchBase {
var view:SwitchBase = UINib(nibName: "SwitchBase", bundle: nil).instantiateWithOwner(self, options: nil)[0] as SwitchBase
return view
}
ほんとはxib名の部分もクラス名からとってやれば楽だったのになぁと思いつつ、
静的に書いてました・・・どう書くんだったか・・・
猫の鳴き声出力 (音声の簡単な出力方)
let soundURL = NSBundle.mainBundle().URLForResource(String(format:"cat%d",self.floor), withExtension: "mp3")
var mySound: SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundURL, &mySound)
AudioServicesPlaySystemSound(mySound)
これを使うのが早いし楽だった。
ほんとは音声管理用のマネージャクラスをシングルトンかなんかで実装しておいて
音量や足などを調整できるとよかった
まとめ
反省点が非常に多い実装だ。
-
デザインナーとのコミュニケーション不足
修正の更新をこちらでフックできなかったり、 パーツとしてもらうべき部分と
デザインとしてもらう部分の切り分けで一部齟齬が生じた。
少しの時間の初期コストを払ってもgitで管理してもらえればよかった。
今回はDropboxで適宜共有していたが、素材と進捗ともろもろ全部githubで共有できていると楽だなぁと思った。 -
設計
これはハッカソンに出るたびに毎回思い、毎回ちょっとよくなり、それでも問題点を見つけつづける。
特に今回に限っては1画面ではあるが、パーツごとに初期位置やアニメーションのロジックがちがい、
ハードコーディングが必要になった。
ここらへんが非常にいけてないので、Jsonかなにかで全部定義しておいて
見通しのいいコードにしとけばよかった。 -
BLEの知識
純粋に知らない部分多いので勉強しなkレバ
うまくいった点
-
開発の分業
インターフェースと、コントローラの実装は完全に分離した。
コントローラ部分はswiftで、BLE扱うライブラリ部分はObcでコンフリクトで問題が起きたり、ライブラリの呼び出しで難読な部分があったりがなくてよかった。
ライブラリ側がobjcだったのでheaderファイルがあり、使いやすかった!
ほんとに助かった! -
時間配分
事前の詳細な仕様の共有と、デザイナーさんの迅速な行動で
大きく時間を残して実装が完了した。
ハードで必要なテストに多く時間をつ方のがよかった。 -
会場の雰囲気
開発をするにあたり誰もが必死で、いいものを楽しく作っている。
これにつきると思う。
24時間開発し続けたけど、いやな疲労感は全然ない!!
まとめ
イベントとしては最高でした。チームも優秀で優しい方しかいなかったのですが、
個人的に上記に挙げたようなことや、考え方とかこだわりぬいているかというトコロで
反省点が多い。
勉強になった部分があればぜひぜひ投票をば
投票ページ