Entertainer Engineering

人を楽しませられる技術者を目指すあおかびんのブログ

ハッカーズチャンプルー2018を運営した話

みなさんご無沙汰です、aokabinです。 Twitterではかびさん@d_ishitakaでやらせてもらっています。

日付が変わって昨日はハッカーズチャンプルー2018の開催がありました! 結論から言うと、とんでもなく楽しい1日でした!!

と言うわけで、ハッカーズチャンプルーの運営をした話をしたいと思います。

ハカチャン2017の時の話

ハッカーズチャンプルー自体の存在は知っていたのですが、 2015年、2016年と都合がつかず参加できずにいて、初めて2017年にボランティアとして参加しました。

昨年度のハッカーズチャンプルーは合宿があったり同級生とisuconで競ったりした後 カンファレンスの部でじゃんけんでグーを出し続けてサーバーレスアーキテクチャの本をもらったり 懇親会で面白い話をたくさん聞いたりして非常に楽しかったのを覚えています。

そんなこんなでハッカーズチャンプルー、いいイベントだなぁと思いつつその日を終えていたのですが、 イベントお疲れ会で意外な話を聞くことになりました。

ハッカーズチャンプルー、2017年が最後説

実はハッカーズチャンプルーは昨年で5回目を迎えていたのですが、 メインで運営していたメンバーの都合がつかず、開催できないかもしれないと言う危機に立っていました。

僕はそのことを全く知らず、ただただいいイベントに参加させてもらってありがたいなと言う気持ちだったのですが とても衝撃を受けました。 「こんなにいいイベントが今年で終わる」とは信じられなかったのを覚えています。

でもやはり僕としても「せっかくこんなにいいイベントなので、2018年はなんとかして継続したい!」という気持ちがあったので 今回から学生が継続して運営メンバーに携わっていくという計画を(一応)立てて 2018年度のハッカーズチャンプルーの副実行委員長に名乗りを上げました。 結果今年も開催できてとても良かったです。

運営になってやったこと

僕が運営チームに入ってからやったことはざっと以下のような感じ

  • スポンサーの募集
  • スピーカーの招致
  • 学生の参加枠を増やす
  • 前夜祭のMC
  • 指笛

スポンサーの募集

とにかくイベントを運営するには最初はスポンサー集めが重要だと思っていた僕は 僕のつながりとトポセシアの寺地さん@GGtera2014からの紹介を元に スポンサーの募集をさせて頂きました。

募集の結果、全体で過去最多の14社の協賛を頂き、 無事、お昼ご飯無料、ノベルティ配布、さらには懇親会費用を学生無料+社会人も千円で提供できるまでになりました。 スポンサー各社には本当に感謝の気持ちでいっぱいです!本当にありがとうございました!!

hackers-champloo.org

スピーカーの招致

今回のスピーカーの方々は錚々たる面々で、東京でもなかなかお目にかかれないような方々ばかりでした。 というのも、これは完全に運営に携わった福利厚生になるのですが 「スピーカーの招致は、コアメンバーが好きなように提案できる」というのがハッカーズチャンプルー運営の仕組みなので 今回僕はisucon&Goのトーク枠としてfujiwaraさんを招待させていただくことにしました。

本当にありがたいことにfujiwaraさんは関係者各位に話をしていただき、すぐに登壇を決めていただきました。 登壇OKを頂いた時は本当に感無量でした、そしてご登壇、本当にありがとうございました!! (めっちゃ幸せでした)

改めまして今回ご登壇いただいた 赤塚さん、あやぴーさん、fujiwaraさん、motemenさん、常名さん、本当にありがとうございました!!! また機会があったら是非、よろしくお願いいたします!!!

学生の参加枠を増やす

これはちょっと意図してやったところで、実際ここまでうまくいくとは思っていなかったのですが 実は今回学生の参加枠を増やすために1つだけ工夫したことがあります。

