SwiftでiOSアプリ作って公開してみた 2 - 要望・要求
アプリを作る際、どんなものにしようかとあれこれと考える時間はとても素敵なものです。
風呂に入りながら技術の枠をこえて発想する時間はとても短く、まさに不撓不屈の意思、決意のもとに風呂上がりの豆乳を体に流し込むわけです。
しかし安心してください。いずれは風呂で発想した宇宙のようなアイデアも、現実というふるいにかけられ仕様に落とし込まれるのです。そして寝食を忘れた開発者としての本当の戦いが始まるのです。想いを最後まで信じ抜いて1つのプロダクトをリリースさせること、これが1番難しいことだと自分が思うのは、人が誰しも誘惑に流されやすく長時間イスに座り続けることを嫌うからです。
リリースしたからといって何が変わるか分からない、そんな不安のなかで製造にあたるのが夢追い個人プログラマのストイックさであり、またアーティストな部分だと思うのです。
要望とは
プロダクトは問題解決のために作られるべきです。
業務が効率化されること、暇をつぶせること、なんでもいいのですが自分の要望を細分化して収集しきることが重要です。これはSEのスキルセットでも非常に需要な部分だと思うのですが、顧客の要望をもれなく拾い上げるSEはプロジェクトを円滑に進めます。なぜなら、出来る・出来ないが最初にすり合わされドキュメントとして残るからです。出来る・出来ないが分からない潜在的なニーズを顧客が要件検証まで持ち続けたプロジェクトに成功はあるのでしょうか。自分が何を作りたいのか、何をやりたいのかがイマイチ理解出来ていない場合、整理できていない場合はプロジェクトを前に進めるべきではありません。技術的な課題を考慮せず、自分自身としっかり対話し要望をメモしておくのです。
要求とは
要望は現実というふるいにかけられ具体的な要求へと変貌を遂げます。
その要望が技術的に実現可能か、妥当か、問題解決に紐づくか、あらゆる観点からつっつき倒していくのです。時には、代案を提示し自分自身と折り合いをつけていく。やることとやらないことをしっかり切り分けていきます。最初から要求が大きすぎるのも考えものなので、適度に要求をまとめあげ、フェーズ分けを行うのも1つの方法です。くどいようですが、プロダクトとは、問題解決ができなければ、はたまたリリースされなければ社会的にはゴミくず同然なのです。
まとめ
多少哲学的な部分ですが、チームで開発するのであれ、個人で開発するのであれ要望・要求の扱いは変わりません。顧客に対して行うか、自分に対して行うかのベクトルが違うだけ。開発において個人的には最も重要なフェーズと考えており、プロジェクト全体の進行に大きく関わるところなのです。慎重に、時に大胆に要求をまとめあげることができれば、開発のフェーズでは何より自分が楽できます。しっかり時間を割きましょうという提案です。
PHPerがSwiftでiOSアプリ作って公開してみた 1 - はじめに
SwiftがOSS化されて、Githubでの開発も盛り上がってますね!
今回申請したアプリはこんなのです。
Webをスクラップしようという考えで作った、ソーシャルブックマークアプリです。
アプリ内からブラウジングして気になる記事をスクラップブックにスクラップすることができます。ユーザーは、他のSclap利用ユーザーのスクラップブックをフォローできるので、ソーシャルな機能も含んでいます。
スクリーンショットです!
参考アプリは、Tumblr、Pintarest、はてなブックマークです。
初めてアプリをリリースしたので、まずは模倣からですが少しづついいとこ取りをして機能する段階でバージョン1.0をリリースさせていただきました。
私はどんな人間か
大学まで野球一筋、元音楽作家・アーティスト、元IT企業のWebプログラマ。グミおいしい。現在再就職活動中の27歳。こんな人間です。
音楽作家としてのリリースの一部
アプリを作った経緯
アプリを作るのは僕の3年前からの目標でした。
いい歳した男が、少年のような思いに従ったというのが経緯になります。今回のリリースも、音楽で言うなら、初めてMPCで組んだシーケンスを友達に聞いてもらうような感覚です。自分が作った作品を世の中に出す瞬間は何にせよワクワクするものです。またそれとは逆に、怖くてたまらない時もあります。自分が作ったものに対して評価を受けること。逆に全く見向きもされないこと。多分これは自分が音楽をやっていた時と一緒な感覚だったりします。
ですが、最後まで作りきること、世に出すことで知れることは計り知れないと思うのです。それが現実であれ、可能性であれ、自分の実力であれ、一歩前に進めたと解釈できることであれば、それは誰がなんと言おうと自分にとってやってみる価値があることだと思ったりするのです。
今後のブログ更新に関して
自分がつまずいたところや反省点を軸に技術的な部分にも触れつつ、数回にわたって「PHPerがSwiftでiOSアプリ作って公開した話」の連載をしていきたいと思います。
僕が記事を書く理由は、自身の開発の振り返りが9割、同じように手探りでアプリを作っている方がスムーズに開発できる助けに少しでもなればという自己満足のような思いが1割です。
ここはこうした方がスマートだなとかアドバイスがありましたら、お手数ですがご指導ご鞭撻よろしく御願いいたします。独学のレベルを抜け出す助けをしてくださる方に自分は最大の感謝をおくらせていただきます。
またこのシリーズは、以下の連載に大きな影響を受けています。開発時にも非常に助けられたことから、リスペクトの意味を込めてリンクを掲載させていただきます。
JavaScriptプログラマがSwift iOSアプリを2週間で作って公開してみた〜その1 Overview〜 | TEJI TECH BLOG
2016年始まって、めっちゃかっこいいってなった5曲
このコーナーは、2016年1, 2月にクラウドにアップロードされた楽曲から気になったものとりあえず貼り付けようというものである。
めっちゃかっこいい!
Swiftのlazyの使い所
このコーナーは、iOSアプリ開発でなあなあにしてた部分について調べて文章にすることで理解を深めようというものです。
今回は、Swiftのlazyの使い所について。
そもそもlazyって何?
遅延初期化(lazy initialization)をサポートするのがSwiftにおけるlazyであり、
lazyで初期化されたプロパティを遅延格納型プロパティ(lazy Stored property)と呼びます。
遅延格納型プロパティの動きを簡単にいうと、飲み会に「行けたら行く」って言ってるAさんの分のビール何本必要かな、いやAさんが来たら買えばいいでしょ。みたいな感じ。
- 必要とされたときに値を初めて決定する
- クラスと構造体で使用可能
- 定数ではなく変数として定義する
- プロパティオブザーバが使用できない
これさえ押さえておけばlazyを適切に使えそう。
lazyの使い所
今回の結論にあたります。主な使い所はこの2点。
- オブジェクトの初期化に合わせてプロパティの初期値を決定したいとき
- コストの高い処理を含んだオブジェクトの初期化を制限したいとき
オブジェクトの初期化に合わせてプロパティの初期値を決定したいとき
import Foundation class Product { var name: String var category: String // 遅延格納型プロパティの定義 lazy var secondhandName: String = { [unowned self] in return "中古の\(self.name)" }() lazy var latestName: String = self.getLatestName() init(name: String, category: String) { self.name = name self.category = category } func getLatestName() -> String { return "最新の\(self.name)!" } } let product: Product = Product(name: "フライパン", category: "調理器具") print("product.name", product.name) // フライパン print("product.secondhandName", product.secondhandName) // 中古のフライパン print("product.latestName", product.latestName) // 最新のフライパン
コストの高い処理を含んだオブジェクトの初期化を制限したいとき
import Foundation class Person { var name: String // 遅延格納型プロパティの定義 lazy var calculator = Calculator() init(name: String) { self.name = name print("Personオブジェクトが初期化されたよ") } func calculateFate() { self.calculator.doSomething() } } // コストの高いクラス class Calculator { init() { print("Calculatorオブジェクトが初期化されたよ") } func doSomething() { // 省略 } } let person: Person = Person(name: "Otowa") // Personオブジェクトが初期化されたよ person.calculateFate() // Calculatorオブジェクトが初期化されたよ(Calculatorのオブジェクトが必要になったタイミングで初期化される)
こういうのがさくっと書けるのSwiftの素敵なとこだと思います。
2015年に素敵ってなった10曲
このコーナーは多少上から目線で、2015年にクラウドにアップロードされた楽曲を紹介し、気持ち程度のコメントを加えるというものである。
一曲に物語がある。気がする。短いのに最後まで聞くと満足感すごい。
空気感が絶妙。シリアスにふれ過ぎない感じの運び方が素敵。
「かわいい」の解釈が素敵だと思った曲。単発サンプルの使い方がセンスに溢れてる。
めっちゃソウルフル。よれ感。メインストリームぽさも出せてる。脱帽。最高。
おれは好きだけど、全く話題にならず涙目になった一曲。
Au5はただの天才。
グリッチホップにファンクの良さを完全に落とし込むことに成功してる一曲。
34秒あたりビルドアップからのそうくるー!?って感じ素敵。
フックのメロに完全に持ってかれた一曲。
いい意味で頭おかしい。キャッチーにまとまってるのも素敵。
日本のトラックメイカーしかり、音楽作家はどんな曲をインプットしてるのだろう。もしかっこいい曲知ってたら気が向いたら教えてください。
武井壮すごいってなったビデオ
これは百獣の王だわ。
nginx + unicorn + rails 画像転送時にPermission denied
◼︎解決方法
- /var/lib/nginx/tmpの所有者変更をする。
- client_body_temp_pathというオプションをnginx.confに追記する。
◼︎起こった問題
nginx + unicorn + rails の環境構成。S3への画像転送がうまくいかない。nginxのerror.logに以下のログが吐かれている。どうやらパーミッションエラーのようだ。
2015/11/01 12:00:00 [crit] 9397#0: *1 open() "/var/lib/nginx/tmp/client_body/0000000001" failed (13: Permission denied), client: 153.***.**.***, server: api.com, request: "PUT /v1/users/23/profile HTTP/1.1", host: "api.com"
/var/lib/nginx/tmpの所有者変更をする。
chown nginx /var/lib/nginx/tmp
これで解決。
しかし、以下のケースもありえる。
/var/lib/nginx/tmpの所有者は、nginx.confのuseオプションで指定した所有者にnginx起動時に毎回書き換えを行なってるくさい。useオプションを書き換えてる場合は注意。
useを変更できない場合は、client_body_temp_pathというオプションをnginx.confに指定すればいいかも。
client_body_temp_path /var/tmp/nginx;