2015/08/17

フリーランスとして活動し始めて(2015年2月〜)、半年が経ちました

フリーランスとして活動し始めて(2015年2月〜)、半年が経ちました。
以前、三ヶ月経過後の記事を書きましたが、今回も制作実績を残しておきます。前回の記事はこちら
中には秘密保持契約のためサービス名など明記していないものもあります。

8月

  • iOS新規案件、追加機能対応(UIの挙動変更、アニメーションなど)(Swift,Realm
  • Campus Voice追加機能(Swift)
  • iPadエンタープライズアプリ(新規、Swift)

7月

  • iOS新規案件、追加機能対応(Swift,Realm)
  • Campus Voice追加機能(Swift)
  • iPadエンタープライズアプリ(新規、Swift)
  • toC向けWebサービス、サーバサイド機能追加(LAMP環境)
  • 新規iOSアプリ修正案件(iOS 8 Swift/Objective-C)

6月

  • Campus Voiceという匿名型twitterのような匿名投稿SNSアプリを新規開発(iOS8.0〜,Swift,サーバサイドAPI開発、DB構築、CentOS 6.6構築、S3画像キャッシュ、その他ミドルウェア導入。バックエンドからクライアントアプリまですべて対応)
  • Campus Voice追加機能(Swift)
  • 新規iOSアプリ修正案件、(iOS 8 Swift/Objective-C)

振り返り

前回の三ヶ月と比べると希望通りiOS案件が増えていい感じです。
残りの半年は受託案件を少し減らして、新規でアプリを作りたいなと思っています。
受託のスキームが確立できれば、落ち着いてサービス開発に重点をおけるので、ここは試行錯誤しながらやっていく。アイディアだけはたくさんある、あとは形にするだけ。

見積に関して

見積を誤ると面倒なことになるので。
パターンが何個かあるので、明記しておく。
・そもそも仕様が決まっていない場合
仕様を決めずに作りながら開発していって月額の専属契約を結ぶ、週単位での報告
・仕様が決まっている(プロトタイプ案件 数人日レベル)
見通しがつきやすいので見積が出せる。
不明点を確認し、すり合わせ後、見積、発注、着手。
・仕様がだいたい決まっている(中規模、大規模)
イメージとしてはあるが画面の構成などの具体的な仕様がない場合、
おおまかな見積を出して、当初の確定した仕様に変更があれば、
追加費用をいただく形。ただこの方法はあまりおすすめできないので、
やったことがないが、お客さんのところにいって作業後、日数分請求という形が望ましいかもしれない。お客さんも相談しやすいし、その場にいれば修正指示など、進捗報告などすぐできる。
もしくは定期的に週一で確認で作業日数分、請求。
・仕様が決まっている(中規模、大規模)
仕様が詳細なので、すり合わせの数が少なくて済むのですぐ見積が可能。
工数が大きいと、気持ちは変わるもので、やっぱりこうしたいみたいなことはあるので、そこは内容によっては柔軟に対応するか、釘を挿しておくかどちらか。
このパターンはほとんどない。

困ったこと

案件の掛け持ちが多く、余裕がなくなってきているので、ここが課題。
アウトソースするなり、方法を考える。
iOS、Swift書ける方、アルバイト募集しております。

教訓てきな

マルチタスクが当たり前になって、休むタイミングが分からない時があるが、
あえて何もせずぼーっとする時間を作って、思索にふける時間を作る。
やらないことを決めるのがいい。
ごく当たり前のことだと思いますが、
行き詰まったことや、自分でどうにも解決できそうにないことがあれば、誰かに相談したり、
アドバイスを求めること。助言いただいた方には感謝しております。
問題があれば、それを解決するための努力を怠らないこと、うやむやにしたり、
放置したり、忙しさにかまけて、無視しない、必ず解決できる方法はあると信じて、そのための時間を作る。
これはプログラムにかぎらず、顧客折衝全般にも言えること。

息抜きは

今後の目標

  • 役に立ってかつ、ひとひねりあるおもしろい、そんなサービスを企画、開発する(アイディア or サンプルはあるがリリースまでもっていけてない、、、)
    →☓アイディアは出した、あとは実装
  • 興味、関心があるプロジェクトに参画し、それをお金に変える(利益を求め過ぎない)
    →△やりたいことはできてきている
  • オープンソースに貢献する
    →githubに全然pushできてない、、
  • 来年はWWDCに行く
  • 仕事がらみで海外に行く
  • ブログの更新頻度をあげる
    →△微妙

おわりに

残りの半年は気負わずぼちぼちやっていきます。
法人化することを検討していますが、税制面でのメリットなどよく知らないので、どなたか詳しい方、教えていただけるとすごく助かります。よろしくお願い致します。

2015/08/13

Swift UIPickerViewで選択した箇所の背景色など、UIを変更する(ピッカーのカスタム)

picker.gif

Pickerの各行のラベルをカスタム

選択状態となった際に、viewForRowデリゲートメソッドにて、背景用のラベルの背景色を変更する。
下記はあくまでサンプルなので、UILabelのサブクラス作成ですっきりさせた方がよい。

//
//  ViewController.swift
//  pickerTest
//
//  Created by matz on 2015/08/13.
//  Copyright (c) 2015年 matz. All rights reserved.
//

import UIKit

final class ViewController: UIViewController,
    UIPickerViewDataSource,UIPickerViewDelegate
{

    @IBOutlet weak var picker: UIPickerView!
    private var preSelectedLb:UILabel!
    private let prefectures: NSArray =
    ["北海道","青森県","岩手県","宮城県","秋田県","山形県","福島県","茨城県","栃木県","群馬県","埼玉県","千葉県","東京都","神奈川県","新潟県","富山県","石川県","福井県","山梨県","長野県","岐阜県","静岡県","愛知県","三重県","滋賀県","京都府","大阪府","兵庫県","奈良県","和歌山県","鳥取県","島根県","岡山県","広島県","山口県","徳島県","香川県","愛媛県","高知県","福岡県","佐賀県","長崎県","熊本県","大分県","宮崎県","鹿児島県","沖縄県"
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
        picker.delegate = self
        picker.dataSource = self
        // 初期選択させるのであれば
//        self.preSelectedLb = picker.viewForRow(0, forComponent: 0) as! UILabel
    }

    // 列数
    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }

    // 行数
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return prefectures.count
    }

    // pickerに表示するUIViewを返す
    func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView!) -> UIView {

        let pickerLabel = UILabel()
        let titleData = prefectures[row] as! String
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "HiraKakuProN-W3", size: 20.0)!,NSForegroundColorAttributeName:UIColor.grayColor()])

        // fontサイズ、テキスト
        pickerLabel.attributedText = myTitle
        // 中央寄せ ※これを指定しないとセンターにならない
        pickerLabel.textAlignment = NSTextAlignment.Center
        pickerLabel.frame = CGRectMake(0, 0, 200, 30)
        // ラベルを角丸に
        pickerLabel.layer.masksToBounds = true
        pickerLabel.layer.cornerRadius = 5.0

        // 既存ラベル、選択状態のラベルが存在している
       if let lb = pickerView.viewForRow(row, forComponent: component) as? UILabel,
            let selected = self.preSelectedLb {
            // 設定
            self.preSelectedLb = lb
            self.preSelectedLb.backgroundColor = UIColor.orangeColor()
            self.preSelectedLb.textColor = UIColor.whiteColor()
        }

        return pickerLabel
    }


    // pickerに表示する値を返す ※viewForRowがあればこちらは単純にタイトルを返すだけなので不要
//    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
//        return prefectures[row] as! String
//    }


    // pickerが選択された際に呼ばれる
    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        println("row: \(row)")
        println("value: \(prefectures[row])")

        // 選択状態のラベルを代入
        self.preSelectedLb = pickerView.viewForRow(row, forComponent: component) as! UILabel
        // ピッカーのリロードでviewForRowが呼ばれる
        pickerView.reloadComponent(component)
    }

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

参考