現在僕は琉球大学に通っているのですが、琉球大学情報工学科では、周りの人に聞くと意外とWeb系に興味がある人が少ない。 分析系に寄っている人の方が多い。また新入生にはWebも分析もあまり刺さらない。 ということが個人的な課題設定としてあって、その壁を超えて情報工学科(知能情報コース)の学生に参加してもらうために 今まではWebやインフラに寄っていた登壇枠に、さらに「ゲーム系」の枠を入れてみることにしました。

そこで、IGDA RyukyusのKooくんに声をかけ、ゲーム系に興味のある学生にも声をかけてもらうようにし Kopくんが呼びたい登壇者の方も呼んでもらうことしました。 結果常名さんに来てもらうことになり、VTuberのお話をしていただき 目論見が当たっていたかどうかはわかりませんが、例年より学生参加が増えた気がします! やっぱりゲーム系は学生の気持ちを惹くには強い気がしますね! IGDA RyukyusのKooくんと安田くん、そしてUnityの常名さん、本当にありがとうございました!!

前夜祭のMC

今年のハッカーズチャンプルーには前夜祭もありまして、スピーカーやマイクの用意はしていたのですが 当日になって「そういえばMCとかのことは考えてなかった」ということに気づき、急遽マイクを持ってMCをしました。

とはいえ、乾杯を3回やったり、LTの案内をする程度でしたが。。。

この前夜祭、嬉しい誤算が1つありまして、これは今後のイベント開催でも参考になるんじゃないかなと思うのですが 元々LTをやろうという話をしていたのですが、会場の都合上プロジェクターを入れることがどうしても難しい状況で それならスライドなしLT、つまりTED Talk形式(TEDも本当はスライドあるんですが...)にしてLTをやろうという話になっていました。 事前の応募では2件しか応募がなかったので、ゆるっとやろうという感じだったのですが とりあえず飛び入りもどうぞという感じにすると、意外にもバンバンLT登壇者が出てくれて 結果として8人くらいがLTをするという非常に意義のある会になったのは、とても良かったなぁと思います。

一番面白かったのは黒曜さんが技術書展で「本を出した方がいい」という前振りの時に質問した 「じゃあ本を書いたことがあるよ、という方どれくらいいらっしゃいますか?」の質問に会場の半分が手を挙げた時でしたww

指笛

こちらも嬉しい誤算。 カンファレンスのLTの部で、いつもは時間切れの合図でドラを鳴らすようにしているのですが、 今回はドラがないという状況だったので、代わりに大きい音が出るということで指笛で時間切の合図をすることにしました。

意外にもこれが功を奏し、最初こそ 「無慈悲の指笛」とか「スポンサーセッションの途中で鳴り響く指笛」とか言われていたものの 後半になってくると 「指笛を期待してしまう」とか「指笛で終わるのいいな」とか評価を貰えるようになって 結果指笛芸人を襲名できて良かったなと思います。

様々なカンファレンスの際にドラではなく指笛芸人の僕@d_ishitakaの起用を是非検討して頂ければと思います。 buildersconも行こうと思っているので、何処かのタイミングで一度でもドラ役出来ないかなー?←

とまぁそんな感じで

運営とはいえ、ハッカーズチャンプルーがゆるさを赦しているイベントなので、僕としてはめちゃくちゃ大変だったことはそこまでなくて でもそれは他のcoreスタッフの方、ボランティアスタッフの方が一生懸命動いていてくれたからだと心から感謝しています。 LTはちょっとあったまってくれたし、良かったと言ってもらえたし あ、LTでは税金の話をしました、良かったら見てね。

反省すること

もちろん、イベントを運営していて、反省すべきところもたくさんあったなという気持ちで居ます。 次から同じ過ちをしないようにしなきゃという気持ちで反省点を書いて行きます。

スポンサー対応

