Code Monkey home page Code Monkey logo

mybalanceinquiry's People

Contributors

shoheiyokoyama avatar

Watchers

 avatar  avatar

mybalanceinquiry's Issues

cell identifier

ここのidentifier変える必要ないと思うけど

bankStatementTableView.register(UINib(nibName: "BankStatementCell", bundle: nil), forCellReuseIdentifier: "StatementCell")

ネストが深いswitch分

//データを返すメソッド
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if pickerView.tag == 1 {
            switch component {
            case 0:
                if row == 0 {
                    return String("")
                } else {
                    let year: String = "20" + "\(17 - row)"
                    return year
                }

こんな感じであればネストが深くなくなる。あとstringも"年"これでいい。意味わからないことしてる

//データを返すメソッド
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
            switch (pickerView.tag, component, row) {
            case (1, 0, 0):  return ""
            case (1, 1, 0):  return ""
            ...

BankingData

BankingViewController.swift

stract BankingData {
let type = BankType
 static func type(withTitle title: String) -> BankType {
    if title == "入金" {
            return .payment
        } else if title == "出金" {
            return .withdrawal
        }

ここはstaticな関数をBankingDataに定義すればここで分岐はいらなくなる
あとは
・Banking -> BankType
・class -> stract
の方がいい気がする

textfield周りの処理

simulator screen shot 2016 10 24 0 55 14

  • enterで閉じるようにしよう
  • キーボードが出るときと、出ない時で画面をスクロールさせて入力箇所が見えるようにしよう。contentInsetあたりをいじればいける

ローカルでmasterに戻れなくなった

git -c diff.mnemonicprefix=false -c core.quotepath=false -c credential.helper=sourcetree checkout master 
error: The following untracked working tree files would be overwritten by checkout:
    MyBalanceInquiry/model/BankModel.swift
Please move or remove them before you can switch branches.
Aborting
Completed with errors, see above

ブランチ移動できない

冗長な条件判定

let result1 = calendar.compare(data.date, to: fromDate, toGranularity: .day)
            // data.date > fromDateであれば
            if result1 == .orderedDescending {

                let result2 = calendar.compare(data.date, to: toDate, toGranularity: .day)
                // data.date < toDateであれば
                if result2 == .orderedAscending {
                    if case .payment = data.banking {
                        totalBalance += data.amount
                    } else {
                        totalBalance -= data.amount
                    }
                }
            }

もっと綺麗に書けそう

入出金データは別ファイルから読み込む

ViewController.swiftでの

// 取引を追加
        myBank1.addBanking(date: dateFormatter.date(from: "2016/08/04"), banking: .withdrawal, amount: 24000)
        myBank1.addBanking(date: dateFormatter.date(from: "2016/08/10"), banking: .payment, amount: 30000)
        myBank1.addBanking(date: dateFormatter.date(from: "2016/08/20"), banking: .withdrawal, amount: 15000)

は1個1個書かないで、別のファイルから読み込むようにします。

機能的には影響しないですけど、テストしやすいようにするためです。

textfieldが閉じない&入力部分が隠れる

simulator screen shot 2016 10 24 0 55 14

  • enterで閉じるようにしよう
  • キーボードが出るときと、出ない時で画面をスクロールさせて入力箇所が見えるようにしよう。contentInsetあたりをいじればいける

pickerの固定値

else if pickerView.tag == 2 {
            let banking: [String] = ["未入力", "入金", "出金"]

ここはクラス内定数に変更して

if pickBanking == "入金" {
            banking = .payment
        } else if pickBanking == "出金" {
            banking = .withdrawal
        }

こういうところはクラス内定数から参照するようにしよう。
例えば、現状だとこの文言とかが変更になった場合何箇所も訂正する必要がある。

仕様変更に対応しやすい設計にしよう

caseのパターンマッチ

if banking == .payment {
            balance += amount
        } else {
            balance -= amount
        }

まあこれでも悪くないんだけど
enumでパターンマッチする場合は

if case .payment = banking {
 //

こういう書き方もできるし、この方がcase分のパターンマッチっぽい

マジックナンバーの扱い

マジックナンバーって言われるんだけど、ここら辺じゃぱっと見数字が何を意味しているのかわからない。

//コンポーネントに含まれるデータの個数を返すメソッド
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if pickerView.tag == 1 {
            switch component {
            case 0:
                // 2012~2016 + 「年」
                return 6
            case 1:
                // 1~12 + 「月」
                return 13
            case 2:
                // 1~31 + 「日」
                return 32
            default:
                return 0
            }
        } else {
            return 3
        }

    }

ここは定数として扱ってももいいんじゃないかな。stract使うと定数をまとめることができるから今回はstractがいいかな

stract DataCount {
    static let year = 6
    static let month = 13
    ...


    ...
    case 0:
                // 2012~2016 + 「年」
                return DataCount.year

名前は誰が見てもわかるように考えて

クラス名の修正

~Classっていう名前はやめよう。
基本的にMVC構成になっているのでクラス名で役割がわかるようにしよう。
例えばViewsのファイルは~Viewっていうクラス、modelであれば~Modelっていう名前だとわかりやすいかな

メソッドを抜ける際のreturn, exit

fileprivate func getTotalBalance(fromDate: Date, toDate: Date) -> Int {
        ...
        // fromData < toDateでなかった場合は強制終了
        if calendar.compare(fromDate, to: toDate, toGranularity: .day) != .orderedAscending {
            print("期間設定に誤りがあります。")
            exit(0)
        }
        ...
    }

とか、

fileprivate func printBankStatement(fromDate: Date, toDate: Date) {
        ...
        // fromData < toDateでなかった場合は強制終了
        if calendar.compare(fromDate, to: toDate, toGranularity: .day) != .orderedAscending {
            print("期間設定に誤りがあります。")
            return;
        }
        ...
    }

のメソッドを抜ける場合の書き方って何がいいですか?

TableViewでセルの色を指定したタイミングで変更したい

MyBankViewControllerでは明細一覧がTableViewで表示され、セルの選択アラートBankingDataのオプション(isIncome)を変更できる。
isIncomeがtrueであれば、セル設定時にbackgroundに色がつく。

アラートでオプションの変更後すぐに色が変わるようにしたいです。

swiftファイルの保存先を変更したい

いくつかswiftファイルを作成した時、MyBalanceInquiryディレクトリの外に作ってしまったので中に入れたい。

ただ移動させるだけだと、xcodeで開けなくなるのでどうすればいいですか?

ハードコーディング3

まず、これでclass typeからクラス名をstringで取得可能

extension String {
    static func className(_ aClass: AnyClass) -> String {
        guard let className = NSStringFromClass(aClass).components(separatedBy: ".").last else { return "" }
        return className
    }

次にUITableViewExtension.swiftでも作れば

extension UITableView {
func registerCells<T: UITableViewCell>(_ types: [T.Type]) {
        types.forEach { registerCell($0) }
    }
    
    func registerCells<T: UITableViewCell>(_ types: [[T.Type]]) {
        types.flatMap{$0.prefix(upTo: 1)}.forEach { registerCell($0) }
    }

    func dequeueCell<T: UITableViewCell>(_ type: T.Type, indexPath: IndexPath) -> T {
        return dequeueReusableCell(withIdentifier: String.className(type), for: indexPath) as! T
    }

bankStatementTableView.register(UINib(nibName: "BankStatementCell", bundle: nil), forCellReuseIdentifier: "BankStatementCell") ->
tableView.registerCell(BankStatementCell.self)

tableView.dequeueReusableCell(withIdentifier: "BankStatementCell", for: indexPath) ->
tableView.dequeueCell(BankStatementCell.self, indexPath: indexPath)

で直接stringを渡すことなくcellの管理可能

変数定義に修正

// 過去全ての取引を計算する
    fileprivate func getTotalBalance() -> Int {
        var totalBalance = firstBalance

        bankStatement.forEach { data in
            if case .payment = data.banking {
                totalBalance += data.amount
            } else {
                totalBalance -= data.amount
            }
        }
        return totalBalance
    }

単に状態によって残高返すから変数で行けそう

ハードコーディング

stringでみずほ銀行とか入れるのってちょっと行けてない感じがある。
多分普通のアプリに置き換えて考えたら、扱える銀行って数社くらいだと思うんだよね。そう考えるとアプリ内で銀行定義しちゃっていいと思うから、ここはenumで指定できるとsafetyなきがする。

        let myBank1 = Bank(name: "みずほ銀行", firstBalance: 100000)
        let myBank2 = Bank(name: "三菱東京UFJ銀行", firstBalance: 200000)
        let myBank3 = Bank(name: "多摩信用金庫", firstBalance: 1200000)
enum BankType {
     case mizuho, mitsubishi, ...
}
        let myBank1 = Bank(type: .mizuho, firstBalance: 100000)
        let myBank2 = Bank(name: .mitsubishi, firstBalance: 200000)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.