LoginSignup
71
70

More than 5 years have passed since last update.

Swift Code改善tips

Last updated at Posted at 2015-08-01

swiftらしいコード書けるように最近ずっとリファクタリングしてて、正しいかどうか自分もわからないけど、一応自分いいと思ったtipをまとめたいと思います。

Stringよりenumを使う

例: stroyboard からview controllerを取得


let searchChannelListViewController = UIStoryboard(name: "Search", bundle: nil).instantiateViewControllerWithIdentifier("SearchChannelList")

guard let searchChannelListViewController = searchChannelListViewController else{
       return 
}

Stringのデメリット:

  • nilではありえないとわかったとしても毎回nil判定もしくは!しないといけない.
  • typoしやすいし、実行時しか違ったことに気づかない

enumのメリット:

  • typoするとコンパイル エラー
  • enumに定義されたやつは必ず値があると定義できる

上のコードちょっとリファクタリング:

 private enum StoryboardName:String {
        case ChannelDetail = "ChannelDetail"
        case Search = "Search"
    }
    private enum ViewControllerIdentifier:String {
        case playlist = "playlist"
        case SearchChannelList = "SearchChannelList"
    }

    private func viewController(storyboardName storyboardName:StoryboardName,viewControllerId:ViewControllerIdentifier?) -> UIViewController {

        if let viewControllerId = viewControllerId {
            return UIStoryboard(name: storyboardName.rawValue, bundle: nil).instantiateViewControllerWithIdentifier(viewControllerId.rawValue)
        }
        // enum使えば値があるのはここで保証する
        return UIStoryboard(name: storyboardName.rawValue, bundle: nil).instantiateInitialViewController()!
    }

    // これで取ったview controller 全部nilではなくなる
    let channelDetailViewController = viewController(storyboardName:.ChannelDetail, viewControllerId:nil)
    let searchChannelListViewController = viewController(storyboardName:.Search,viewControllerId:.SearchChannelList)

default valueを使う

前のコードstoryboardのroot view controllerとるのにviewControllerId:nil渡すのは直感ではない、できるかぎりstoryboardNameだけで渡したい。この時はパラメーターdefault value.

private func viewController(storyboardName storyboardName:StoryboardName,viewControllerId:ViewControllerIdentifier? = nil) -> UIViewController {
 ....
}

// viewControllerId:nil を削除
let channelDetailViewController = viewController(storyboardName:.ChannelDetail)
let searchChannelListViewController = viewController(storyboardName:.Search,viewControllerId:.SearchChannelList)

as! より genericsを使う

上のコードはUIViewController返すだけなので、そのViewControllerに対して特定な操作したいときにtype変換する必要が出ってきます。つまり


let channelDetailViewController = viewController(storyboardName:.ChannelDetail) as! ChannelDetailViewController
let searchChannelListViewController = viewController(storyboardName:.Search,viewControllerId:.SearchChannelList) as! searchChannelListViewController

as! ちょっと汚いね。。こういう場合はgenerics!

private func viewController<T:UIViewController>(storyboardName storyboardName:StoryboardName,viewControllerId:ViewControllerIdentifier? = nil,type:T.Type) -> T {
        if let viewControllerId = viewControllerId {
           return UIStoryboard(name: storyboardName.rawValue, bundle: nil).instantiateViewControllerWithIdentifier(viewControllerId.rawValue) as! T
        }
        return UIStoryboard(name: storyboardName.rawValue, bundle: nil).instantiateInitialViewController() as! T
    }

//これでdown castする必要がなくなる、なとなく前より綺麗になりました
let channelDetailViewController = viewController(storyboardName:.ChannelDetail,type: ChannelDetailViewController.self)
let searchChannelListViewController = viewController(storyboardName:.Search,viewControllerId:.SearchChannelList,type: searchChannelListViewController.self) 

いらないものは _ で隠す

例: UI animation

UIView.animateWithDuration(0.25, animations: {
  //make same super cool animation
}, completion: {
  finished in
  // same clean up
})

completion blockのほう finishedが返ってきてるけど、実際には使われてなくて、
_ を使って隠す

UIView.animateWithDuration(0.25, animations: {
  //make same super cool animation
}, completion: {
  _ in
  // same clean up
})

struct namespace

struct/enum内でstructを定義できるので、namespaceとして使える.

例: 色定義

struct ColorPalette {
      static let Red = UIColor(red: 1.0, green: 0.1491, blue: 0.0, alpha: 1.0)
      static let Green = UIColor(red: 0.0, green: 0.5628, blue: 0.3188, alpha: 1.0)
      static let Blue = UIColor(red: 0.0, green: 0.3285, blue: 0.5749, alpha: 1.0)

      struct Gray {
          static let Light = UIColor(white: 0.8374, alpha: 1.0)
          static let Medium = UIColor(white: 0.4756, alpha: 1.0)
          static let Dark = UIColor(white: 0.2605, alpha: 1.0)
     }
 }

 let red = ColorPalette.Red
 let darkGray = ColorPalette.Gray.Dark

didSetを使ってIBOutletするviewカスタマイズする

普通のviewDidLoadでcustomする


class ViewController: UIViewController {
    @IBOutlet weak var myLabel: UILabel!
    @IBOutlet weak var myButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()

        // viewカスタマイズ
        configureViews()
    }

    func configureViews() {
        myLabel.textColor = UIColor.purpleColor()
        myButton.tintColor = UIColor.redColor()
    }
}

didSet内でcustomする


class ViewController: UIViewController {
    @IBOutlet weak var myLabel: UILabel! {
        didSet {
            myLabel.textColor = UIColor.purpleColor()
        }
    }

    @IBOutlet weak var myButton: UIButton! {
        didSet {
            myButton.tintColor = UIColor.redColor()
        }
    }
}
71
70
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
71
70