完全に僕個人的な反省点なのですが、初めてだったのでスポンサーの方々に個別に連絡をとったり諸々手続きをお願いするのに手間取りました。 しかも、今回スポンサーブースがあったのにも関わらず、うまく誘導ができず、ブースがグダグダになってしまったのは本当に反省点だと思います。 次回からはちゃんと席を決めてそれぞれのブースを用意し、ちゃんと配布物を配布できる環境を整えるところまで考えるようにしたいと思います。 また、スポンサーの方に参加申し込みの案内をして居なかったのもだいぶミスです、結果うまくまとまったので良かったですが、次回以降はちゃんと生かしたいと思います。 ご迷惑をおかけして申し訳ありませんでした。。。

Twitterハッシュタグのstreaming

今回は流ツイというサービスを使って左前のスクリーンにTwitterハッシュタグ情報を流して居たのですが 残念なことに変なbotやRTがやたら流れてくるということもあり、あまりうまく動作させれませんでした。 ないよりはめちゃくちゃ良かったと思うのですが、わがままをいうとbotやRTは表示させないような仕組みができるといいなぁと思いました。

まとめ

本当は書きたいこともっといっぱいあるのですが、 反省点も色々とあるものの、前夜祭、カンファレンス、懇親会(、二次会)とすごくいい流れにできてとても良かったと思います!

今回僕が運営をしていてすごくいいなぁと思ったことは 「主導権を持つということは素晴らしいことである」ということです。 好きなゲストスピーカーを呼び、好きなことを喋り、好きなように場を動かす。 主導権、裁量が与えられている現場ってこんなに楽しんだと、こんなに充実感があるものなのだと改めて実感するとてもいい機会になりました! 一緒に運営をやっていただいた西島さん、富田さん、そしてcoreスタッフの皆さん、当日スタッフの皆さん、本当にありがとうございました。 今回のイベントは本当、感謝してもしきれないくらい楽しく充実した会でした。 また来年もやりましょう!読んでいただきありがとうございました!!

P.S. Go言語の勉強会を開くので良かったらみんな来てくださいね!! okinawa-go.doorkeeper.jp

Macの無線LANが壊れたので、無線LANのUSBアダプタを買ったら爆死しそうになった話

お久しぶりです、aokabinです。かびさんです。

全然更新してなくて、久々の更新内容があんまり技術系じゃないのですが
結構困っていたことが解決されたのでメモしておきます。

東京出張中に無線に繋がらなくなった

先週東京に出張していたのですが、
ある日PCを開くとネットの調子が悪く、全然インターネットに接続できませんでした。

一旦再起動すると、メニューバーの中にあるWi-Fiの状態が
ONでもOFFでもなく、X(バツ)になっていることに気づきました。
状態としては、「Wi-Fi: ハードウェアなし」との表記...

NYに行く予定もあるので、このままではまずい、と
慣れないながらもヨドバシカメラに行って無線LANのUSBアダプタを購入してきました。

こちら、WDC-150SU2MBK

ヨドバシカメラで購入した時点では、【OSX10.10対応】と書いてあったので
多分いけるかな、と思って購入したのですが、アクシデント

El CapitanOSX 10.11!

しくじりました...El CapitanOSX 10.11で、対応していなかったのです。

ドライバのインストール手順通りに対応してもうまくいかず撃沈...

と思っていた矢先、学校にこのタイプの子機があったことを思い出しました。

PLANEXの無線LANアダプタは、OSX10.11に対応しているとのことで(なんならmacOS 10.12 Sierraも対応)
学校に戻ってからこの無線LANアダプタのドライバをインストールすることに

ダウンロード|GW-USNANO2A|プラネックス

奇跡!ELECOMが動き出す

すると、微動だにしなかったELECOMが動き始めました!
どうやら、中のハードが共通のものらしく、PLANEXがOSX 10.11対応版を出しており
そのドライバをインストールしたことによって共通のAPIを持つELECOMの方のアダプタも動作し始めたようです。

いやー、これで一件落着、安心してNYいけます。(速度はとても速いわけじゃないですが)

来年は新しくMacを新調する予定なので、その繋ぎとして購入したアダプタが動いてよかった。
価格もそんなに高くないので、買ってみたけど動かないよって人は試してみるといいかもしれません。

以上、あおかびんでした!

初心者向けiPhoneアプリ作り入門&ハンズオンを実施した話

こんにちは、お久しぶりです、かびさんことあおかびんです。

しばらく更新していない間に月間PVが1000を超えたので密かに喜んでいる次第です。

さて、今回は琉Techの第一回イベントとして

初心者向けにiPhoneアプリ作りのためのSwiftの勉強会を開催したので

そのイベントレポートをつらつらと書いていきたいと思います。

ryutech.doorkeeper.jp

開催前

開催する前に、Swiftの勉強会用の資料をつくりました。
Swift勉強会.pdf - Google ドライブ

だいたい150枚超くらいの(個人的には)大作です!

製作には大体30時間くらいかかったんじゃないかなー?


資料の作り方ですが、最初にまずザッと勉強会の流れを書いて、

そこでもっと詰めた方がいい内容をちょくちょく入れて

その後、マスタースライドの編集を行いました。


マスタースライドを編集した後は結構レイアウト崩れていたので

流れを書くときはデフォルトのフォーマットから崩さないことをオススメします。。。


このスライドの内容で、13:30〜18:00で終わらなかったので

もう少し削るか、時間を延ばした方が良かったかなーとか思ってます。

次回に活かしたいですね。


このスライドを作った時点で結構満足してしまった節があり

内容のところはもう少し詰めるべきだったんじゃないかと思っています。申し訳ない。。。

次回に活かしたいことをまとめると

  • デフォルトフォーマットを崩さずに内容を書く
  • 4時間半で、大体スライド120枚くらい

開催中

人の入りは結構まばらで、開催後に入ってくる人が多かったけど

スライドを事前に公開していたので、追いつける人はすぐに追いつけた印象

入り時間とスタート時間を別で記した方がいいんだろなと思った


鍵の解鍵をお願いするのを忘れていました、、、追記します。


会場は終始和やかな雰囲気にしたかったのですが

会話も質問も少なかったので、もう少し工夫したかったですね

途中から音楽を探して入れたので、そこからは少しマシになったかも

無音での雰囲気だと声を出すのがはばかられますからね


詰まっているんだけど、質問していいのか?という雰囲気があり

「今エラー直してます」というのがよくあった気がしてて

本当はそれも質問としてしていいんだけど

多分講師が一人だから、そのリソース取るとストップしちゃうのが

嫌だったんじゃないかなと思っていたりします。

質問に対応できる人が別でいると、ちょっとは気軽なのかな?


あと途中から追いつけなくなった人もいたようで

そのあたりへの配慮が足りなかったなぁと痛感

初心者に優しい勉強会にするのはまた難しいものがありますねぇ。。。

スキルマップ的なものを作って公開できるサイトとかあったら

それをリンクして、「これくらいの人向け!」とかも言いやすいのですが、なんかありませんか?

いや、タイトルに「Swift初心者向け」とかってつければいいのかな、、、

「プログラミング初心者向け」とかと区別するためのね

開催後

アンケートの評価を見てみた感じ、そんなに悪くはありませんでした。(平均4.1875)

f:id:aokabin:20160228171222p:plain

ただ、評価が2や3のものもあったので、

ターゲットをちゃんと明確にしたり(どのレベル層)

メンターを数名用意するなどのサポートをすべきだったなと反省


わかりにくい&もっとしりたいことには色々と意見がありましたが

f:id:aokabin:20160228171730p:plain

  1. とにかく何か別の詳しいところまでもっと知りたい
  2. スライドの作業と手元の作業との整合がとりたい
  3. 専門用語

詳しいことをもっとしりたいという要望に関しては

また新たにもっと詳しいSwift勉強会を開催することで対応しようと思います

スライドの作業と手元の作業との整合に関しては

実際に目の前で書いて動かす作業を見せたり

スライドは事前に数部印刷しておいて、いつでも確認できる状態にすることで対応しようと思います


専門用語やわかりづらい表現に関しては

そういったものをすっ飛ばして解説できればいいのですが

そういった人向けのスライドも準備することで対応できればいい!

(のですがなかなか労働コストがかかりますよね...笑、難しい...)


他に行きたい勉強会については

f:id:aokabin:20160228173020p:plain

が特筆して見られました。

Pythonは個人的にも好きなので、こちらは必ずやりたいと思います。

より専門性の深いところは、初心者向けではないのですが

中上級者向けとして開催する余地は非常に高いですので

僕が開催するかはおいといて必ずやっておきたいですよね!

有名なフレームワーク(TensorFlow)を使うくらいだったら勉強会でも収まりますし

体験するところから入ってもありかもしれませんね

総論

勉強会を開催するのは以外と疲れますが

やってみると結構楽しいですし、知識を一気に共有できるという意味では

確実にやってみる価値は高いなと思いました

ただ、やはり講義からすこし外れる方が、お互いの時間を有意義に使えるかもしれないので

次からは、手を動かす作業をもっと多くもっておきたいですね

次回に生かすこと

  • スライド作りでは、フォーマットを崩さずに書くことで修正しやすい
  • 4時間半でスライド120枚くらいの進み具合
  • イベントの入り時間とスタート時間は別記すべき!
  • 鍵の解鍵もお願いすることを忘れないこと
  • イベント中は音楽を流しておくと、ちょっと雰囲気良くなります
  • 質問に対応できるメンターを用意しましょう
  • 対象とするターゲットはちゃんと明確にしましょう
  • ハンズオンでは、目の前で実際に書いて動かす作業を見せる
  • スライドは事前に印刷しておくと、ちょっとはスムーズになりそう
  • フレームワーク体験会とかやってもいいかもね


非常に大変でしたが、非常に有意義な体験でした。

次回開催時には上記のことに気をつけて頑張っていきたいと思います!

以上、あおかびんでした!

Swiftでカメラロールから写真データを保存する話

おはようございます。あおかび (ん)です。

この間やっとアプリケーション作りがひと段落したので、
その間に学んだことをずらずらっと書いていこうと思っております。

今回はSwiftを使ってカメラロールから写真データを引っ張ってくる方法を書いていきたいと思います。

ボタンを一つ置いて、そのボタンがクリックされたらカメラロールにアクセス、
その画像をローカルデータとして保存しておくところまでやっておきたいと思います。
DBの部分は今回は割愛します。


1.ボタンを配置して、カメラロールにアクセス
ViewController.swiftにまず、AssetsLibraryをimportした後、
UIViewControllerに加えてUIImagePickerControllerDelegateとUINavigationControllerDelegateを継承(?)しましょう。

/* ViewController.swift */
import UIKit
import AssetsLibrary

class testViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

つづいてviewDidLoadメソッドにてボタンを配置、アクションは今回はaccessCamerarollとしました。

    override func viewDidLoad() {
        self.view.backgroundColor = UIColor.whiteColor()
        super.viewDidLoad()
        
        let button: UIButton = UIButton()
        button.frame = CGRectMake(100, 100, 100, 100)
        button.setTitle("Access!", forState: UIControlState.Normal)
        button.backgroundColor = UIColor.blueColor()
        button.addTarget(self, action: Selector("accessCameraroll:"), forControlEvents: UIControlEvents.TouchUpInside)
        self.view.addSubview(button)
    }

そのaccessCamerarollメソッドは次のようになっています。

    // カメラロールから写真を選ぶためのメソッド
    func accessCameraroll(button: UIButton) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
            let controller = UIImagePickerController()
            controller.delegate = self
            controller.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
            self.presentViewController(controller, animated: true, completion: nil)
        }
    }

ここまででとりあえずカメラロールにアクセスすることはできました!
次はカメラロールから選択した写真を保存しましょう。

2.選択した写真をローカルストレージに保存
写真を選択した時に呼ばれるメソッド

    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
    }

というメソッドがあります。この関数内で、選択した画像を保存していきましょう。

    // 写真を選択した時に呼ばれるメソッド
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
        if info[UIImagePickerControllerOriginalImage] != nil {
            let image: UIImage? = info[UIImagePickerControllerOriginalImage] as! UIImage?
            let pictURL: NSURL = info[UIImagePickerControllerReferenceURL] as! NSURL
            var library: ALAssetsLibrary = ALAssetsLibrary()
            var data: NSData?
            
            let sema: dispatch_semaphore_t = dispatch_semaphore_create(0)
            let queue: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
            
            var getImage: UIImage?
            
            dispatch_async(queue, {() -> Void in
                library.assetForURL(pictURL, resultBlock: {(asset: ALAsset!) -> Void in
                    let representation: ALAssetRepresentation? = asset.defaultRepresentation()
                    getImage = UIImage(CGImage: representation!.fullResolutionImage().takeUnretainedValue())!
                    data = UIImagePNGRepresentation(getImage!)
                    dispatch_semaphore_signal(sema)
                    }, failureBlock: {(error: NSError!) -> Void in
                        println(error)
                        dispatch_semaphore_signal(sema);
                })
            })
            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
            
            saveImage(data!)
        }
        picker.dismissViewControllerAnimated(true, completion: nil)
        let mainViewController: MainViewController = MainViewController()
        self.navigationController?.pushViewController(mainViewController, animated: true)
    }

    // 画像をローカルストレージに保存するメソッド
    func saveImage(data: NSData) {
        let dataPath = (NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as! Array<String>).first!.stringByAppendingPathComponent("test.jpg")
        var fileManager: NSFileManager = NSFileManager()
        data.writeToFile(dataPath, atomically: true)
    }

これで画像が保存されたはずです。

最初はAVFoundationとか使ってカメラにアクセスしたりしてたんですが、なんかうまくいかなかったですね...

コーディング能力、プログラミング能力の両方がこのままではやばい気がするよなー
勉強頑張っていきます。ありがとうございました、かびでした。。。


P.S.

コードの全容

import UIKit
import AssetsLibrary

class testViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    override func viewDidLoad() {
        self.view.backgroundColor = UIColor.whiteColor()
        super.viewDidLoad()
        
        let button: UIButton = UIButton()
        button.frame = CGRectMake(100, 100, 100, 100)
        button.setTitle("Access!", forState: UIControlState.Normal)
        button.backgroundColor = UIColor.blueColor()
        button.addTarget(self, action: Selector("accessCameraroll:"), forControlEvents: UIControlEvents.TouchUpInside)
        self.view.addSubview(button)
        
    }
    
    // カメラロールから写真を選ぶためのメソッド
    func accessCameraroll(button: UIButton) {
        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.PhotoLibrary) {
            let controller = UIImagePickerController()
            controller.delegate = self
            controller.sourceType = UIImagePickerControllerSourceType.PhotoLibrary
            self.presentViewController(controller, animated: true, completion: nil)
        }
    }
    
    // 写真を選択した時に呼ばれるメソッド
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
        if info[UIImagePickerControllerOriginalImage] != nil {
            let image: UIImage? = info[UIImagePickerControllerOriginalImage] as! UIImage?
            let pictURL: NSURL = info[UIImagePickerControllerReferenceURL] as! NSURL
            var library: ALAssetsLibrary = ALAssetsLibrary()
            var data: NSData?
            
            let sema: dispatch_semaphore_t = dispatch_semaphore_create(0)
            let queue: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
            
            var getImage: UIImage?
            
            dispatch_async(queue, {() -> Void in
                library.assetForURL(pictURL, resultBlock: {(asset: ALAsset!) -> Void in
                    let representation: ALAssetRepresentation? = asset.defaultRepresentation()
                    getImage = UIImage(CGImage: representation!.fullResolutionImage().takeUnretainedValue())!
                    data = UIImagePNGRepresentation(getImage!)
                    dispatch_semaphore_signal(sema)
                    }, failureBlock: {(error: NSError!) -> Void in
                        println(error)
                        dispatch_semaphore_signal(sema);
                })
            })
            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
            
            saveImage(data!)
        }
        picker.dismissViewControllerAnimated(true, completion: nil)
        let mainViewController: MainViewController = MainViewController()
        self.navigationController?.pushViewController(mainViewController, animated: true)
    }
    
    // 画像をローカルストレージに保存するメソッド
    func saveImage(data: NSData) {
        let dataPath = (NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as! Array<String>).first!.stringByAppendingPathComponent("test.jpg")
        var fileManager: NSFileManager = NSFileManager()
        data.writeToFile(dataPath, atomically: true)
    }
    

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

Swiftで NavigationBarを出したり引っ込めたりする話

こんばんは、かびさん@あおかびんです。

21日間ブログを書くというチャレンジに失敗しまくっている次第ですが
また気をとりなおしていきたいと思います。

さて、NavigationBarで前の画面に戻れる機能は便利なのですが
場合によっては表示させたくないということがあるかと思います。

そこで出したり引っ込めたりする方法を書いていきたいと思います。

流れは

  1. 画面遷移はNavigationControllerに任せる
  2. 画面を描画する前にNavigationBarの設定をする

こんな感じになるかと思います。

実際に書いてみましょう。

1.AppDelegate.swift

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // 最初に表示する画面を指定する
        let firstView: MainViewController = MainViewController()
        // NavigationControllerを設定する
        let myNavigationController: UINavigationController = UINavigationController(rootViewController: firstView)
        
        // おまじない
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        self.window?.rootViewController = myNavigationController
        self.window?.makeKeyAndVisible()
        return true
    }
    ・・・
}

最初に表示する画面からNavigationControllerを設定する感じですね。
次はMainViewControllerを設定します。

2. MainViewController.swift (NavigationBarを表示しない)

class MainViewController: UIViewController {
    …
    // ボタンが押された時の処理
    func touchButton(sender: UIButton){
        let subViewController: SubViewController = SubViewController()
        self.navigationController?.pushViewController(subViewController, animated: true)
    }
    // 画面をロードする前に呼ばれるメソッド
    override func viewWillAppear(animated: Bool) {
        // NavigationBarを隠す処理
        self.navigationController?.setNavigationBarHidden(true, animated: true)
    }
    …
}

これによって画面をロードする時にNavigationBarを表示しない設定をします。
次は、このボタンを押したあとでSubViewControllerの方ではNavigationBarを表示しましょう。

3. SubViewController.swift (NavigationBarを表示する)

class SubViewController: UIViewController {
    ・・・
    override func viewWillAppear(animated: Bool) {
        self.navigationController?.setNavigationBarHidden(false, animated: true)
    }
    ・・・
}

これを追加することによって、<BackのついたNavigationBarを表示できると思います。

こんな感じですかね。

ブログを更新するのを忘れちゃうのは嫌だよな。。。
やっぱ通知つけようかな。。。

以上、あおかびんでした。

SwiftのUIViewController間でデータを受け渡す話

おはようございます、かびさん@あおかびんです。

iPhoneアプリSwiftを使って開発しているのですが
UIViewController間でデータを渡したいときに
AppDelegate.swiftに変数を追加すると渡せるということだったので
その方法を記述したいと思います。

1.AppDelegate.swift

AppDelegate.swiftファイルの中に、値を保持する領域を宣言します。
具体的には、

class AppDelegate: UIResponder, UIApplicationDelegate {
    var message: String?
    ・・・
}

こんな感じですかね。

2.SendViewController.swif (受け渡しView)

値に書き込むためにはAppDelegateクラスの変数を用意して、
その変数のクラス変数(?)を経由して書き込む形になります。

class SendViewController: UIViewController {
    var delegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    ・・・

    // ボタンを押したときの処理
    func touchButton(sender: UIButton){
        // AppDelegateのmessageに押されたボタンのtagを代入
        self.delegate.message = String(sender.tag)
        // NavigationControllerを使ったページの遷移
        let receiveViewController: ReceiveViewController = ReceiveViewController()
        self.navigationController?.pushViewController(receiveViewController, animated: true)
    }
}

こんな感じで記述しました。
(今回NavigationControllerを使っているので、ちょっとややこしいかもしれない)

3.ReceiveViewController.swift (値の受け取りView)

class ReceiveViewController: UIViewController {
    var delegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
    override func viewDidLoad() {
        super.viewDidLoad()
        println(self.delegate.message)

    }
    ・・・
}

2と同じように呼び出しを行って、値を吐き出しています。
多分うまくいくんじゃないかな

ダメだったら連絡ください、修正します。。。

これを知らなかったからViewのinitをoverrideしようと苦戦してた。。。
スキル無さすぎダメダメのダメ。

すみません、以上あおかびんでした。

学校の課題を解くためにHaskellを使った話

こんにちは、かびさん@あおかびんです。

学校の課題で、ちょっとした計算問題を解くときに
普通に解くのが面倒くさいなーと思って
前まではPythonの対話を使って計算をしていたのですが、
この間確率統計のときに
先生「100万の中から1万個取り出す組み合わせはやろうと思ってもできない」
という発言があり(実際にはマクローリン展開かなんか使えばできるみたいな解説のため)
「できそう」と思ってしまったが故にPythonで書こうとしたら案の定計算できない。

また、3の20乗を計算する問題が出て、
計算するのにわざわざコード書くのも面倒だなと。

そこでHaskellを導入してやりました。その手順を書きます。

1. Haskell PlatformのDLとインストール

Download Haskell

こちら、Haskell Platformの公式DLサイトよりHaskell PlatformをDLします。
ちなみに、brewを使わないのは
Haskell関係のパッケージ(?)をインストールするcabalが
brewだとうまく動いてくれないので、こちらのHaskell Platformを使います。

あとはDLしたpkgを開いてインストールしてください。

2.ターミナルでhaskellの対話シェルを起動する。

インストールが終わったら対話形式でhaskellを実行してみましょう。
コマンドライン

ghci

と入力すると、最初の激重initの後haskellインタラクティブシェルが起動します。

閉じるときは

:q

コマンドを入力すれば大丈夫。

(発展)3.100万から1万個を取り出す組み合わせ問題を解かせる。

適当なエディタを使って、test.hsに次のソースコードを書き込んで保存しましょう。

手元にファイルがなかったので、後で追記します。

(発展)4.分数の累乗とかを求めてみる。

haskell先輩は分数も扱うことができます。ありがたいですね!

ghciを起動したら、次のコードを入力してください。

import Data.Ratio

すると、%区切りで分数を扱うことができます。

1 % 3 * 1 % 4 -- 3分の1 × 4分の1
1 % 12 -- 12分の1

また、このまま累乗も計算できる。

((1 % 3) * (1 % 4)) ^ 20 -- (3分の1 × 4分の1)の20乗
1 % 3833759992447475122176 -- おおきなかず分の1

簡単な数式を入れるときはhaskellを使うようになりました。

すごく便利なghciでしたね。
以上、あおかびんでした。